netfilter: nf_tables: remove busy mark and gc batch API
Ditch it, it has been replace it by the GC transaction API and it has no clients anymore. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
c92db30304
commit
a2dd0233cb
@ -599,7 +599,6 @@ struct nft_set *nft_set_lookup_global(const struct net *net,
|
|||||||
|
|
||||||
struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
|
struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
|
||||||
const struct nft_set *set);
|
const struct nft_set *set);
|
||||||
void *nft_set_catchall_gc(const struct nft_set *set);
|
|
||||||
|
|
||||||
static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
|
static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
|
||||||
{
|
{
|
||||||
@ -816,62 +815,6 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
|
|||||||
void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
||||||
const struct nft_set *set, void *elem);
|
const struct nft_set *set, void *elem);
|
||||||
|
|
||||||
/**
|
|
||||||
* struct nft_set_gc_batch_head - nf_tables set garbage collection batch
|
|
||||||
*
|
|
||||||
* @rcu: rcu head
|
|
||||||
* @set: set the elements belong to
|
|
||||||
* @cnt: count of elements
|
|
||||||
*/
|
|
||||||
struct nft_set_gc_batch_head {
|
|
||||||
struct rcu_head rcu;
|
|
||||||
const struct nft_set *set;
|
|
||||||
unsigned int cnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \
|
|
||||||
sizeof(struct nft_set_gc_batch_head)) / \
|
|
||||||
sizeof(void *))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct nft_set_gc_batch - nf_tables set garbage collection batch
|
|
||||||
*
|
|
||||||
* @head: GC batch head
|
|
||||||
* @elems: garbage collection elements
|
|
||||||
*/
|
|
||||||
struct nft_set_gc_batch {
|
|
||||||
struct nft_set_gc_batch_head head;
|
|
||||||
void *elems[NFT_SET_GC_BATCH_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
|
|
||||||
gfp_t gfp);
|
|
||||||
void nft_set_gc_batch_release(struct rcu_head *rcu);
|
|
||||||
|
|
||||||
static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
|
|
||||||
{
|
|
||||||
if (gcb != NULL)
|
|
||||||
call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct nft_set_gc_batch *
|
|
||||||
nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
|
|
||||||
gfp_t gfp)
|
|
||||||
{
|
|
||||||
if (gcb != NULL) {
|
|
||||||
if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
|
|
||||||
return gcb;
|
|
||||||
nft_set_gc_batch_complete(gcb);
|
|
||||||
}
|
|
||||||
return nft_set_gc_batch_alloc(set, gfp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
|
|
||||||
void *elem)
|
|
||||||
{
|
|
||||||
gcb->elems[gcb->head.cnt++] = elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nft_expr_ops;
|
struct nft_expr_ops;
|
||||||
/**
|
/**
|
||||||
* struct nft_expr_type - nf_tables expression type
|
* struct nft_expr_type - nf_tables expression type
|
||||||
@ -1560,47 +1503,12 @@ static inline void nft_set_elem_change_active(const struct net *net,
|
|||||||
|
|
||||||
#endif /* IS_ENABLED(CONFIG_NF_TABLES) */
|
#endif /* IS_ENABLED(CONFIG_NF_TABLES) */
|
||||||
|
|
||||||
/*
|
#define NFT_SET_ELEM_DEAD_MASK (1 << 2)
|
||||||
* We use a free bit in the genmask field to indicate the element
|
|
||||||
* is busy, meaning it is currently being processed either by
|
|
||||||
* the netlink API or GC.
|
|
||||||
*
|
|
||||||
* Even though the genmask is only a single byte wide, this works
|
|
||||||
* because the extension structure if fully constant once initialized,
|
|
||||||
* so there are no non-atomic write accesses unless it is already
|
|
||||||
* marked busy.
|
|
||||||
*/
|
|
||||||
#define NFT_SET_ELEM_BUSY_MASK (1 << 2)
|
|
||||||
|
|
||||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||||
#define NFT_SET_ELEM_BUSY_BIT 2
|
#define NFT_SET_ELEM_DEAD_BIT 2
|
||||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
#elif defined(__BIG_ENDIAN_BITFIELD)
|
||||||
#define NFT_SET_ELEM_BUSY_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2)
|
#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 2)
|
||||||
#else
|
|
||||||
#error
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext)
|
|
||||||
{
|
|
||||||
unsigned long *word = (unsigned long *)ext;
|
|
||||||
|
|
||||||
BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
|
|
||||||
return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
|
|
||||||
{
|
|
||||||
unsigned long *word = (unsigned long *)ext;
|
|
||||||
|
|
||||||
clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NFT_SET_ELEM_DEAD_MASK (1 << 3)
|
|
||||||
|
|
||||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
|
||||||
#define NFT_SET_ELEM_DEAD_BIT 3
|
|
||||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
|
||||||
#define NFT_SET_ELEM_DEAD_BIT (BITS_PER_LONG - BITS_PER_BYTE + 3)
|
|
||||||
#else
|
#else
|
||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
@ -6296,29 +6296,6 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nft_set_catchall_lookup);
|
EXPORT_SYMBOL_GPL(nft_set_catchall_lookup);
|
||||||
|
|
||||||
void *nft_set_catchall_gc(const struct nft_set *set)
|
|
||||||
{
|
|
||||||
struct nft_set_elem_catchall *catchall, *next;
|
|
||||||
struct nft_set_ext *ext;
|
|
||||||
void *elem = NULL;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
|
|
||||||
ext = nft_set_elem_ext(set, catchall->elem);
|
|
||||||
|
|
||||||
if (!nft_set_elem_expired(ext) ||
|
|
||||||
nft_set_elem_mark_busy(ext))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
elem = catchall->elem;
|
|
||||||
list_del_rcu(&catchall->list);
|
|
||||||
kfree_rcu(catchall, rcu);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(nft_set_catchall_gc);
|
|
||||||
|
|
||||||
static int nft_setelem_catchall_insert(const struct net *net,
|
static int nft_setelem_catchall_insert(const struct net *net,
|
||||||
struct nft_set *set,
|
struct nft_set *set,
|
||||||
const struct nft_set_elem *elem,
|
const struct nft_set_elem *elem,
|
||||||
@ -6789,7 +6766,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
|||||||
goto err_elem_free;
|
goto err_elem_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
|
ext->genmask = nft_genmask_cur(ctx->net);
|
||||||
|
|
||||||
err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags);
|
err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -7181,29 +7158,6 @@ static int nf_tables_delsetelem(struct sk_buff *skb,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nft_set_gc_batch_release(struct rcu_head *rcu)
|
|
||||||
{
|
|
||||||
struct nft_set_gc_batch *gcb;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
|
|
||||||
for (i = 0; i < gcb->head.cnt; i++)
|
|
||||||
nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
|
|
||||||
kfree(gcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
|
|
||||||
gfp_t gfp)
|
|
||||||
{
|
|
||||||
struct nft_set_gc_batch *gcb;
|
|
||||||
|
|
||||||
gcb = kzalloc(sizeof(*gcb), gfp);
|
|
||||||
if (gcb == NULL)
|
|
||||||
return gcb;
|
|
||||||
gcb->head.set = set;
|
|
||||||
return gcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stateful objects
|
* Stateful objects
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user