Skip to content

Commit 6aa67d5

Browse files
Sebastian Andrzej SiewiorFlorian Westphal
authored andcommitted
netfilter: nft_set_pipapo: Store real pointer, adjust later.
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 <[email protected]> Signed-off-by: Florian Westphal <[email protected]>
1 parent 84c1da7 commit 6aa67d5

File tree

3 files changed

+14
-40
lines changed

3 files changed

+14
-40
lines changed

net/netfilter/nft_set_pipapo.c

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,8 @@ static struct nft_pipapo_elem *pipapo_get_slow(const struct nft_pipapo_match *m,
418418
const u8 *data, u8 genmask,
419419
u64 tstamp)
420420
{
421+
unsigned long *res_map, *fill_map, *map;
421422
struct nft_pipapo_scratch *scratch;
422-
unsigned long *res_map, *fill_map;
423423
const struct nft_pipapo_field *f;
424424
bool map_index;
425425
int i;
@@ -432,8 +432,9 @@ static struct nft_pipapo_elem *pipapo_get_slow(const struct nft_pipapo_match *m,
432432

433433
map_index = scratch->map_index;
434434

435-
res_map = scratch->map + (map_index ? m->bsize_max : 0);
436-
fill_map = scratch->map + (map_index ? 0 : m->bsize_max);
435+
map = NFT_PIPAPO_LT_ALIGN(&scratch->__map[0]);
436+
res_map = map + (map_index ? m->bsize_max : 0);
437+
fill_map = map + (map_index ? 0 : m->bsize_max);
437438

438439
pipapo_resmap_init(m, res_map);
439440

@@ -1171,22 +1172,17 @@ static void pipapo_map(struct nft_pipapo_match *m,
11711172
}
11721173

11731174
/**
1174-
* pipapo_free_scratch() - Free per-CPU map at original (not aligned) address
1175+
* pipapo_free_scratch() - Free per-CPU map at original address
11751176
* @m: Matching data
11761177
* @cpu: CPU number
11771178
*/
11781179
static void pipapo_free_scratch(const struct nft_pipapo_match *m, unsigned int cpu)
11791180
{
11801181
struct nft_pipapo_scratch *s;
1181-
void *mem;
11821182

11831183
s = *per_cpu_ptr(m->scratch, cpu);
1184-
if (!s)
1185-
return;
11861184

1187-
mem = s;
1188-
mem -= s->align_off;
1189-
kvfree(mem);
1185+
kvfree(s);
11901186
}
11911187

11921188
/**
@@ -1203,11 +1199,8 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone,
12031199

12041200
for_each_possible_cpu(i) {
12051201
struct nft_pipapo_scratch *scratch;
1206-
#ifdef NFT_PIPAPO_ALIGN
1207-
void *scratch_aligned;
1208-
u32 align_off;
1209-
#endif
1210-
scratch = kvzalloc_node(struct_size(scratch, map, bsize_max * 2) +
1202+
1203+
scratch = kvzalloc_node(struct_size(scratch, __map, bsize_max * 2) +
12111204
NFT_PIPAPO_ALIGN_HEADROOM,
12121205
GFP_KERNEL_ACCOUNT, cpu_to_node(i));
12131206
if (!scratch) {
@@ -1222,23 +1215,6 @@ static int pipapo_realloc_scratch(struct nft_pipapo_match *clone,
12221215
}
12231216

12241217
pipapo_free_scratch(clone, i);
1225-
1226-
#ifdef NFT_PIPAPO_ALIGN
1227-
/* Align &scratch->map (not the struct itself): the extra
1228-
* %NFT_PIPAPO_ALIGN_HEADROOM bytes passed to kzalloc_node()
1229-
* above guarantee we can waste up to those bytes in order
1230-
* to align the map field regardless of its offset within
1231-
* the struct.
1232-
*/
1233-
BUILD_BUG_ON(offsetof(struct nft_pipapo_scratch, map) > NFT_PIPAPO_ALIGN_HEADROOM);
1234-
1235-
scratch_aligned = NFT_PIPAPO_LT_ALIGN(&scratch->map);
1236-
scratch_aligned -= offsetof(struct nft_pipapo_scratch, map);
1237-
align_off = scratch_aligned - (void *)scratch;
1238-
1239-
scratch = scratch_aligned;
1240-
scratch->align_off = align_off;
1241-
#endif
12421218
*per_cpu_ptr(clone->scratch, i) = scratch;
12431219
}
12441220

net/netfilter/nft_set_pipapo.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,11 @@ struct nft_pipapo_field {
125125
/**
126126
* struct nft_pipapo_scratch - percpu data used for lookup and matching
127127
* @map_index: Current working bitmap index, toggled between field matches
128-
* @align_off: Offset to get the originally allocated address
129-
* @map: store partial matching results during lookup
128+
* @__map: store partial matching results during lookup
130129
*/
131130
struct nft_pipapo_scratch {
132131
u8 map_index;
133-
u32 align_off;
134-
unsigned long map[];
132+
unsigned long __map[];
135133
};
136134

137135
/**

net/netfilter/nft_set_pipapo_avx2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
11551155
{
11561156
struct nft_pipapo_scratch *scratch;
11571157
const struct nft_pipapo_field *f;
1158-
unsigned long *res, *fill;
1158+
unsigned long *res, *fill, *map;
11591159
bool map_index;
11601160
int i;
11611161

@@ -1164,9 +1164,9 @@ struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
11641164
return NULL;
11651165

11661166
map_index = scratch->map_index;
1167-
1168-
res = scratch->map + (map_index ? m->bsize_max : 0);
1169-
fill = scratch->map + (map_index ? 0 : m->bsize_max);
1167+
map = NFT_PIPAPO_LT_ALIGN(&scratch->__map[0]);
1168+
res = map + (map_index ? m->bsize_max : 0);
1169+
fill = map + (map_index ? 0 : m->bsize_max);
11701170

11711171
pipapo_resmap_init_avx2(m, res);
11721172

0 commit comments

Comments
 (0)