701-v6.2-0012-net-dpaa2-mac-move-rtnl_lock-only-around-phylink.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. From 4ea2faf5bb13d9ba9f07e996d495c4cbe34a4236 Mon Sep 17 00:00:00 2001
  2. From: Vladimir Oltean <[email protected]>
  3. Date: Tue, 29 Nov 2022 16:12:21 +0200
  4. Subject: [PATCH 14/14] net: dpaa2-mac: move rtnl_lock() only around
  5. phylink_{,dis}connect_phy()
  6. After the introduction of a private mac_lock that serializes access to
  7. priv->mac (and port_priv->mac in the switch), the only remaining purpose
  8. of rtnl_lock() is to satisfy the locking requirements of
  9. phylink_fwnode_phy_connect() and phylink_disconnect_phy().
  10. But the functions these live in, dpaa2_mac_connect() and
  11. dpaa2_mac_disconnect(), have contradictory locking requirements.
  12. While phylink_fwnode_phy_connect() wants rtnl_lock() to be held,
  13. phylink_create() wants it to not be held.
  14. Move the rtnl_lock() from top-level (in the dpaa2-eth and dpaa2-switch
  15. drivers) to only surround the phylink calls that require it, in the
  16. dpaa2-mac library code.
  17. This is possible because dpaa2_mac_connect() and dpaa2_mac_disconnect()
  18. run unlocked, and there isn't any danger of an AB/BA deadlock between
  19. the rtnl_mutex and other private locks.
  20. Signed-off-by: Vladimir Oltean <[email protected]>
  21. Reviewed-by: Ioana Ciornei <[email protected]>
  22. Tested-by: Ioana Ciornei <[email protected]>
  23. Signed-off-by: Paolo Abeni <[email protected]>
  24. ---
  25. drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ----
  26. drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 5 +++++
  27. drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 4 ----
  28. 3 files changed, 5 insertions(+), 8 deletions(-)
  29. --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
  30. +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
  31. @@ -4530,7 +4530,6 @@ static irqreturn_t dpni_irq0_handler_thr
  32. dpaa2_eth_set_mac_addr(netdev_priv(net_dev));
  33. dpaa2_eth_update_tx_fqids(priv);
  34. - rtnl_lock();
  35. /* We can avoid locking because the "endpoint changed" IRQ
  36. * handler is the only one who changes priv->mac at runtime,
  37. * so we are not racing with anyone.
  38. @@ -4540,7 +4539,6 @@ static irqreturn_t dpni_irq0_handler_thr
  39. dpaa2_eth_disconnect_mac(priv);
  40. else
  41. dpaa2_eth_connect_mac(priv);
  42. - rtnl_unlock();
  43. }
  44. return IRQ_HANDLED;
  45. @@ -4859,9 +4857,7 @@ static int dpaa2_eth_remove(struct fsl_m
  46. else
  47. fsl_mc_free_irqs(ls_dev);
  48. - rtnl_lock();
  49. dpaa2_eth_disconnect_mac(priv);
  50. - rtnl_unlock();
  51. dpaa2_eth_free_rings(priv);
  52. free_percpu(priv->fd);
  53. free_percpu(priv->sgt_cache);
  54. --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
  55. +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
  56. @@ -428,7 +428,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *
  57. }
  58. mac->phylink = phylink;
  59. + rtnl_lock();
  60. err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
  61. + rtnl_unlock();
  62. if (err) {
  63. netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
  64. goto err_phylink_destroy;
  65. @@ -446,7 +448,10 @@ err_pcs_destroy:
  66. void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
  67. {
  68. + rtnl_lock();
  69. phylink_disconnect_phy(mac->phylink);
  70. + rtnl_unlock();
  71. +
  72. phylink_destroy(mac->phylink);
  73. dpaa2_pcs_destroy(mac);
  74. of_phy_put(mac->serdes_phy);
  75. --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
  76. +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
  77. @@ -1530,7 +1530,6 @@ static irqreturn_t dpaa2_switch_irq0_han
  78. }
  79. if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
  80. - rtnl_lock();
  81. /* We can avoid locking because the "endpoint changed" IRQ
  82. * handler is the only one who changes priv->mac at runtime,
  83. * so we are not racing with anyone.
  84. @@ -1540,7 +1539,6 @@ static irqreturn_t dpaa2_switch_irq0_han
  85. dpaa2_switch_port_disconnect_mac(port_priv);
  86. else
  87. dpaa2_switch_port_connect_mac(port_priv);
  88. - rtnl_unlock();
  89. }
  90. out:
  91. @@ -2951,9 +2949,7 @@ static void dpaa2_switch_remove_port(str
  92. {
  93. struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
  94. - rtnl_lock();
  95. dpaa2_switch_port_disconnect_mac(port_priv);
  96. - rtnl_unlock();
  97. free_netdev(port_priv->netdev);
  98. ethsw->ports[port_idx] = NULL;
  99. }