|
@@ -303,16 +303,24 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout)
|
|
{
|
|
{
|
|
struct nf_conntrack_tuple_hash *h;
|
|
struct nf_conntrack_tuple_hash *h;
|
|
const struct hlist_nulls_node *nn;
|
|
const struct hlist_nulls_node *nn;
|
|
|
|
+ unsigned int last_hsize;
|
|
|
|
+ spinlock_t *lock;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
local_bh_disable();
|
|
local_bh_disable();
|
|
- for (i = 0; i < nf_conntrack_htable_size; i++) {
|
|
|
|
- nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
|
|
|
- if (i < nf_conntrack_htable_size) {
|
|
|
|
- hlist_nulls_for_each_entry(h, nn, &nf_conntrack_hash[i], hnnode)
|
|
|
|
- untimeout(h, timeout);
|
|
|
|
|
|
+restart:
|
|
|
|
+ last_hsize = nf_conntrack_htable_size;
|
|
|
|
+ for (i = 0; i < last_hsize; i++) {
|
|
|
|
+ lock = &nf_conntrack_locks[i % CONNTRACK_LOCKS];
|
|
|
|
+ nf_conntrack_lock(lock);
|
|
|
|
+ if (last_hsize != nf_conntrack_htable_size) {
|
|
|
|
+ spin_unlock(lock);
|
|
|
|
+ goto restart;
|
|
}
|
|
}
|
|
- spin_unlock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
|
|
|
|
|
|
+
|
|
|
|
+ hlist_nulls_for_each_entry(h, nn, &nf_conntrack_hash[i], hnnode)
|
|
|
|
+ untimeout(h, timeout);
|
|
|
|
+ spin_unlock(lock);
|
|
}
|
|
}
|
|
local_bh_enable();
|
|
local_bh_enable();
|
|
}
|
|
}
|