]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: flowtable: dedicated slab for flow entry
authorQingfang Deng <dqfext@gmail.com>
Fri, 30 Jan 2026 07:22:07 +0000 (15:22 +0800)
committerFlorian Westphal <fw@strlen.de>
Fri, 6 Feb 2026 12:34:55 +0000 (13:34 +0100)
The size of `struct flow_offload` has grown beyond 256 bytes on 64-bit
kernels (currently 280 bytes) because of the `flow_offload_tunnel`
member added recently. So kmalloc() allocates from the kmalloc-512 slab,
causing significant memory waste per entry.

Introduce a dedicated slab cache for flow entries to reduce memory
footprint. Results in a reduction from 512 bytes to 320 bytes per entry
on x86_64 kernels.

Signed-off-by: Qingfang Deng <dqfext@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nf_flow_table_core.c

index 06e8251a6644e2335117ae3720b9ebf159eb2264..2c4140e6f53c51b6da4ea266e77aa8c2e7191120 100644 (file)
@@ -16,6 +16,7 @@
 
 static DEFINE_MUTEX(flowtable_lock);
 static LIST_HEAD(flowtables);
+static __read_mostly struct kmem_cache *flow_offload_cachep;
 
 static void
 flow_offload_fill_dir(struct flow_offload *flow,
@@ -56,7 +57,7 @@ struct flow_offload *flow_offload_alloc(struct nf_conn *ct)
        if (unlikely(nf_ct_is_dying(ct)))
                return NULL;
 
-       flow = kzalloc(sizeof(*flow), GFP_ATOMIC);
+       flow = kmem_cache_zalloc(flow_offload_cachep, GFP_ATOMIC);
        if (!flow)
                return NULL;
 
@@ -812,9 +813,13 @@ static int __init nf_flow_table_module_init(void)
 {
        int ret;
 
+       flow_offload_cachep = KMEM_CACHE(flow_offload, SLAB_HWCACHE_ALIGN);
+       if (!flow_offload_cachep)
+               return -ENOMEM;
+
        ret = register_pernet_subsys(&nf_flow_table_net_ops);
        if (ret < 0)
-               return ret;
+               goto out_pernet;
 
        ret = nf_flow_table_offload_init();
        if (ret)
@@ -830,6 +835,8 @@ out_bpf:
        nf_flow_table_offload_exit();
 out_offload:
        unregister_pernet_subsys(&nf_flow_table_net_ops);
+out_pernet:
+       kmem_cache_destroy(flow_offload_cachep);
        return ret;
 }
 
@@ -837,6 +844,7 @@ static void __exit nf_flow_table_module_exit(void)
 {
        nf_flow_table_offload_exit();
        unregister_pernet_subsys(&nf_flow_table_net_ops);
+       kmem_cache_destroy(flow_offload_cachep);
 }
 
 module_init(nf_flow_table_module_init);