Not a bug fix, idea is that this allows us to add runtime assertions, when set is free'd counter should be 0 as well. Signed-off-by: Florian Westphal <fw@xxxxxxxxx> --- net/netfilter/nf_tables_api.c | 5 +++++ net/netfilter/nft_set_bitmap.c | 5 ++++- net/netfilter/nft_set_hash.c | 6 ++++++ net/netfilter/nft_set_pipapo.c | 2 ++ net/netfilter/nft_set_rbtree.c | 2 ++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index be8254d31988..bac5847a5499 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5261,6 +5261,10 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx, static void nft_set_put(struct nft_set *set) { if (refcount_dec_and_test(&set->refs)) { + unsigned int nelems = atomic_read(&set->nelems); + + WARN(nelems, "set %s (%ps) has element count of %u\n", + set->name, set->ops->lookup, nelems); kfree(set->name); kvfree(set); } @@ -9663,6 +9667,7 @@ static void nft_trans_gc_trans_free(struct rcu_head *rcu) if (!nft_setelem_is_catchall(trans->set, elem_priv)) atomic_dec(&trans->set->nelems); + WARN_ON_ONCE(atomic_read(&trans->set->nelems) < 0); nf_tables_set_elem_destroy(&ctx, trans->set, elem_priv); } diff --git a/net/netfilter/nft_set_bitmap.c b/net/netfilter/nft_set_bitmap.c index 32df7a16835d..5999415467ef 100644 --- a/net/netfilter/nft_set_bitmap.c +++ b/net/netfilter/nft_set_bitmap.c @@ -275,9 +275,12 @@ static void nft_bitmap_destroy(const struct nft_ctx *ctx, { struct nft_bitmap *priv = nft_set_priv(set); struct nft_bitmap_elem *be, *n; + struct nft_set *mset = (void *)set; - list_for_each_entry_safe(be, n, &priv->list, head) + list_for_each_entry_safe(be, n, &priv->list, head) { nf_tables_set_elem_destroy(ctx, set, &be->priv); + atomic_dec(&mset->nelems); + } } static bool nft_bitmap_estimate(const struct nft_set_desc *desc, u32 features, diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c index 06337a089c34..6b0f84ef4e5f 100644 --- a/net/netfilter/nft_set_hash.c +++ b/net/netfilter/nft_set_hash.c @@ -438,8 +438,12 @@ static void nft_rhash_elem_destroy(void *ptr, void *arg) { struct nft_rhash_ctx *rhash_ctx = arg; struct nft_rhash_elem *he = ptr; + struct nft_set *set; nf_tables_set_elem_destroy(&rhash_ctx->ctx, rhash_ctx->set, &he->priv); + + set = (struct nft_set *)rhash_ctx->set; + atomic_dec(&set->nelems); } static void nft_rhash_destroy(const struct nft_ctx *ctx, @@ -688,6 +692,7 @@ static int nft_hash_init(const struct nft_set *set, static void nft_hash_destroy(const struct nft_ctx *ctx, const struct nft_set *set) { + struct nft_set *mset = (struct nft_set *)set; struct nft_hash *priv = nft_set_priv(set); struct nft_hash_elem *he; struct hlist_node *next; @@ -697,6 +702,7 @@ static void nft_hash_destroy(const struct nft_ctx *ctx, hlist_for_each_entry_safe(he, next, &priv->table[i], node) { hlist_del_rcu(&he->node); nf_tables_set_elem_destroy(ctx, set, &he->priv); + atomic_dec(&mset->nelems); } } } diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index c0ceea068936..4797f1aa3c11 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -2295,6 +2295,7 @@ static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx, const struct nft_set *set, struct nft_pipapo_match *m) { + struct nft_set *mset = (void *)set; struct nft_pipapo_field *f; unsigned int i, r; @@ -2310,6 +2311,7 @@ static void nft_set_pipapo_match_destroy(const struct nft_ctx *ctx, e = f->mt[r].e; nf_tables_set_elem_destroy(ctx, set, &e->priv); + atomic_dec(&mset->nelems); } } diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index 9944fe479e53..0da94e9378ca 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -709,6 +709,7 @@ static void nft_rbtree_destroy(const struct nft_ctx *ctx, const struct nft_set *set) { struct nft_rbtree *priv = nft_set_priv(set); + struct nft_set *mset = (void *)set; struct nft_rbtree_elem *rbe; struct rb_node *node; @@ -716,6 +717,7 @@ static void nft_rbtree_destroy(const struct nft_ctx *ctx, rb_erase(node, &priv->root); rbe = rb_entry(node, struct nft_rbtree_elem, node); nf_tables_set_elem_destroy(ctx, set, &rbe->priv); + atomic_dec(&mset->nelems); } } -- 2.43.0