701-v6.2-0007-net-dpaa2-publish-MAC-stringset-to-ethtool-S-even-if.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. From ce44b6ed9ee65efa9b3025552c513842eabcab88 Mon Sep 17 00:00:00 2001
  2. From: Vladimir Oltean <[email protected]>
  3. Date: Tue, 29 Nov 2022 16:12:16 +0200
  4. Subject: [PATCH 09/14] net: dpaa2: publish MAC stringset to ethtool -S even if
  5. MAC is missing
  6. DPNIs and DPSW objects can connect and disconnect at runtime from DPMAC
  7. objects on the same fsl-mc bus. The DPMAC object also holds "ethtool -S"
  8. unstructured counters. Those counters are only shown for the entity
  9. owning the netdev (DPNI, DPSW) if it's connected to a DPMAC.
  10. The ethtool stringset code path is split into multiple callbacks, but
  11. currently, connecting and disconnecting the DPMAC takes the rtnl_lock().
  12. This blocks the entire ethtool code path from running, see
  13. ethnl_default_doit() -> rtnl_lock() -> ops->prepare_data() ->
  14. strset_prepare_data().
  15. This is going to be a problem if we are going to no longer require
  16. rtnl_lock() when connecting/disconnecting the DPMAC, because the DPMAC
  17. could appear between ops->get_sset_count() and ops->get_strings().
  18. If it appears out of the blue, we will provide a stringset into an array
  19. that was dimensioned thinking the DPMAC wouldn't be there => array
  20. accessed out of bounds.
  21. There isn't really a good way to work around that, and I don't want to
  22. put too much pressure on the ethtool framework by playing locking games.
  23. Just make the DPMAC counters be always available. They'll be zeroes if
  24. the DPNI or DPSW isn't connected to a DPMAC.
  25. Signed-off-by: Vladimir Oltean <[email protected]>
  26. Reviewed-by: Andrew Lunn <[email protected]>
  27. Reviewed-by: Ioana Ciornei <[email protected]>
  28. Tested-by: Ioana Ciornei <[email protected]>
  29. Signed-off-by: Paolo Abeni <[email protected]>
  30. ---
  31. drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 12 +++---------
  32. .../ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c | 11 ++---------
  33. 2 files changed, 5 insertions(+), 18 deletions(-)
  34. --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
  35. +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
  36. @@ -186,7 +186,6 @@ static int dpaa2_eth_set_pauseparam(stru
  37. static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
  38. u8 *data)
  39. {
  40. - struct dpaa2_eth_priv *priv = netdev_priv(netdev);
  41. u8 *p = data;
  42. int i;
  43. @@ -200,22 +199,17 @@ static void dpaa2_eth_get_strings(struct
  44. strscpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN);
  45. p += ETH_GSTRING_LEN;
  46. }
  47. - if (dpaa2_eth_has_mac(priv))
  48. - dpaa2_mac_get_strings(p);
  49. + dpaa2_mac_get_strings(p);
  50. break;
  51. }
  52. }
  53. static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
  54. {
  55. - int num_ss_stats = DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS;
  56. - struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
  57. -
  58. switch (sset) {
  59. case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */
  60. - if (dpaa2_eth_has_mac(priv))
  61. - num_ss_stats += dpaa2_mac_get_sset_count();
  62. - return num_ss_stats;
  63. + return DPAA2_ETH_NUM_STATS + DPAA2_ETH_NUM_EXTRA_STATS +
  64. + dpaa2_mac_get_sset_count();
  65. default:
  66. return -EOPNOTSUPP;
  67. }
  68. --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
  69. +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-ethtool.c
  70. @@ -145,14 +145,9 @@ dpaa2_switch_set_link_ksettings(struct n
  71. static int
  72. dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
  73. {
  74. - struct ethsw_port_priv *port_priv = netdev_priv(netdev);
  75. - int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS;
  76. -
  77. switch (sset) {
  78. case ETH_SS_STATS:
  79. - if (port_priv->mac)
  80. - num_ss_stats += dpaa2_mac_get_sset_count();
  81. - return num_ss_stats;
  82. + return DPAA2_SWITCH_NUM_COUNTERS + dpaa2_mac_get_sset_count();
  83. default:
  84. return -EOPNOTSUPP;
  85. }
  86. @@ -161,7 +156,6 @@ dpaa2_switch_ethtool_get_sset_count(stru
  87. static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
  88. u32 stringset, u8 *data)
  89. {
  90. - struct ethsw_port_priv *port_priv = netdev_priv(netdev);
  91. u8 *p = data;
  92. int i;
  93. @@ -172,8 +166,7 @@ static void dpaa2_switch_ethtool_get_str
  94. ETH_GSTRING_LEN);
  95. p += ETH_GSTRING_LEN;
  96. }
  97. - if (port_priv->mac)
  98. - dpaa2_mac_get_strings(p);
  99. + dpaa2_mac_get_strings(p);
  100. break;
  101. }
  102. }