From: Oleg Nesterov <oleg@redhat.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Pavel Emelyanov <xemul@openvz.org>,
Linux Containers <containers@lists.osdl.org>,
linux-kernel@vger.kernel.org, Louis Rilling <louis.rillin>
Subject: Re: [PATCH] procfs: Do not release pid_ns->proc_mnt too early
Date: Fri, 18 Jun 2010 23:23:55 +0200 [thread overview]
Message-ID: <20100618212355.GA29478@redhat.com> (raw)
In-Reply-To: <20100618175541.GA13680@redhat.com>
On 06/18, Oleg Nesterov wrote:
>
> work->func(ns) is
> called when ns is already fixed.
^^^^^
(I meant freed)
We can move kmem_cache_free(ns) into work->func(), or we can optimize
the usage of schedule_work(), something like the patch below.
Once again, it is completely untested, I do not pretend I understand
this code today, and I am sure the patch is wrong. I only try to discuss
the idea to break the circular reference. In any case, I am not proud
of this patch ;)
Or we should do the more sophisticated change suggested by Pavel. But
I'd like to avoid the changes in do_wait/release_task, this doesn't
look right to me.
Oleg.
include/linux/pid_namespace.h | 1 +
kernel/pid_namespace.c | 35 ++++++++++++++++++++++++++++++++++-
fs/proc/base.c | 4 ----
fs/proc/root.c | 10 ++++++----
4 files changed, 41 insertions(+), 9 deletions(-)
--- 34-rc1/include/linux/pid_namespace.h~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/include/linux/pid_namespace.h 2010-06-18 22:37:45.000000000 +0200
@@ -26,6 +26,7 @@ struct pid_namespace {
struct pid_namespace *parent;
#ifdef CONFIG_PROC_FS
struct vfsmount *proc_mnt;
+ struct list_head dead_node;
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
struct bsd_acct_struct *bacct;
--- 34-rc1/kernel/pid_namespace.c~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/kernel/pid_namespace.c 2010-06-18 22:52:41.000000000 +0200
@@ -10,6 +10,7 @@
#include <linux/pid.h>
#include <linux/pid_namespace.h>
+#include <linux/proc_fs.h>
#include <linux/syscalls.h>
#include <linux/err.h>
#include <linux/acct.h>
@@ -105,15 +106,47 @@ out:
return ERR_PTR(-ENOMEM);
}
-static void destroy_pid_namespace(struct pid_namespace *ns)
+static LIST_HEAD(dead_list);
+static DEFINE_SPINLOCK(dead_lock);
+
+static void do_destroy_pid_namespace(struct pid_namespace *ns)
{
int i;
+ pid_ns_release_proc(ns);
+
for (i = 0; i < PIDMAP_ENTRIES; i++)
kfree(ns->pidmap[i].page);
kmem_cache_free(pid_ns_cachep, ns);
}
+static void dead_work_func(struct work_struct *unused)
+{
+ LIST_HEAD(list);
+ unsigned long flags;
+ struct pid_namespace *ns, *tmp;
+
+ spin_lock_irqsave(&dead_lock, flags);
+ list_splice_init(&dead_list, &list);
+ spin_unlock_irqrestore(&dead_lock, flags);
+
+ list_for_each_entry_safe(ns, tmp, &list, dead_node)
+ do_destroy_pid_namespace(ns);
+}
+
+static DECLARE_WORK(dead_work, dead_work_func);
+
+static void destroy_pid_namespace(struct pid_namespace *ns)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dead_lock, flags);
+ list_add(&ns->dead_node, &dead_list);
+ spin_unlock_irqrestore(&dead_lock, flags);
+
+ schedule_work(&dead_work);
+}
+
struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
{
if (!(flags & CLONE_NEWPID))
--- 34-rc1/fs/proc/base.c~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/fs/proc/base.c 2010-06-18 17:49:45.000000000 +0200
@@ -2720,10 +2720,6 @@ void proc_flush_task(struct task_struct
proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
tgid->numbers[i].nr);
}
-
- upid = &pid->numbers[pid->level];
- if (upid->nr == 1)
- pid_ns_release_proc(upid->ns);
}
static struct dentry *proc_pid_instantiate(struct inode *dir,
--- 34-rc1/fs/proc/root.c~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/fs/proc/root.c 2010-06-18 22:54:03.000000000 +0200
@@ -31,7 +31,7 @@ static int proc_set_super(struct super_b
struct pid_namespace *ns;
ns = (struct pid_namespace *)data;
- sb->s_fs_info = get_pid_ns(ns);
+ sb->s_fs_info = ns;
return set_anon_super(sb, NULL);
}
@@ -74,7 +74,7 @@ static int proc_get_sb(struct file_syste
ei = PROC_I(sb->s_root->d_inode);
if (!ei->pid) {
rcu_read_lock();
- ei->pid = get_pid(find_pid_ns(1, ns));
+ ei->pid = find_pid_ns(1, ns);
rcu_read_unlock();
}
@@ -92,7 +92,6 @@ static void proc_kill_sb(struct super_bl
ns = (struct pid_namespace *)sb->s_fs_info;
kill_anon_super(sb);
- put_pid_ns(ns);
}
static struct file_system_type proc_fs_type = {
@@ -218,5 +217,8 @@ int pid_ns_prepare_proc(struct pid_names
void pid_ns_release_proc(struct pid_namespace *ns)
{
- mntput(ns->proc_mnt);
+ if (ns->proc_mnt) {
+ PROC_I(ns->proc_mnt->mnt_sb->s_root->d_inode)->pid = NULL;
+ mntput(ns->proc_mnt);
+ }
}
WARNING: multiple messages have this Message-ID (diff)
From: Oleg Nesterov <oleg@redhat.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Pavel Emelyanov <xemul@openvz.org>,
Linux Containers <containers@lists.osdl.org>,
linux-kernel@vger.kernel.org,
Louis Rilling <louis.rilling@kerlabs.com>,
"Eric W. Biederman" <ebiederm@xmission.com>
Subject: Re: [PATCH] procfs: Do not release pid_ns->proc_mnt too early
Date: Fri, 18 Jun 2010 23:23:55 +0200 [thread overview]
Message-ID: <20100618212355.GA29478@redhat.com> (raw)
In-Reply-To: <20100618175541.GA13680@redhat.com>
On 06/18, Oleg Nesterov wrote:
>
> work->func(ns) is
> called when ns is already fixed.
^^^^^
(I meant freed)
We can move kmem_cache_free(ns) into work->func(), or we can optimize
the usage of schedule_work(), something like the patch below.
Once again, it is completely untested, I do not pretend I understand
this code today, and I am sure the patch is wrong. I only try to discuss
the idea to break the circular reference. In any case, I am not proud
of this patch ;)
Or we should do the more sophisticated change suggested by Pavel. But
I'd like to avoid the changes in do_wait/release_task, this doesn't
look right to me.
Oleg.
include/linux/pid_namespace.h | 1 +
kernel/pid_namespace.c | 35 ++++++++++++++++++++++++++++++++++-
fs/proc/base.c | 4 ----
fs/proc/root.c | 10 ++++++----
4 files changed, 41 insertions(+), 9 deletions(-)
--- 34-rc1/include/linux/pid_namespace.h~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/include/linux/pid_namespace.h 2010-06-18 22:37:45.000000000 +0200
@@ -26,6 +26,7 @@ struct pid_namespace {
struct pid_namespace *parent;
#ifdef CONFIG_PROC_FS
struct vfsmount *proc_mnt;
+ struct list_head dead_node;
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
struct bsd_acct_struct *bacct;
--- 34-rc1/kernel/pid_namespace.c~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/kernel/pid_namespace.c 2010-06-18 22:52:41.000000000 +0200
@@ -10,6 +10,7 @@
#include <linux/pid.h>
#include <linux/pid_namespace.h>
+#include <linux/proc_fs.h>
#include <linux/syscalls.h>
#include <linux/err.h>
#include <linux/acct.h>
@@ -105,15 +106,47 @@ out:
return ERR_PTR(-ENOMEM);
}
-static void destroy_pid_namespace(struct pid_namespace *ns)
+static LIST_HEAD(dead_list);
+static DEFINE_SPINLOCK(dead_lock);
+
+static void do_destroy_pid_namespace(struct pid_namespace *ns)
{
int i;
+ pid_ns_release_proc(ns);
+
for (i = 0; i < PIDMAP_ENTRIES; i++)
kfree(ns->pidmap[i].page);
kmem_cache_free(pid_ns_cachep, ns);
}
+static void dead_work_func(struct work_struct *unused)
+{
+ LIST_HEAD(list);
+ unsigned long flags;
+ struct pid_namespace *ns, *tmp;
+
+ spin_lock_irqsave(&dead_lock, flags);
+ list_splice_init(&dead_list, &list);
+ spin_unlock_irqrestore(&dead_lock, flags);
+
+ list_for_each_entry_safe(ns, tmp, &list, dead_node)
+ do_destroy_pid_namespace(ns);
+}
+
+static DECLARE_WORK(dead_work, dead_work_func);
+
+static void destroy_pid_namespace(struct pid_namespace *ns)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dead_lock, flags);
+ list_add(&ns->dead_node, &dead_list);
+ spin_unlock_irqrestore(&dead_lock, flags);
+
+ schedule_work(&dead_work);
+}
+
struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
{
if (!(flags & CLONE_NEWPID))
--- 34-rc1/fs/proc/base.c~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/fs/proc/base.c 2010-06-18 17:49:45.000000000 +0200
@@ -2720,10 +2720,6 @@ void proc_flush_task(struct task_struct
proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
tgid->numbers[i].nr);
}
-
- upid = &pid->numbers[pid->level];
- if (upid->nr == 1)
- pid_ns_release_proc(upid->ns);
}
static struct dentry *proc_pid_instantiate(struct inode *dir,
--- 34-rc1/fs/proc/root.c~PID_NS 2010-06-18 17:48:56.000000000 +0200
+++ 34-rc1/fs/proc/root.c 2010-06-18 22:54:03.000000000 +0200
@@ -31,7 +31,7 @@ static int proc_set_super(struct super_b
struct pid_namespace *ns;
ns = (struct pid_namespace *)data;
- sb->s_fs_info = get_pid_ns(ns);
+ sb->s_fs_info = ns;
return set_anon_super(sb, NULL);
}
@@ -74,7 +74,7 @@ static int proc_get_sb(struct file_syste
ei = PROC_I(sb->s_root->d_inode);
if (!ei->pid) {
rcu_read_lock();
- ei->pid = get_pid(find_pid_ns(1, ns));
+ ei->pid = find_pid_ns(1, ns);
rcu_read_unlock();
}
@@ -92,7 +92,6 @@ static void proc_kill_sb(struct super_bl
ns = (struct pid_namespace *)sb->s_fs_info;
kill_anon_super(sb);
- put_pid_ns(ns);
}
static struct file_system_type proc_fs_type = {
@@ -218,5 +217,8 @@ int pid_ns_prepare_proc(struct pid_names
void pid_ns_release_proc(struct pid_namespace *ns)
{
- mntput(ns->proc_mnt);
+ if (ns->proc_mnt) {
+ PROC_I(ns->proc_mnt->mnt_sb->s_root->d_inode)->pid = NULL;
+ mntput(ns->proc_mnt);
+ }
}
next prev parent reply other threads:[~2010-06-18 21:23 UTC|newest]
Thread overview: 98+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-16 16:34 [PATCH] procfs: Do not release pid_ns->proc_mnt too early Louis Rilling
[not found] ` <1276706068-18567-1-git-send-email-louis.rilling-aw0BnHfMbSpBDgjK7y7TUQ@public.gmane.org>
2010-06-17 9:53 ` Pavel Emelyanov
2010-06-17 9:53 ` Pavel Emelyanov
2010-06-17 13:41 ` Eric W. Biederman
2010-06-17 14:20 ` Louis Rilling
2010-06-17 21:36 ` Oleg Nesterov
2010-06-18 8:27 ` Louis Rilling
2010-06-18 16:27 ` Oleg Nesterov
2010-06-21 11:11 ` Louis Rilling
2010-06-21 12:58 ` Eric W. Biederman
2010-06-21 14:15 ` Louis Rilling
2010-06-21 14:26 ` Eric W. Biederman
[not found] ` <20100618082738.GE16877-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2010-06-18 16:27 ` Oleg Nesterov
2010-06-17 21:20 ` Oleg Nesterov
2010-06-18 8:20 ` Louis Rilling
2010-06-18 11:15 ` Oleg Nesterov
2010-06-18 16:08 ` Oleg Nesterov
2010-06-18 16:08 ` Oleg Nesterov
2010-06-18 17:33 ` Louis Rilling
2010-06-18 17:55 ` Oleg Nesterov
2010-06-18 17:55 ` Oleg Nesterov
2010-06-18 21:23 ` Oleg Nesterov [this message]
2010-06-18 21:23 ` Oleg Nesterov
2010-06-19 19:08 ` [PATCH 0/4] pid_ns_prepare_proc/unshare cleanups Oleg Nesterov
2010-06-19 19:09 ` [PATCH 1/4] procfs: proc_get_sb: consolidate/cleanup root_inode->pid logic Oleg Nesterov
2010-06-19 19:10 ` [PATCH 2/4] procfs: kill the global proc_mnt variable Oleg Nesterov
2010-06-19 19:10 ` [PATCH 3/4] procfs: move pid_ns_prepare_proc() from copy_process() to create_pid_namespace() Oleg Nesterov
2010-06-19 19:11 ` [PATCH RESEND 4/4] sys_unshare: simplify the not-really-implemented CLONE_THREAD/SIGHAND/VM code Oleg Nesterov
2010-06-20 8:42 ` [PATCH 0/6] Unshare support for the pid namespace Eric W. Biederman
2010-06-20 8:44 ` [PATCH 1/6] pid: Remove the child_reaper special case in init/main.c Eric W. Biederman
[not found] ` <m1ljaaqejm.fsf_-_-+imSwln9KH6u2/kzUuoCbdi2O/JbrIOy@public.gmane.org>
2010-06-20 18:29 ` Oleg Nesterov
2010-06-20 18:29 ` Oleg Nesterov
2010-06-20 20:27 ` Oleg Nesterov
2010-06-20 8:45 ` [PATCH 2/6] pidns: Call pid_ns_prepare_proc from create_pid_namespace Eric W. Biederman
[not found] ` <m1hbkyqeib.fsf_-_-+imSwln9KH6u2/kzUuoCbdi2O/JbrIOy@public.gmane.org>
2010-06-20 18:19 ` Oleg Nesterov
2010-06-20 18:19 ` Oleg Nesterov
2010-06-20 8:45 ` [PATCH 3/6] procfs: kill the global proc_mnt variable Eric W. Biederman
2010-06-20 8:47 ` [PATCH 4/6] pidns: Don't allow new pids after the namespace is dead Eric W. Biederman
2010-06-20 18:44 ` Oleg Nesterov
2010-06-20 8:48 ` [PATCH 5/6] pidns: Use task_active_pid_ns where appropriate Eric W. Biederman
2010-06-20 8:49 ` [PATCH 6/6] pidns: Support unsharing the pid namespace Eric W. Biederman
2010-06-20 20:14 ` Oleg Nesterov
2010-06-20 20:42 ` Oleg Nesterov
2010-06-21 1:53 ` Eric W. Biederman
2010-06-20 18:03 ` [PATCH 0/6] Unshare support for " Oleg Nesterov
2010-06-20 18:05 ` [PATCH 0/2] pid_ns_release_proc() fixes Oleg Nesterov
2010-06-20 18:06 ` [PATCH 1/2] pid_ns: move destroy_pid_namespace() into workqueue context Oleg Nesterov
2010-06-20 18:06 ` [PATCH 2/2] pid_ns: refactor the buggy pid_ns_release_proc() logic Oleg Nesterov
2010-06-20 21:00 ` [PATCH 0/6] Unshare support for the pid namespace Eric W. Biederman
2010-06-20 21:48 ` Oleg Nesterov
[not found] ` <m14ogxctd6.fsf-+imSwln9KH6u2/kzUuoCbdi2O/JbrIOy@public.gmane.org>
2010-06-20 21:56 ` Oleg Nesterov
2010-06-20 21:56 ` Oleg Nesterov
2011-01-26 15:57 ` Daniel Lezcano
2010-06-23 20:36 ` [PATCH 0/1] pid_ns: move pid_ns_release_proc() from proc_flush_task() to zap_pid_ns_processes() Oleg Nesterov
[not found] ` <20100623203652.GA25298-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-06-23 20:37 ` [PATCH 1/1] " Oleg Nesterov
2010-06-23 20:37 ` Oleg Nesterov
2010-06-24 6:36 ` Sukadev Bhattiprolu
2010-06-24 12:59 ` Oleg Nesterov
2010-06-24 7:06 ` Eric W. Biederman
2010-06-24 13:01 ` Oleg Nesterov
2010-06-24 8:37 ` [PATCH] pid_ns: Fix proc_flush_task() accessing freed proc_mnt Louis Rilling
2010-06-24 17:08 ` [RESEND PATCH] " Louis Rilling
2010-06-24 19:18 ` Oleg Nesterov
2010-06-25 10:23 ` Louis Rilling
[not found] ` <20100625102303.GG3773-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2010-06-25 12:21 ` Oleg Nesterov
2010-06-25 12:21 ` Oleg Nesterov
2010-06-25 18:37 ` Sukadev Bhattiprolu
2010-06-25 18:37 ` Sukadev Bhattiprolu
2010-06-25 19:29 ` Oleg Nesterov
2010-06-25 21:26 ` Sukadev Bhattiprolu
2010-06-25 21:27 ` Oleg Nesterov
2010-06-25 22:07 ` Sukadev Bhattiprolu
2010-07-09 4:36 ` [RFC][PATCH 1/2] pidns: Add a flag to indicate a pid namespace is dead Eric W. Biederman
2010-07-09 4:39 ` [RFC][PATCH 2/2] pidns: Remove proc flush races when a pid namespaces are exiting Eric W. Biederman
2010-07-09 12:14 ` Louis Rilling
2010-07-09 13:05 ` Eric W. Biederman
2010-07-09 14:13 ` Louis Rilling
2010-07-09 15:58 ` [PATCH 01/24] pidns: Remove races by stopping the caching of proc_mnt Eric W. Biederman
2010-07-09 22:13 ` Serge E. Hallyn
2010-07-11 14:14 ` Louis Rilling
2010-07-11 14:25 ` Eric W. Biederman
2010-07-12 18:09 ` [PATCH] pidns: Fix wait for zombies to be reaped in zap_pid_ns_processes Eric W. Biederman
2010-07-13 21:42 ` Louis Rilling
[not found] ` <20100713214234.GA21042-Hu8+6S1rdjywhHL9vcZdMVaTQe2KTcn/@public.gmane.org>
2010-07-13 22:34 ` Serge E. Hallyn
2010-07-13 22:34 ` Serge E. Hallyn
2010-07-14 1:47 ` Eric W. Biederman
[not found] ` <m1oceakf5x.fsf-+imSwln9KH6u2/kzUuoCbdi2O/JbrIOy@public.gmane.org>
2010-10-30 7:07 ` Sukadev Bhattiprolu
2010-10-30 7:07 ` Sukadev Bhattiprolu
2010-07-14 20:53 ` Sukadev Bhattiprolu
2010-07-14 21:35 ` Eric W. Biederman
2010-06-21 11:09 ` [PATCH] procfs: Do not release pid_ns->proc_mnt too early Louis Rilling
2010-06-21 11:15 ` Louis Rilling
2010-06-21 14:38 ` Oleg Nesterov
-- strict thread matches above, loose matches on Subject: below --
2010-06-16 15:58 Louis Rilling
2010-06-16 15:58 ` Louis Rilling
2010-06-16 16:04 ` Pavel Emelyanov
2010-06-16 16:15 ` Louis Rilling
2010-06-16 16:16 ` Louis Rilling
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100618212355.GA29478@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=containers@lists.osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=xemul@openvz.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.