From 728dba3a39c66b3d8ac889ddbe38b5b1c264aec3 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 3 Feb 2014 19:13:49 -0800 Subject: namespaces: Use task_lock and not rcu to protect nsproxy The synchronous syncrhonize_rcu in switch_task_namespaces makes setns a sufficiently expensive system call that people have complained. Upon inspect nsproxy no longer needs rcu protection for remote reads. remote reads are rare. So optimize for same process reads and write by switching using rask_lock instead. This yields a simpler to understand lock, and a faster setns system call. In particular this fixes a performance regression observed by Rafael David Tinoco . This is effectively a revert of Pavel Emelyanov's commit cf7b708c8d1d7a27736771bcf4c457b332b0f818 Make access to task's nsproxy lighter from 2007. The race this originialy fixed no longer exists as do_notify_parent uses task_active_pid_ns(parent) instead of parent->nsproxy. Signed-off-by: "Eric W. Biederman" --- fs/proc/proc_net.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/proc/proc_net.c') diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 4677bb7dc7c..a63af3e0a61 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -113,9 +113,11 @@ static struct net *get_proc_task_net(struct inode *dir) rcu_read_lock(); task = pid_task(proc_pid(dir), PIDTYPE_PID); if (task != NULL) { - ns = task_nsproxy(task); + task_lock(task); + ns = task->nsproxy; if (ns != NULL) net = get_net(ns->net_ns); + task_unlock(task); } rcu_read_unlock(); -- cgit v1.2.3-70-g09d2 From e81324407269b7708a0678a5c40710d2a75e9bf0 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 31 Jul 2014 03:22:30 -0700 Subject: proc: Point /proc/net at /proc/thread-self/net instead of /proc/self/net In oddball cases where the thread has a different network namespace than the primary thread group leader or more likely in cases where the thread remains and the thread group leader has exited this ensures that /proc/net continues to work. This should not cause any problems but if it does this patch can just be reverted. Signed-off-by: "Eric W. Biederman" --- fs/proc/proc_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/proc/proc_net.c') diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index a63af3e0a61..39481028ec0 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -226,7 +226,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = { int __init proc_net_init(void) { - proc_symlink("net", NULL, "self/net"); + proc_symlink("net", NULL, "thread-self/net"); return register_pernet_subsys(&proc_net_ns_ops); } -- cgit v1.2.3-70-g09d2 From 155134fef2b6c7426c3f25ffe84fb3043167c860 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 10 Aug 2014 21:24:59 -0700 Subject: Revert "proc: Point /proc/{mounts,net} at /proc/thread-self/{mounts,net} instead of /proc/self/{mounts,net}" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commits 344470cac42e and e81324407269. It turns out that the exact path in the symlink matters, if for somewhat unfortunate reasons: some apparmor configurations don't allow dhclient access to the per-thread /proc files. As reported by Jörg Otte: audit: type=1400 audit(1407684227.003:28): apparmor="DENIED" operation="open" profile="/sbin/dhclient" name="/proc/1540/task/1540/net/dev" pid=1540 comm="dhclient" requested_mask="r" denied_mask="r" fsuid=0 ouid=0 so we had better revert this for now. We might be able to work around this in practice by only using the per-thread symlinks if the thread isn't the thread group leader, and if the namespaces differ between threads (which basically never happens). We'll see. In the meantime, the revert was made to be intentionally easy. Reported-by: Jörg Otte Acked-by: Eric W. Biederman Signed-off-by: Linus Torvalds --- fs/proc/proc_net.c | 2 +- fs/proc/root.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/proc/proc_net.c') diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 39481028ec0..a63af3e0a61 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -226,7 +226,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = { int __init proc_net_init(void) { - proc_symlink("net", NULL, "thread-self/net"); + proc_symlink("net", NULL, "self/net"); return register_pernet_subsys(&proc_net_ns_ops); } diff --git a/fs/proc/root.c b/fs/proc/root.c index 6296c762696..094e44d4a6b 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -173,7 +173,7 @@ void __init proc_root_init(void) proc_self_init(); proc_thread_self_init(); - proc_symlink("mounts", NULL, "thread-self/mounts"); + proc_symlink("mounts", NULL, "self/mounts"); proc_net_init(); -- cgit v1.2.3-70-g09d2