dpaa2-switch: avoid holding rtnl_lock in dpaa2_switch_event_work()

The only reason why the rtnl_lock is held in the
dpaa2_switch_event_work() is so that there is no concurency between the
changeupper notifier which manages the per port FDB assignment and the
workqueue which adds / deletes addresses into that forwarding database.

To avoid this kind of concurency without a rtnl_lock, flush the event
workqueue as the last step from the pre_bridge_leave so that any
in-flight operations targeting the current FDB are finalized before the
bridge layout (and the per port FDB assignment) changes.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Link: https://patch.msgid.link/20260629112309.154328-3-ioana.ciornei@nxp.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Ioana Ciornei 2026-06-29 14:22:58 +03:00 committed by Paolo Abeni
parent 97cb4ae751
commit 0cf0b8ac40

View File

@ -2069,7 +2069,15 @@ static int dpaa2_switch_port_restore_rxvlan(struct net_device *vdev, int vid, vo
static void dpaa2_switch_port_pre_bridge_leave(struct net_device *netdev)
{
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
struct ethsw_core *ethsw = port_priv->ethsw_data;
switchdev_bridge_port_unoffload(netdev, NULL, NULL, NULL);
/* Make sure that any FDB add/del operations are completed before the
* bridge layout changes
*/
flush_workqueue(ethsw->workqueue);
}
static int dpaa2_switch_port_bridge_leave(struct net_device *netdev)
@ -2281,7 +2289,6 @@ static void dpaa2_switch_event_work(struct work_struct *work)
struct switchdev_notifier_fdb_info *fdb_info;
int err;
rtnl_lock();
fdb_info = &switchdev_work->fdb_info;
switch (switchdev_work->event) {
@ -2310,7 +2317,6 @@ static void dpaa2_switch_event_work(struct work_struct *work)
break;
}
rtnl_unlock();
kfree(switchdev_work->fdb_info.addr);
kfree(switchdev_work);
dev_put(dev);