diff options
author | Florian Westphal <fw@strlen.de> | 2018-01-04 13:24:44 +0100 |
---|---|---|
committer | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2018-01-04 13:24:44 +0100 |
commit | 56004fb77322d454e72187394a1f17e457cb3e04 (patch) | |
tree | 6a462cda469e73ad5f7cd95f8e839f3358f947da /kernel/net/netfilter/ipset/ip_set_hash_gen.h | |
parent | ad92ed77e77fe421a86f0fde907c51286ed47928 (diff) | |
download | ipset-56004fb77322d454e72187394a1f17e457cb3e04.tar.gz |
netfilter: ipset: add resched points during set listing
When sets are extremely large we can get softlockup during ipset -L.
We could fix this by adding cond_resched_rcu() at the right location
during iteration, but this only works if RCU nesting depth is 1.
At this time entire variant->list() is called under under rcu_read_lock_bh.
This used to be a read_lock_bh() but as rcu doesn't really lock anything,
it does not appear to be needed, so remove it (ipset increments set
reference count before this, so a set deletion should not be possible).
Reported-by: Li Shuang <shuali@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'kernel/net/netfilter/ipset/ip_set_hash_gen.h')
-rw-r--r-- | kernel/net/netfilter/ipset/ip_set_hash_gen.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h index 291c7d4..49a5958 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h +++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h @@ -1136,6 +1136,7 @@ mtype_list(const struct ip_set *set, rcu_read_lock(); for (; cb->args[IPSET_CB_ARG0] < jhash_size(t->htable_bits); cb->args[IPSET_CB_ARG0]++) { + cond_resched_rcu(); incomplete = skb_tail_pointer(skb); n = rcu_dereference(hbucket(t, cb->args[IPSET_CB_ARG0])); pr_debug("cb->arg bucket: %lu, t %p n %p\n", |