]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
vxlan: Convert FDB flushing to RCU
authorIdo Schimmel <idosch@nvidia.com>
Tue, 15 Apr 2025 12:11:38 +0000 (15:11 +0300)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 22 Apr 2025 09:11:16 +0000 (11:11 +0200)
Instead of holding the FDB hash lock when traversing the FDB linked list
during flushing, use RCU and only acquire the lock for entries that need
to be flushed.

Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20250415121143.345227-11-idosch@nvidia.com
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/vxlan/vxlan_core.c

index c3511a43ce9984fc7bf0d1960eca270cfec983af..762dde70d9e9cc09f09ce94cceda7d49a9a01ba7 100644 (file)
@@ -3037,14 +3037,17 @@ static void vxlan_flush(struct vxlan_dev *vxlan,
                        const struct vxlan_fdb_flush_desc *desc)
 {
        bool match_remotes = vxlan_fdb_flush_should_match_remotes(desc);
-       struct hlist_node *n;
        struct vxlan_fdb *f;
 
-       spin_lock_bh(&vxlan->hash_lock);
-       hlist_for_each_entry_safe(f, n, &vxlan->fdb_list, fdb_node) {
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(f, &vxlan->fdb_list, fdb_node) {
                if (!vxlan_fdb_flush_matches(f, vxlan, desc))
                        continue;
 
+               spin_lock_bh(&vxlan->hash_lock);
+               if (hlist_unhashed(&f->fdb_node))
+                       goto unlock;
+
                if (match_remotes) {
                        bool destroy_fdb = false;
 
@@ -3052,12 +3055,14 @@ static void vxlan_flush(struct vxlan_dev *vxlan,
                                                      &destroy_fdb);
 
                        if (!destroy_fdb)
-                               continue;
+                               goto unlock;
                }
 
                vxlan_fdb_destroy(vxlan, f, true, true);
+unlock:
+               spin_unlock_bh(&vxlan->hash_lock);
        }
-       spin_unlock_bh(&vxlan->hash_lock);
+       rcu_read_unlock();
 }
 
 static const struct nla_policy vxlan_del_bulk_policy[NDA_MAX + 1] = {