Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1278921

[PATCH 1/3] cgroup: pids: fix race between cgroup_post_fork() and cgroup_migrate()

From Oleg Nesterov <oleg@redhat.com>
Newsgroups linux.kernel
Subject [PATCH 1/3] cgroup: pids: fix race between cgroup_post_fork() and cgroup_migrate()
Date 2015-11-27 20:00 +0100
Message-ID <qzwpr-6zS-3@gated-at.bofh.it> (permalink)
References <qzwpr-6zS-1@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


If the new child migrates to another cgroup before cgroup_post_fork() calls
subsys->fork(), then both pids_can_attach() and pids_fork() will do the same
pids_uncharge(old_pids) + pids_charge(pids) sequence twice.

Change copy_process() to call threadgroup_change_begin/threadgroup_change_end
unconditionally. percpu_down_read() is cheap and this allows other cleanups,
see the next changes.

Also, this way we can unify cgroup_threadgroup_rwsem and dup_mmap_sem.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 kernel/cgroup_pids.c |   21 ++-------------------
 kernel/fork.c        |    9 +++------
 2 files changed, 5 insertions(+), 25 deletions(-)

diff --git a/kernel/cgroup_pids.c b/kernel/cgroup_pids.c
index cdd8df4..15ef2e4 100644
--- a/kernel/cgroup_pids.c
+++ b/kernel/cgroup_pids.c
@@ -243,27 +243,10 @@ static void pids_cancel_fork(struct task_struct *task, void *priv)
 
 static void pids_fork(struct task_struct *task, void *priv)
 {
-	struct cgroup_subsys_state *css;
-	struct cgroup_subsys_state *old_css = priv;
-	struct pids_cgroup *pids;
-	struct pids_cgroup *old_pids = css_pids(old_css);
-
-	css = task_get_css(task, pids_cgrp_id);
-	pids = css_pids(css);
-
-	/*
-	 * If the association has changed, we have to revert and reapply the
-	 * charge/uncharge on the wrong hierarchy to the current one. Since
-	 * the association can only change due to an organisation event, its
-	 * okay for us to ignore the limit in this case.
-	 */
-	if (pids != old_pids) {
-		pids_uncharge(old_pids, 1);
-		pids_charge(pids, 1);
-	}
+	struct cgroup_subsys_state *css = priv;
 
+	WARN_ON(task_css_check(task, pids_cgrp_id, true) != css);
 	css_put(css);
-	css_put(old_css);
 }
 
 static void pids_free(struct task_struct *task)
diff --git a/kernel/fork.c b/kernel/fork.c
index f97f2c4..fce002e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1368,8 +1368,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	p->real_start_time = ktime_get_boot_ns();
 	p->io_context = NULL;
 	p->audit_context = NULL;
-	if (clone_flags & CLONE_THREAD)
-		threadgroup_change_begin(current);
+	threadgroup_change_begin(current);
 	cgroup_fork(p);
 #ifdef CONFIG_NUMA
 	p->mempolicy = mpol_dup(p->mempolicy);
@@ -1610,8 +1609,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
 	proc_fork_connector(p);
 	cgroup_post_fork(p, cgrp_ss_priv);
-	if (clone_flags & CLONE_THREAD)
-		threadgroup_change_end(current);
+	threadgroup_change_end(current);
 	perf_event_fork(p);
 
 	trace_task_newtask(p, clone_flags);
@@ -1652,8 +1650,7 @@ bad_fork_cleanup_policy:
 	mpol_put(p->mempolicy);
 bad_fork_cleanup_threadgroup_lock:
 #endif
-	if (clone_flags & CLONE_THREAD)
-		threadgroup_change_end(current);
+	threadgroup_change_end(current);
 	delayacct_tsk_free(p);
 bad_fork_cleanup_count:
 	atomic_dec(&p->cred->user->processes);
-- 
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH 0/3] cgroup: fix race between cgroup_post_fork() and  cgroup_migrate() Oleg Nesterov <oleg@redhat.com> - 2015-11-27 20:00 +0100
  [PATCH 1/3] cgroup: pids: fix race between cgroup_post_fork() and  cgroup_migrate() Oleg Nesterov <oleg@redhat.com> - 2015-11-27 20:00 +0100
  [PATCH 2/3] cgroup: pids: kill pids_fork(), simplify  pids_can_fork() and pids_cancel_fork() Oleg Nesterov <oleg@redhat.com> - 2015-11-27 20:00 +0100
  [PATCH 3/3] cgroup: kill cgrp_ss_priv[CGROUP_CANFORK_COUNT] and  friends Oleg Nesterov <oleg@redhat.com> - 2015-11-27 20:00 +0100
  Re: [PATCH 0/3] cgroup: fix race between cgroup_post_fork() and  cgroup_migrate() Zefan Li <lizefan@huawei.com> - 2015-11-28 04:20 +0100
    Re: [PATCH 0/3] cgroup: fix race between cgroup_post_fork() and  cgroup_migrate() Oleg Nesterov <oleg@redhat.com> - 2015-11-30 16:20 +0100
  Re: [PATCH 0/3] cgroup: fix race between cgroup_post_fork() and  cgroup_migrate() Tejun Heo <tj@kernel.org> - 2015-11-30 16:00 +0100

csiph-web