Skip to content

Commit 87db82c

Browse files
vladimirolteanPaolo Abeni
authored andcommitted
net: dpaa2-mac: move rtnl_lock() only around phylink_{,dis}connect_phy()
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 <[email protected]> Reviewed-by: Ioana Ciornei <[email protected]> Tested-by: Ioana Ciornei <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 3c7f44f commit 87db82c

File tree

3 files changed

+5
-8
lines changed

3 files changed

+5
-8
lines changed

drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4715,7 +4715,6 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
47154715
dpaa2_eth_set_mac_addr(netdev_priv(net_dev));
47164716
dpaa2_eth_update_tx_fqids(priv);
47174717

4718-
rtnl_lock();
47194718
/* We can avoid locking because the "endpoint changed" IRQ
47204719
* handler is the only one who changes priv->mac at runtime,
47214720
* so we are not racing with anyone.
@@ -4725,7 +4724,6 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
47254724
dpaa2_eth_disconnect_mac(priv);
47264725
else
47274726
dpaa2_eth_connect_mac(priv);
4728-
rtnl_unlock();
47294727
}
47304728

47314729
return IRQ_HANDLED;
@@ -5045,9 +5043,7 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
50455043
else
50465044
fsl_mc_free_irqs(ls_dev);
50475045

5048-
rtnl_lock();
50495046
dpaa2_eth_disconnect_mac(priv);
5050-
rtnl_unlock();
50515047
dpaa2_eth_free_rings(priv);
50525048
free_percpu(priv->fd);
50535049
free_percpu(priv->sgt_cache);

drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
430430
}
431431
mac->phylink = phylink;
432432

433+
rtnl_lock();
433434
err = phylink_fwnode_phy_connect(mac->phylink, dpmac_node, 0);
435+
rtnl_unlock();
434436
if (err) {
435437
netdev_err(net_dev, "phylink_fwnode_phy_connect() = %d\n", err);
436438
goto err_phylink_destroy;
@@ -448,7 +450,10 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
448450

449451
void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
450452
{
453+
rtnl_lock();
451454
phylink_disconnect_phy(mac->phylink);
455+
rtnl_unlock();
456+
452457
phylink_destroy(mac->phylink);
453458
dpaa2_pcs_destroy(mac);
454459
of_phy_put(mac->serdes_phy);

drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,6 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
15291529
}
15301530

15311531
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
1532-
rtnl_lock();
15331532
/* We can avoid locking because the "endpoint changed" IRQ
15341533
* handler is the only one who changes priv->mac at runtime,
15351534
* so we are not racing with anyone.
@@ -1539,7 +1538,6 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
15391538
dpaa2_switch_port_disconnect_mac(port_priv);
15401539
else
15411540
dpaa2_switch_port_connect_mac(port_priv);
1542-
rtnl_unlock();
15431541
}
15441542

15451543
out:
@@ -2957,9 +2955,7 @@ static void dpaa2_switch_remove_port(struct ethsw_core *ethsw,
29572955
{
29582956
struct ethsw_port_priv *port_priv = ethsw->ports[port_idx];
29592957

2960-
rtnl_lock();
29612958
dpaa2_switch_port_disconnect_mac(port_priv);
2962-
rtnl_unlock();
29632959
free_netdev(port_priv->netdev);
29642960
ethsw->ports[port_idx] = NULL;
29652961
}

0 commit comments

Comments
 (0)