]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net-sysfs: get rid of rps_dev_flow_lock
authorEric Dumazet <edumazet@google.com>
Mon, 2 Mar 2026 18:14:30 +0000 (18:14 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 5 Mar 2026 00:54:10 +0000 (16:54 -0800)
Use unrcu_pointer() and xchg() in store_rps_dev_flow_table_cnt()
instead of a dedicated spinlock.

Make a similar change in rx_queue_release(), so that both
functions use a similar construct and synchronization.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260302181432.1836150-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/core/net-sysfs.c

index 07624b682b08b24da790d377f1deec4dc0a84269..52fcf7fa58a808e79c1a17c8719830bcfb7c1674 100644 (file)
@@ -1084,7 +1084,6 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
 {
        unsigned long mask, count;
        struct rps_dev_flow_table *table, *old_table;
-       static DEFINE_SPINLOCK(rps_dev_flow_lock);
        int rc;
 
        if (!capable(CAP_NET_ADMIN))
@@ -1128,11 +1127,8 @@ static ssize_t store_rps_dev_flow_table_cnt(struct netdev_rx_queue *queue,
                table = NULL;
        }
 
-       spin_lock(&rps_dev_flow_lock);
-       old_table = rcu_dereference_protected(queue->rps_flow_table,
-                                             lockdep_is_held(&rps_dev_flow_lock));
-       rcu_assign_pointer(queue->rps_flow_table, table);
-       spin_unlock(&rps_dev_flow_lock);
+       old_table = unrcu_pointer(xchg(&queue->rps_flow_table,
+                                      RCU_INITIALIZER(table)));
 
        if (old_table)
                call_rcu(&old_table->rcu, rps_dev_flow_table_release);
@@ -1161,8 +1157,8 @@ static void rx_queue_release(struct kobject *kobj)
 {
        struct netdev_rx_queue *queue = to_rx_queue(kobj);
 #ifdef CONFIG_RPS
+       struct rps_dev_flow_table *old_table;
        struct rps_map *map;
-       struct rps_dev_flow_table *flow_table;
 
        map = rcu_dereference_protected(queue->rps_map, 1);
        if (map) {
@@ -1170,11 +1166,9 @@ static void rx_queue_release(struct kobject *kobj)
                kfree_rcu(map, rcu);
        }
 
-       flow_table = rcu_dereference_protected(queue->rps_flow_table, 1);
-       if (flow_table) {
-               RCU_INIT_POINTER(queue->rps_flow_table, NULL);
-               call_rcu(&flow_table->rcu, rps_dev_flow_table_release);
-       }
+       old_table = unrcu_pointer(xchg(&queue->rps_flow_table, NULL));
+       if (old_table)
+               call_rcu(&old_table->rcu, rps_dev_flow_table_release);
 #endif
 
        memset(kobj, 0, sizeof(*kobj));