First couple of patches could be applied, as they add more warns/checks to the control plane. Actual gc changes are not for merging, this is for archive only; I don't see a compelling reason at this time to do this. The implemeneted strategy is to have the async gc (rhashtable) enqueue the *key* of *gc candidates*, rather than the actual expired elements. Therefore no races with control plane are possible and the "gc sequence" can be removed. If async gc enqueues element e and control plane removes it before gc has a chance to run, then gc will no longer find it -> no op. If control plane removes and re-adds -> gc candidate is not expired -> no op. Downside is the vast increase in memory (instead of just storing a pointer, we need to be able to store the max key size, i.e. 64 byte). I'll mark most of this as RFC in patchwork so we can recover this work later if there is any issue with the exising gc mechanism that this approach would avoid. Florian Westphal (9): netfilter: nf_tables: warn if set being destroyed is still active netfilter: nf_tables: decrement element counters on set removal/flush netfilter: nf_tables: add lockdep assertion for chain use counter netfilter: remove nft_trans_gc_catchall_async handling netfilter: nf_tables: condense catchall gc netfilter: nf_tables: add in-kernel only query that will return expired/dead elements netfilter: nf_tables: prepare for key-based deletion from workqueue netfilter: nf_tables: remove expired elements based on key lookup only netfilter: nf_tables: remove gc sequence counter include/net/netfilter/nf_tables.h | 27 +-- include/uapi/linux/netfilter/nf_tables.h | 5 + net/netfilter/nf_tables_api.c | 280 ++++++++++++++--------- net/netfilter/nft_set_bitmap.c | 5 +- net/netfilter/nft_set_hash.c | 39 ++-- net/netfilter/nft_set_pipapo.c | 6 +- net/netfilter/nft_set_rbtree.c | 8 +- 7 files changed, 216 insertions(+), 154 deletions(-) -- 2.43.0