[ Upstream commit
5a8cdf6fd860ac5e6d08d72edbcecee049a7fec4 ]
use ->scratch for both avx2 and the generic implementation.
After previous change the scratch->map member is always aligned properly
for AVX2, so we can just use scratch->map in AVX2 too.
The alignoff delta is stored in the scratchpad so we can reconstruct
the correct address to free the area again.
Fixes:
7400b063969b ("nft_set_pipapo: Introduce AVX2-based lookup implementation")
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
struct nft_pipapo_scratch *scratch;
#ifdef NFT_PIPAPO_ALIGN
void *scratch_aligned;
struct nft_pipapo_scratch *scratch;
#ifdef NFT_PIPAPO_ALIGN
void *scratch_aligned;
#endif
scratch = kzalloc_node(struct_size(scratch, map,
bsize_max * 2) +
#endif
scratch = kzalloc_node(struct_size(scratch, map,
bsize_max * 2) +
pipapo_free_scratch(clone, i);
pipapo_free_scratch(clone, i);
- *per_cpu_ptr(clone->scratch, i) = scratch;
-
#ifdef NFT_PIPAPO_ALIGN
/* Align &scratch->map (not the struct itself): the extra
* %NFT_PIPAPO_ALIGN_HEADROOM bytes passed to kzalloc_node()
#ifdef NFT_PIPAPO_ALIGN
/* Align &scratch->map (not the struct itself): the extra
* %NFT_PIPAPO_ALIGN_HEADROOM bytes passed to kzalloc_node()
scratch_aligned = NFT_PIPAPO_LT_ALIGN(&scratch->map);
scratch_aligned -= offsetof(struct nft_pipapo_scratch, map);
scratch_aligned = NFT_PIPAPO_LT_ALIGN(&scratch->map);
scratch_aligned -= offsetof(struct nft_pipapo_scratch, map);
- *per_cpu_ptr(clone->scratch_aligned, i) = scratch_aligned;
+ align_off = scratch_aligned - (void *)scratch;
+
+ scratch = scratch_aligned;
+ scratch->align_off = align_off;
+ *per_cpu_ptr(clone->scratch, i) = scratch;
if (!new->scratch)
goto out_scratch;
if (!new->scratch)
goto out_scratch;
-#ifdef NFT_PIPAPO_ALIGN
- new->scratch_aligned = alloc_percpu(*new->scratch_aligned);
- if (!new->scratch_aligned)
- goto out_scratch;
-#endif
for_each_possible_cpu(i)
*per_cpu_ptr(new->scratch, i) = NULL;
for_each_possible_cpu(i)
*per_cpu_ptr(new->scratch, i) = NULL;
out_scratch_realloc:
for_each_possible_cpu(i)
pipapo_free_scratch(new, i);
out_scratch_realloc:
for_each_possible_cpu(i)
pipapo_free_scratch(new, i);
-#ifdef NFT_PIPAPO_ALIGN
- free_percpu(new->scratch_aligned);
-#endif
out_scratch:
free_percpu(new->scratch);
kfree(new);
out_scratch:
free_percpu(new->scratch);
kfree(new);
for_each_possible_cpu(i)
pipapo_free_scratch(m, i);
for_each_possible_cpu(i)
pipapo_free_scratch(m, i);
-#ifdef NFT_PIPAPO_ALIGN
- free_percpu(m->scratch_aligned);
-#endif
pipapo_free_fields(m);
kfree(m);
pipapo_free_fields(m);
kfree(m);
for_each_possible_cpu(i)
*per_cpu_ptr(m->scratch, i) = NULL;
for_each_possible_cpu(i)
*per_cpu_ptr(m->scratch, i) = NULL;
-#ifdef NFT_PIPAPO_ALIGN
- m->scratch_aligned = alloc_percpu(struct nft_pipapo_scratch *);
- if (!m->scratch_aligned) {
- err = -ENOMEM;
- goto out_free;
- }
- for_each_possible_cpu(i)
- *per_cpu_ptr(m->scratch_aligned, i) = NULL;
-#endif
-
rcu_head_init(&m->rcu);
nft_pipapo_for_each_field(f, i, m) {
rcu_head_init(&m->rcu);
nft_pipapo_for_each_field(f, i, m) {
-#ifdef NFT_PIPAPO_ALIGN
- free_percpu(m->scratch_aligned);
-#endif
free_percpu(m->scratch);
out_scratch:
kfree(m);
free_percpu(m->scratch);
out_scratch:
kfree(m);
nft_set_pipapo_match_destroy(ctx, set, m);
nft_set_pipapo_match_destroy(ctx, set, m);
-#ifdef NFT_PIPAPO_ALIGN
- free_percpu(m->scratch_aligned);
-#endif
for_each_possible_cpu(cpu)
pipapo_free_scratch(m, cpu);
free_percpu(m->scratch);
for_each_possible_cpu(cpu)
pipapo_free_scratch(m, cpu);
free_percpu(m->scratch);
if (priv->dirty)
nft_set_pipapo_match_destroy(ctx, set, m);
if (priv->dirty)
nft_set_pipapo_match_destroy(ctx, set, m);
-#ifdef NFT_PIPAPO_ALIGN
- free_percpu(priv->clone->scratch_aligned);
-#endif
for_each_possible_cpu(cpu)
pipapo_free_scratch(priv->clone, cpu);
free_percpu(priv->clone->scratch);
for_each_possible_cpu(cpu)
pipapo_free_scratch(priv->clone, cpu);
free_percpu(priv->clone->scratch);
/**
* struct nft_pipapo_scratch - percpu data used for lookup and matching
* @map_index: Current working bitmap index, toggled between field matches
/**
* struct nft_pipapo_scratch - percpu data used for lookup and matching
* @map_index: Current working bitmap index, toggled between field matches
+ * @align_off: Offset to get the originally allocated address
* @map: store partial matching results during lookup
*/
struct nft_pipapo_scratch {
u8 map_index;
* @map: store partial matching results during lookup
*/
struct nft_pipapo_scratch {
u8 map_index;
* struct nft_pipapo_match - Data used for lookup and matching
* @field_count Amount of fields in set
* @scratch: Preallocated per-CPU maps for partial matching results
* struct nft_pipapo_match - Data used for lookup and matching
* @field_count Amount of fields in set
* @scratch: Preallocated per-CPU maps for partial matching results
- * @scratch_aligned: Version of @scratch aligned to NFT_PIPAPO_ALIGN bytes
* @bsize_max: Maximum lookup table bucket size of all fields, in longs
* @rcu Matching data is swapped on commits
* @f: Fields, with lookup and mapping tables
*/
struct nft_pipapo_match {
int field_count;
* @bsize_max: Maximum lookup table bucket size of all fields, in longs
* @rcu Matching data is swapped on commits
* @f: Fields, with lookup and mapping tables
*/
struct nft_pipapo_match {
int field_count;
-#ifdef NFT_PIPAPO_ALIGN
- struct nft_pipapo_scratch * __percpu *scratch_aligned;
-#endif
struct nft_pipapo_scratch * __percpu *scratch;
size_t bsize_max;
struct rcu_head rcu;
struct nft_pipapo_scratch * __percpu *scratch;
size_t bsize_max;
struct rcu_head rcu;
*/
kernel_fpu_begin_mask(0);
*/
kernel_fpu_begin_mask(0);
- scratch = *raw_cpu_ptr(m->scratch_aligned);
+ scratch = *raw_cpu_ptr(m->scratch);
if (unlikely(!scratch)) {
kernel_fpu_end();
return false;
if (unlikely(!scratch)) {
kernel_fpu_end();
return false;