[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251210125945.211350-1-toke@redhat.com>
Date: Wed, 10 Dec 2025 13:59:44 +0100
From: Toke Høiland-Jørgensen <toke@...hat.com>
To: Aaron Conole <aconole@...hat.com>,
Eelco Chaudron <echaudro@...hat.com>,
Ilya Maximets <i.maximets@....org>,
Alexei Starovoitov <ast@...nel.org>,
Jesse Gross <jesse@...ira.com>
Cc: Toke Høiland-Jørgensen <toke@...hat.com>,
Adrian Moreno <amorenoz@...hat.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Simon Horman <horms@...nel.org>,
netdev@...r.kernel.org,
dev@...nvswitch.org
Subject: [PATCH net] net: openvswitch: Avoid needlessly taking the RTNL on vport destroy
The openvswitch teardown code will immediately call
ovs_netdev_detach_dev() in response to a NETDEV_UNREGISTER notification.
It will then start the dp_notify_work workqueue, which will later end up
calling the vport destroy() callback. This callback takes the RTNL to do
another ovs_netdev_detach_port(), which in this case is unnecessary.
This causes extra pressure on the RTNL, in some cases leading to
"unregister_netdevice: waiting for XX to become free" warnings on
teardown.
We can straight-forwardly avoid the extra RTNL lock acquisition by
checking the device flags before taking the lock, and skip the locking
altogether if the IFF_OVS_DATAPATH flag has already been unset.
Fixes: b07c26511e94 ("openvswitch: fix vport-netdev unregister")
Tested-by: Adrian Moreno <amorenoz@...hat.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@...hat.com>
---
net/openvswitch/vport-netdev.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index 91a11067e458..519f038526f9 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -160,10 +160,13 @@ void ovs_netdev_detach_dev(struct vport *vport)
static void netdev_destroy(struct vport *vport)
{
- rtnl_lock();
- if (netif_is_ovs_port(vport->dev))
- ovs_netdev_detach_dev(vport);
- rtnl_unlock();
+ if (netif_is_ovs_port(vport->dev)) {
+ rtnl_lock();
+ /* check again while holding the lock */
+ if (netif_is_ovs_port(vport->dev))
+ ovs_netdev_detach_dev(vport);
+ rtnl_unlock();
+ }
call_rcu(&vport->rcu, vport_netdev_free);
}
--
2.52.0
Powered by blists - more mailing lists