memcg: enable accounting for new namesapces and struct nsproxy
authorVasily Averin <vvs@virtuozzo.com>
Thu, 2 Sep 2021 21:55:27 +0000 (14:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Sep 2021 16:58:12 +0000 (09:58 -0700)
Container admin can create new namespaces and force kernel to allocate up
to several pages of memory for the namespaces and its associated
structures.

Net and uts namespaces have enabled accounting for such allocations.  It
makes sense to account for rest ones to restrict the host's memory
consumption from inside the memcg-limited container.

Link: https://lkml.kernel.org/r/5525bcbf-533e-da27-79b7-158686c64e13@virtuozzo.com
Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
Acked-by: Serge Hallyn <serge@hallyn.com>
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Acked-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Andrei Vagin <avagin@gmail.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dmitry Safonov <0x7f454c46@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Jeff Layton <jlayton@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Jiri Slaby <jirislaby@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Roman Gushchin <guro@fb.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vladimir Davydov <vdavydov.dev@gmail.com>
Cc: Yutian Yang <nglaive@gmail.com>
Cc: Zefan Li <lizefan.x@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/namespace.c
ipc/namespace.c
kernel/cgroup/namespace.c
kernel/nsproxy.c
kernel/pid_namespace.c
kernel/time/namespace.c
kernel/user_namespace.c

index e51b63a..94a9817 100644 (file)
@@ -3307,7 +3307,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool a
        if (!ucounts)
                return ERR_PTR(-ENOSPC);
 
        if (!ucounts)
                return ERR_PTR(-ENOSPC);
 
-       new_ns = kzalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
+       new_ns = kzalloc(sizeof(struct mnt_namespace), GFP_KERNEL_ACCOUNT);
        if (!new_ns) {
                dec_mnt_namespaces(ucounts);
                return ERR_PTR(-ENOMEM);
        if (!new_ns) {
                dec_mnt_namespaces(ucounts);
                return ERR_PTR(-ENOMEM);
index 7bd0766..ae83f0f 100644 (file)
@@ -42,7 +42,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
                goto fail;
 
        err = -ENOMEM;
                goto fail;
 
        err = -ENOMEM;
-       ns = kzalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
+       ns = kzalloc(sizeof(struct ipc_namespace), GFP_KERNEL_ACCOUNT);
        if (ns == NULL)
                goto fail_dec;
 
        if (ns == NULL)
                goto fail_dec;
 
index f5e8828..0d5c298 100644 (file)
@@ -24,7 +24,7 @@ static struct cgroup_namespace *alloc_cgroup_ns(void)
        struct cgroup_namespace *new_ns;
        int ret;
 
        struct cgroup_namespace *new_ns;
        int ret;
 
-       new_ns = kzalloc(sizeof(struct cgroup_namespace), GFP_KERNEL);
+       new_ns = kzalloc(sizeof(struct cgroup_namespace), GFP_KERNEL_ACCOUNT);
        if (!new_ns)
                return ERR_PTR(-ENOMEM);
        ret = ns_alloc_inum(&new_ns->ns);
        if (!new_ns)
                return ERR_PTR(-ENOMEM);
        ret = ns_alloc_inum(&new_ns->ns);
index abc01fc..eec72ca 100644 (file)
@@ -568,6 +568,6 @@ out:
 
 int __init nsproxy_cache_init(void)
 {
 
 int __init nsproxy_cache_init(void)
 {
-       nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
+       nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC|SLAB_ACCOUNT);
        return 0;
 }
        return 0;
 }
index cb5a25a..a46a372 100644 (file)
@@ -450,7 +450,7 @@ const struct proc_ns_operations pidns_for_children_operations = {
 
 static __init int pid_namespaces_init(void)
 {
 
 static __init int pid_namespaces_init(void)
 {
-       pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);
+       pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC | SLAB_ACCOUNT);
 
 #ifdef CONFIG_CHECKPOINT_RESTORE
        register_sysctl_paths(kern_path, pid_ns_ctl_table);
 
 #ifdef CONFIG_CHECKPOINT_RESTORE
        register_sysctl_paths(kern_path, pid_ns_ctl_table);
index 12eab0d..aec8328 100644 (file)
@@ -88,13 +88,13 @@ static struct time_namespace *clone_time_ns(struct user_namespace *user_ns,
                goto fail;
 
        err = -ENOMEM;
                goto fail;
 
        err = -ENOMEM;
-       ns = kmalloc(sizeof(*ns), GFP_KERNEL);
+       ns = kmalloc(sizeof(*ns), GFP_KERNEL_ACCOUNT);
        if (!ns)
                goto fail_dec;
 
        refcount_set(&ns->ns.count, 1);
 
        if (!ns)
                goto fail_dec;
 
        refcount_set(&ns->ns.count, 1);
 
-       ns->vvar_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+       ns->vvar_page = alloc_page(GFP_KERNEL_ACCOUNT | __GFP_ZERO);
        if (!ns->vvar_page)
                goto fail_free;
 
        if (!ns->vvar_page)
                goto fail_free;
 
index ef82d40..6b2e3ca 100644 (file)
@@ -1385,7 +1385,7 @@ const struct proc_ns_operations userns_operations = {
 
 static __init int user_namespaces_init(void)
 {
 
 static __init int user_namespaces_init(void)
 {
-       user_ns_cachep = KMEM_CACHE(user_namespace, SLAB_PANIC);
+       user_ns_cachep = KMEM_CACHE(user_namespace, SLAB_PANIC | SLAB_ACCOUNT);
        return 0;
 }
 subsys_initcall(user_namespaces_init);
        return 0;
 }
 subsys_initcall(user_namespaces_init);