]> www.infradead.org Git - users/willy/linux.git/commitdiff
netfilter: nft_set_pipapo: Store real pointer, adjust later.
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Fri, 15 Aug 2025 16:09:35 +0000 (18:09 +0200)
committerFlorian Westphal <fw@strlen.de>
Wed, 20 Aug 2025 11:52:37 +0000 (13:52 +0200)
The struct nft_pipapo_scratch is allocated, then aligned to the required
alignment and difference (in bytes) is then saved in align_off. The
aligned pointer is used later.
While this works, it gets complicated with all the extra checks if
all member before map are larger than the required alignment.

Instead of saving the aligned pointer, just save the returned pointer
and align the map pointer in nft_pipapo_lookup() before using it. The
alignment later on shouldn't be that expensive. With this change, the
align_off can be removed and the pointer can be passed to kfree() as is.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nft_set_pipapo.c
net/netfilter/nft_set_pipapo.h
net/netfilter/nft_set_pipapo_avx2.c

index 7ed9c5f0e2333b3d5906d28315a7ded4ece53df1..96b7539f5506acce27da4cd8503008592a808912 100644 (file)
@@ -418,8 +418,8 @@ static struct nft_pipapo_elem *pipapo_get_slow(const struct nft_pipapo_match *m,
                                               const u8 *data, u8 genmask,
                                               u64 tstamp)
 {
+       unsigned long *res_map, *fill_map, *map;
        struct nft_pipapo_scratch *scratch;
-       unsigned long *res_map, *fill_map;
        const struct nft_pipapo_field *f;
        bool map_index;
        int i;
@@ -432,8 +432,9 @@ static struct nft_pipapo_elem *pipapo_get_slow(const struct nft_pipapo_match *m,
 
        map_index = scratch->map_index;
 
-       res_map  = scratch->map + (map_index ? m->bsize_max : 0);
-       fill_map = scratch->map + (map_index ? 0 : m->bsize_max);
+       map = NFT_PIPAPO_LT_ALIGN(&scratch->__map[0]);
+       res_map  = map + (map_index ? m->bsize_max : 0);
+       fill_map = map + (map_index ? 0 : m->bsize_max);
 
        pipapo_resmap_init(m, res_map);
 
@@ -1171,22 +1172,17 @@ static void pipapo_map(struct nft_pipapo_match *m,
 }
 
 /**
- * pipapo_free_scratch() - Free per-CPU map at original (not aligned) address
+ * pipapo_free_scratch() - Free per-CPU map at original address
  * @m:         Matching data
  * @cpu:       CPU number
  */
 static void pipapo_free_scratch(const struct nft_pipapo_match *m, unsigned int cpu)
 {
        struct nft_pipapo_scratch *s;
-       void *mem;
 
        s = *per_cpu_ptr(m->scratch, cpu);
-       if (!s)
-               return;
 
-       mem = s;
-       mem -= s->align_off;
-       kvfree(mem);
+       kvfree(s);
 }
 
 /**
@@ -1203,11 +1199,8 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone,
 
        for_each_possible_cpu(i) {
                struct nft_pipapo_scratch *scratch;
-#ifdef NFT_PIPAPO_ALIGN
-               void *scratch_aligned;
-               u32 align_off;
-#endif
-               scratch = kvzalloc_node(struct_size(scratch, map, bsize_max * 2) +
+
+               scratch = kvzalloc_node(struct_size(scratch, __map, bsize_max * 2) +
                                        NFT_PIPAPO_ALIGN_HEADROOM,
                                        GFP_KERNEL_ACCOUNT, cpu_to_node(i));
                if (!scratch) {
@@ -1222,23 +1215,6 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone,
                }
 
                pipapo_free_scratch(clone, i);
-
-#ifdef NFT_PIPAPO_ALIGN
-               /* Align &scratch->map (not the struct itself): the extra
-                * %NFT_PIPAPO_ALIGN_HEADROOM bytes passed to kzalloc_node()
-                * above guarantee we can waste up to those bytes in order
-                * to align the map field regardless of its offset within
-                * the struct.
-                */
-               BUILD_BUG_ON(offsetof(struct nft_pipapo_scratch, map) > NFT_PIPAPO_ALIGN_HEADROOM);
-
-               scratch_aligned = NFT_PIPAPO_LT_ALIGN(&scratch->map);
-               scratch_aligned -= offsetof(struct nft_pipapo_scratch, map);
-               align_off = scratch_aligned - (void *)scratch;
-
-               scratch = scratch_aligned;
-               scratch->align_off = align_off;
-#endif
                *per_cpu_ptr(clone->scratch, i) = scratch;
        }
 
index 4a2ff85ce1c435b01d3bc7e1219476667c4911c4..e10cdbaa65d8864a2c9174780a82cb44776709af 100644 (file)
@@ -125,13 +125,11 @@ struct nft_pipapo_field {
 /**
  * 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
+ * @__map:     store partial matching results during lookup
  */
 struct nft_pipapo_scratch {
        u8 map_index;
-       u32 align_off;
-       unsigned long map[];
+       unsigned long __map[];
 };
 
 /**
index 028c11724b42999bb8ef689b1c94151ca4d6de77..f0d8c796d7318695be4ab8ba21d159fb3a81a9a0 100644 (file)
@@ -1155,7 +1155,7 @@ struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
 {
        struct nft_pipapo_scratch *scratch;
        const struct nft_pipapo_field *f;
-       unsigned long *res, *fill;
+       unsigned long *res, *fill, *map;
        bool map_index;
        int i;
 
@@ -1164,9 +1164,9 @@ struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
                return NULL;
 
        map_index = scratch->map_index;
-
-       res  = scratch->map + (map_index ? m->bsize_max : 0);
-       fill = scratch->map + (map_index ? 0 : m->bsize_max);
+       map = NFT_PIPAPO_LT_ALIGN(&scratch->__map[0]);
+       res  = map + (map_index ? m->bsize_max : 0);
+       fill = map + (map_index ? 0 : m->bsize_max);
 
        pipapo_resmap_init_avx2(m, res);