Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

user_ns: improve the user_ns on-the-slab packaging

Currently on 64-bit arch the user_namespace is 2096 and when being
kmalloc-ed it resides on a 4k slab wasting 2003 bytes.

If we allocate a separate cache for it and reduce the hash size from 128
to 64 chains the packaging becomes *much* better - the struct is 1072
bytes and the hole between is 98 bytes.

[akpm@linux-foundation.org: s/__initcall/module_init/]
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Acked-by: Serge E. Hallyn <serge@hallyn.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Pavel Emelyanov and committed by
Linus Torvalds
6164281a e020e742

+13 -4
+1 -1
include/linux/user_namespace.h
··· 6 6 #include <linux/sched.h> 7 7 #include <linux/err.h> 8 8 9 - #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 8) 9 + #define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 7) 10 10 #define UIDHASH_SZ (1 << UIDHASH_BITS) 11 11 12 12 struct user_namespace {
+12 -3
kernel/user_namespace.c
··· 12 12 #include <linux/highuid.h> 13 13 #include <linux/cred.h> 14 14 15 + static struct kmem_cache *user_ns_cachep __read_mostly; 16 + 15 17 /* 16 18 * Create a new user namespace, deriving the creator from the user in the 17 19 * passed credentials, and replacing that user with the new root user for the ··· 28 26 struct user_struct *root_user; 29 27 int n; 30 28 31 - ns = kmalloc(sizeof(struct user_namespace), GFP_KERNEL); 29 + ns = kmem_cache_alloc(user_ns_cachep, GFP_KERNEL); 32 30 if (!ns) 33 31 return -ENOMEM; 34 32 ··· 40 38 /* Alloc new root user. */ 41 39 root_user = alloc_uid(ns, 0); 42 40 if (!root_user) { 43 - kfree(ns); 41 + kmem_cache_free(user_ns_cachep, ns); 44 42 return -ENOMEM; 45 43 } 46 44 ··· 73 71 struct user_namespace *ns = 74 72 container_of(work, struct user_namespace, destroyer); 75 73 free_uid(ns->creator); 76 - kfree(ns); 74 + kmem_cache_free(user_ns_cachep, ns); 77 75 } 78 76 79 77 void free_user_ns(struct kref *kref) ··· 128 126 /* No useful relationship so no mapping */ 129 127 return overflowgid; 130 128 } 129 + 130 + static __init int user_namespaces_init(void) 131 + { 132 + user_ns_cachep = KMEM_CACHE(user_namespace, SLAB_PANIC); 133 + return 0; 134 + } 135 + module_init(user_namespaces_init);