summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2015-11-04 09:48:39 +0100
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2015-11-07 11:02:43 +0100
commitbf21c385be47e5f77b9384c8a4177c803d83ad42 (patch)
tree97fa34f8a929e25265fd85bee4b232050f50bd6b
parent7623e1bcf0be0c65e2abc9a0dcd3ec606e501dc5 (diff)
Fix hash type expire: release empty hash bucket block
When all entries are expired/all slots are empty, release the bucket. Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
-rw-r--r--kernel/net/netfilter/ipset/ip_set_hash_gen.h14
1 files changed, 10 insertions, 4 deletions
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h
index d774059..6989fcb 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h
@@ -465,7 +465,7 @@ static void
mtype_expire(struct ip_set *set, struct htype *h)
{
struct htable *t;
- struct hbucket *n;
+ struct hbucket *n, *tmp;
struct mtype_elem *data;
u32 i, j, d;
size_t dsize = set->dsize;
@@ -500,9 +500,15 @@ mtype_expire(struct ip_set *set, struct htype *h)
d++;
}
if (d >= AHASH_INIT_SIZE) {
- struct hbucket *tmp = kzalloc(sizeof(*tmp) +
- (n->size - AHASH_INIT_SIZE) * dsize,
- GFP_ATOMIC);
+ if (d >= n->size) {
+ set->ext_size -= ext_size(n->size, dsize);
+ rcu_assign_pointer(hbucket(t, i), NULL);
+ kfree_rcu(n, rcu);
+ continue;
+ }
+ tmp = kzalloc(sizeof(*tmp) +
+ (n->size - AHASH_INIT_SIZE) * dsize,
+ GFP_ATOMIC);
if (!tmp)
/* Still try to delete expired elements */
continue;