All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH ipsec-next] xfrm: use a dedicated slab cache for struct xfrm_state
@ 2018-05-03  8:55 Mathias Krause
  2018-05-04  9:31 ` Steffen Klassert
  0 siblings, 1 reply; 2+ messages in thread
From: Mathias Krause @ 2018-05-03  8:55 UTC (permalink / raw)
  To: Steffen Klassert; +Cc: Mathias Krause, Herbert Xu, David S. Miller, netdev

struct xfrm_state is rather large (768 bytes here) and therefore wastes
quite a lot of memory as it falls into the kmalloc-1024 slab cache,
leaving 256 bytes of unused memory per XFRM state object -- a net waste
of 25%.

Using a dedicated slab cache for struct xfrm_state reduces the level of
internal fragmentation to a minimum.

On my configuration SLUB chooses to create a slab cache covering 4
pages holding 21 objects, resulting in an average memory waste of ~13
bytes per object -- a net waste of only 1.6%.

In my tests this led to memory savings of roughly 2.3MB for 10k XFRM
states.

Signed-off-by: Mathias Krause <minipli@googlemail.com>
---
 net/xfrm/xfrm_state.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f9d2f2233f09..73db0ea8692a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -42,6 +42,7 @@
 
 static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
 static __read_mostly seqcount_t xfrm_state_hash_generation = SEQCNT_ZERO(xfrm_state_hash_generation);
+static struct kmem_cache *xfrm_state_cache __ro_after_init;
 
 static DECLARE_WORK(xfrm_state_gc_work, xfrm_state_gc_task);
 static HLIST_HEAD(xfrm_state_gc_list);
@@ -451,7 +452,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
 	}
 	xfrm_dev_state_free(x);
 	security_xfrm_state_free(x);
-	kfree(x);
+	kmem_cache_free(xfrm_state_cache, x);
 }
 
 static void xfrm_state_gc_task(struct work_struct *work)
@@ -563,7 +564,7 @@ struct xfrm_state *xfrm_state_alloc(struct net *net)
 {
 	struct xfrm_state *x;
 
-	x = kzalloc(sizeof(struct xfrm_state), GFP_ATOMIC);
+	x = kmem_cache_alloc(xfrm_state_cache, GFP_ATOMIC | __GFP_ZERO);
 
 	if (x) {
 		write_pnet(&x->xs_net, net);
@@ -2307,6 +2308,10 @@ int __net_init xfrm_state_init(struct net *net)
 {
 	unsigned int sz;
 
+	if (net_eq(net, &init_net))
+		xfrm_state_cache = KMEM_CACHE(xfrm_state,
+					      SLAB_HWCACHE_ALIGN | SLAB_PANIC);
+
 	INIT_LIST_HEAD(&net->xfrm.state_all);
 
 	sz = sizeof(struct hlist_head) * 8;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH ipsec-next] xfrm: use a dedicated slab cache for struct xfrm_state
  2018-05-03  8:55 [PATCH ipsec-next] xfrm: use a dedicated slab cache for struct xfrm_state Mathias Krause
@ 2018-05-04  9:31 ` Steffen Klassert
  0 siblings, 0 replies; 2+ messages in thread
From: Steffen Klassert @ 2018-05-04  9:31 UTC (permalink / raw)
  To: Mathias Krause; +Cc: Herbert Xu, David S. Miller, netdev

On Thu, May 03, 2018 at 10:55:07AM +0200, Mathias Krause wrote:
> struct xfrm_state is rather large (768 bytes here) and therefore wastes
> quite a lot of memory as it falls into the kmalloc-1024 slab cache,
> leaving 256 bytes of unused memory per XFRM state object -- a net waste
> of 25%.
> 
> Using a dedicated slab cache for struct xfrm_state reduces the level of
> internal fragmentation to a minimum.
> 
> On my configuration SLUB chooses to create a slab cache covering 4
> pages holding 21 objects, resulting in an average memory waste of ~13
> bytes per object -- a net waste of only 1.6%.
> 
> In my tests this led to memory savings of roughly 2.3MB for 10k XFRM
> states.
> 
> Signed-off-by: Mathias Krause <minipli@googlemail.com>

Applied, thanks Mathias!

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-05-04  9:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-03  8:55 [PATCH ipsec-next] xfrm: use a dedicated slab cache for struct xfrm_state Mathias Krause
2018-05-04  9:31 ` Steffen Klassert

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.