xfrm: use a dedicated slab cache for struct xfrm_state
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> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
		
							parent
							
								
									154a8c46ba
								
							
						
					
					
						commit
						565f0fa902
					
				| @ -42,6 +42,7 @@ static void xfrm_state_gc_task(struct work_struct *work); | ||||
| 
 | ||||
| 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; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user