@@ -392,6 +392,8 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
struct nf_conntrack_expect *exp;
const struct hlist_node *next;
const struct hlist_nulls_node *nn;
+ unsigned int sequence;
+ spinlock_t *lock;
unsigned int i;
int cpu;
@@ -422,14 +424,22 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
unhelp(h, me);
spin_unlock_bh(&pcpu->lock);
}
+
local_bh_disable();
+restart:
+ sequence = read_seqcount_begin(&nf_conntrack_generation);
for (i = 0; i < nf_conntrack_htable_size; i++) {
- nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
+ lock = &nf_conntrack_locks[i % CONNTRACK_LOCKS];
+ nf_conntrack_lock(lock);
+ if (read_seqcount_retry(&nf_conntrack_generation, sequence)) {
+ spin_unlock(lock);
+ goto restart;
+ }
if (i < nf_conntrack_htable_size) {
hlist_nulls_for_each_entry(h, nn, &nf_conntrack_hash[i], hnnode)
unhelp(h, me);
}
- spin_unlock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
+ spin_unlock(lock);
}
local_bh_enable();
}