]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: ipset: mark the rcu locked areas properly
authorJozsef Kadlecsik <kadlec@netfilter.org>
Thu, 2 Jul 2026 13:46:57 +0000 (15:46 +0200)
committerFlorian Westphal <fw@strlen.de>
Wed, 8 Jul 2026 13:33:43 +0000 (15:33 +0200)
When we bump the uref counter, there's no need to keep
the rcu lock because the referred hash table can't
disappear. Also, from the same reason in mtype_gc we
need the rcu lock and not a spinlock.

Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/ipset/ip_set_hash_gen.h

index dedf59b661ddf37d3a93ef5a049ad75b7413f7d8..c9a07176624388b3772c07be8ed01dfcb58eea2d 100644 (file)
@@ -569,9 +569,10 @@ mtype_gc(struct work_struct *work)
        set = gc->set;
        h = set->data;
 
-       spin_lock_bh(&set->lock);
-       t = ipset_dereference_set(h->table, set);
+       rcu_read_lock_bh();
+       t = rcu_dereference_bh(h->table);
        atomic_inc(&t->uref);
+       rcu_read_unlock_bh();
        numof_locks = ahash_numof_locks(t->htable_bits);
        r = gc->region++;
        if (r >= numof_locks) {
@@ -580,7 +581,6 @@ mtype_gc(struct work_struct *work)
        next_run = (IPSET_GC_PERIOD(set->timeout) * HZ) / numof_locks;
        if (next_run < HZ/10)
                next_run = HZ/10;
-       spin_unlock_bh(&set->lock);
 
        mtype_gc_do(set, h, t, r);
 
@@ -860,15 +860,13 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
        key = HKEY(value, h->initval, t->htable_bits);
        r = ahash_region(key);
        atomic_inc(&t->uref);
+       rcu_read_unlock_bh();
        elements = t->hregion[r].elements;
        maxelem = t->maxelem;
        if (elements >= maxelem) {
                u32 e;
-               if (SET_WITH_TIMEOUT(set)) {
-                       rcu_read_unlock_bh();
+               if (SET_WITH_TIMEOUT(set))
                        mtype_gc_do(set, h, t, r);
-                       rcu_read_lock_bh();
-               }
                maxelem = h->maxelem;
                elements = 0;
                for (e = 0; e < ahash_numof_locks(t->htable_bits); e++)
@@ -876,7 +874,6 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
                if (elements >= maxelem && SET_WITH_FORCEADD(set))
                        forceadd = true;
        }
-       rcu_read_unlock_bh();
 
        spin_lock_bh(&t->hregion[r].lock);
        n = rcu_dereference_bh(hbucket(t, key));