summaryrefslogtreecommitdiff
path: root/kernel/pid_namespace.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-03 13:28:06 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-10-24 23:43:29 -0400
commit1adfcb03e31ba0d6be5fddf773da4357d0792cbb (patch)
treec5c89b58403938c263e81c115fc864ad9aabc782 /kernel/pid_namespace.c
parent1dcddd4abd2c6df7f28928ad5cafa4a1cd20030b (diff)
downloadlwn-1adfcb03e31ba0d6be5fddf773da4357d0792cbb.tar.gz
lwn-1adfcb03e31ba0d6be5fddf773da4357d0792cbb.zip
pid_namespace: make freeing struct pid_namespace rcu-delayed
makes procfs ->premission() instances safety in RCU mode independent from vfsmount_lock. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel/pid_namespace.c')
-rw-r--r--kernel/pid_namespace.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 42086551a24a..06c62de9c711 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -132,6 +132,12 @@ out:
return ERR_PTR(err);
}
+static void delayed_free_pidns(struct rcu_head *p)
+{
+ kmem_cache_free(pid_ns_cachep,
+ container_of(p, struct pid_namespace, rcu));
+}
+
static void destroy_pid_namespace(struct pid_namespace *ns)
{
int i;
@@ -140,7 +146,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns)
for (i = 0; i < PIDMAP_ENTRIES; i++)
kfree(ns->pidmap[i].page);
put_user_ns(ns->user_ns);
- kmem_cache_free(pid_ns_cachep, ns);
+ call_rcu(&ns->rcu, delayed_free_pidns);
}
struct pid_namespace *copy_pid_ns(unsigned long flags,