]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy()
authorVladimir Oltean <vladimir.oltean@nxp.com>
Tue, 29 Nov 2022 14:12:21 +0000 (16:12 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 1 Dec 2022 12:40:22 +0000 (13:40 +0100)
After the introduction of a private mac_lock that serializes access to
priv->mac (and port_priv->mac in the switch), the only remaining purpose
of rtnl_lock() is to satisfy the locking requirements of
phylink_fwnode_phy_connect() and phylink_disconnect_phy().

But the functions these live in, dpaa2_mac_connect() and
dpaa2_mac_disconnect(), have contradictory locking requirements.
While phylink_fwnode_phy_connect() wants rtnl_lock() to be held,
phylink_create() wants it to not be held.

Move the rtnl_lock() from top-level (in the dpaa2-eth and dpaa2-switch
drivers) to only surround the phylink calls that require it, in the
dpaa2-mac library code.

This is possible because dpaa2_mac_connect() and dpaa2_mac_disconnect()
run unlocked, and there isn't any danger of an AB/BA deadlock between
the rtnl_mutex and other private locks.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Tested-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c

index 3ed54c147e987adb8ff952f1de4fed94346ce754..0c35abb7d065e64d6c57a98769e4a0c0c54cfe26 100644 (file)
@@ -4715,7 +4715,6 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
                dpaa2_eth_set_mac_addr(netdev_priv(net_dev));
                dpaa2_eth_update_tx_fqids(priv);
 
-               rtnl_lock();
                /* We can avoid locking because the "endpoint changed" IRQ
                 * handler is the only one who changes priv->mac at runtime,
                 * so we are not racing with anyone.
@@ -4725,7 +4724,6 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
                        dpaa2_eth_disconnect_mac(priv);
                else
                        dpaa2_eth_connect_mac(priv);
-               rtnl_unlock();
        }
 
        return IRQ_HANDLED;
@@ -5045,9 +5043,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
        else
                fsl_mc_free_irqs(ls_dev);
 
-       rtnl_lock();
        dpaa2_eth_disconnect_mac(priv);
-       rtnl_unlock();
        dpaa2_eth_free_rings(priv);
        free_percpu(priv->fd);
        free_percpu(priv->sgt_cache);
index 3096810120ee1086fe078a9678da578953acb3a5..c886f33f8c6fee7fadb3bdf04deac3be8e20daf4 100644 (file)
@@ -430,7 +430,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
        }
        mac->phylink = phylink;
 
+       rtnl_lock();
        err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
+       rtnl_unlock();
        if (err) {
                netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
                goto err_phylink_destroy;
@@ -448,7 +450,10 @@ err_pcs_destroy:
 
 void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
 {
+       rtnl_lock();
        phylink_disconnect_phy(mac->phylink);
+       rtnl_unlock();
+
        phylink_destroy(mac->phylink);
        dpaa2_pcs_destroy(mac);
        of_phy_put(mac->serdes_phy);
index 0472e24191ad85d75668cdf2df9e14ad8c5c899f..f4ae4289c41ae674c1fc84318ef71b316fd178b5 100644 (file)
@@ -1529,7 +1529,6 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
        }
 
        if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
-               rtnl_lock();
                /* We can avoid locking because the "endpoint changed" IRQ
                 * handler is the only one who changes priv->mac at runtime,
                 * so we are not racing with anyone.
@@ -1539,7 +1538,6 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
                        dpaa2_switch_port_disconnect_mac(port_priv);
                else
                        dpaa2_switch_port_connect_mac(port_priv);
-               rtnl_unlock();
        }
 
 out:
@@ -2957,9 +2955,7 @@ static void dpaa2_switch_remove_port(struct ethsw_core *ethsw,
 {
        struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
 
-       rtnl_lock();
        dpaa2_switch_port_disconnect_mac(port_priv);
-       rtnl_unlock();
        free_netdev(port_priv->netdev);
        ethsw->ports[port_idx] = NULL;
 }