Skip to content

Commit 84c1da7

Browse files
author
Florian Westphal
committed
netfilter: nft_set_pipapo: use avx2 algorithm for insertions too
Always prefer the avx2 implementation if its available. This greatly improves insertion performance (each insertion checks if the new element would overlap with an existing one): time nft -f - <<EOF table ip pipapo { set s { typeof ip saddr . tcp dport flags interval size 800000 elements = { 10.1.1.1 - 10.1.1.4 . 3996, [.. 800k entries elided .. ] before: real 1m55.993s user 0m2.505s sys 1m53.296s after: real 0m42.586s user 0m2.554s sys 0m39.811s Fold patch from Sebastian: kernel_fpu_begin_mask()/ _end() remains in pipapo_get_avx2() where it is required. A followup patch will add local_lock_t to struct nft_pipapo_scratch in order to protect the map pointer. The lock can not be acquired in preemption disabled context which is what kernel_fpu_begin*() does. Link: https://lore.kernel.org/netfilter-devel/[email protected]/ Co-developed-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: Florian Westphal <[email protected]>
1 parent 416e53e commit 84c1da7

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

net/netfilter/nft_set_pipapo.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ int pipapo_refill(unsigned long *map, unsigned int len, unsigned int rules,
397397
}
398398

399399
/**
400-
* pipapo_get() - Get matching element reference given key data
400+
* pipapo_get_slow() - Get matching element reference given key data
401401
* @m: storage containing the set elements
402402
* @data: Key data to be matched against existing elements
403403
* @genmask: If set, check that element is active in given genmask
@@ -414,9 +414,9 @@ int pipapo_refill(unsigned long *map, unsigned int len, unsigned int rules,
414414
*
415415
* Return: pointer to &struct nft_pipapo_elem on match, NULL otherwise.
416416
*/
417-
static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m,
418-
const u8 *data, u8 genmask,
419-
u64 tstamp)
417+
static struct nft_pipapo_elem *pipapo_get_slow(const struct nft_pipapo_match *m,
418+
const u8 *data, u8 genmask,
419+
u64 tstamp)
420420
{
421421
struct nft_pipapo_scratch *scratch;
422422
unsigned long *res_map, *fill_map;
@@ -502,6 +502,41 @@ static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m,
502502
return NULL;
503503
}
504504

505+
/**
506+
* pipapo_get() - Get matching element reference given key data
507+
* @m: Storage containing the set elements
508+
* @data: Key data to be matched against existing elements
509+
* @genmask: If set, check that element is active in given genmask
510+
* @tstamp: Timestamp to check for expired elements
511+
*
512+
* This is a dispatcher function, either calling out the generic C
513+
* implementation or, if available, the AVX2 one.
514+
* This helper is only called from the control plane, with either RCU
515+
* read lock or transaction mutex held.
516+
*
517+
* Return: pointer to &struct nft_pipapo_elem on match, NULL otherwise.
518+
*/
519+
static struct nft_pipapo_elem *pipapo_get(const struct nft_pipapo_match *m,
520+
const u8 *data, u8 genmask,
521+
u64 tstamp)
522+
{
523+
struct nft_pipapo_elem *e;
524+
525+
local_bh_disable();
526+
527+
#if defined(CONFIG_X86_64) && !defined(CONFIG_UML)
528+
if (boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX) &&
529+
irq_fpu_usable()) {
530+
e = pipapo_get_avx2(m, data, genmask, tstamp);
531+
local_bh_enable();
532+
return e;
533+
}
534+
#endif
535+
e = pipapo_get_slow(m, data, genmask, tstamp);
536+
local_bh_enable();
537+
return e;
538+
}
539+
505540
/**
506541
* nft_pipapo_lookup() - Dataplane fronted for main lookup function
507542
* @net: Network namespace
@@ -523,7 +558,7 @@ nft_pipapo_lookup(const struct net *net, const struct nft_set *set,
523558
const struct nft_pipapo_elem *e;
524559

525560
m = rcu_dereference(priv->match);
526-
e = pipapo_get(m, (const u8 *)key, genmask, get_jiffies_64());
561+
e = pipapo_get_slow(m, (const u8 *)key, genmask, get_jiffies_64());
527562

528563
return e ? &e->ext : NULL;
529564
}

net/netfilter/nft_set_pipapo_avx2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,9 +1149,9 @@ static inline void pipapo_resmap_init_avx2(const struct nft_pipapo_match *m, uns
11491149
*
11501150
* Return: pointer to &struct nft_pipapo_elem on match, NULL otherwise.
11511151
*/
1152-
static struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
1153-
const u8 *data, u8 genmask,
1154-
u64 tstamp)
1152+
struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
1153+
const u8 *data, u8 genmask,
1154+
u64 tstamp)
11551155
{
11561156
struct nft_pipapo_scratch *scratch;
11571157
const struct nft_pipapo_field *f;
@@ -1261,7 +1261,7 @@ static struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
12611261
*
12621262
* This function is called from the data path. It will search for
12631263
* an element matching the given key in the current active copy using
1264-
* the AVX2 routines if the fpu is usable or fall back to the generic
1264+
* the AVX2 routines if the FPU is usable or fall back to the generic
12651265
* implementation of the algorithm otherwise.
12661266
*
12671267
* Return: nftables API extension pointer or NULL if no match.

net/netfilter/nft_set_pipapo_avx2.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
#include <asm/fpu/xstate.h>
66
#define NFT_PIPAPO_ALIGN (XSAVE_YMM_SIZE / BITS_PER_BYTE)
77

8+
struct nft_pipapo_match;
89
bool nft_pipapo_avx2_estimate(const struct nft_set_desc *desc, u32 features,
910
struct nft_set_estimate *est);
11+
struct nft_pipapo_elem *pipapo_get_avx2(const struct nft_pipapo_match *m,
12+
const u8 *data, u8 genmask,
13+
u64 tstamp);
1014
#endif /* defined(CONFIG_X86_64) && !defined(CONFIG_UML) */
1115

1216
#endif /* _NFT_SET_PIPAPO_AVX2_H */

0 commit comments

Comments
 (0)