diff options
author | KalimochoAz <calimochoazucarado@gmail.com> | 2012-10-14 10:57:12 +0200 |
---|---|---|
committer | KalimochoAz <calimochoazucarado@gmail.com> | 2012-10-14 10:57:12 +0200 |
commit | 50e2778ee890c3e0b7f2e9c876d85aa962abc997 (patch) | |
tree | 5dce0669613802469470633ddb7d407f8f8f7986 /kernel/sched.c | |
parent | 6a9dff5ea86ccd4a1dd503a36ce9856c4c092360 (diff) | |
parent | b9a7985a8d9ca00d8ce977756fde1306c9ab1e41 (diff) | |
download | kernel_samsung_crespo-50e2778ee890c3e0b7f2e9c876d85aa962abc997.zip kernel_samsung_crespo-50e2778ee890c3e0b7f2e9c876d85aa962abc997.tar.gz kernel_samsung_crespo-50e2778ee890c3e0b7f2e9c876d85aa962abc997.tar.bz2 |
Merge commit 'b9a7985' into HEAD
Conflicts:
kernel/time/timekeeping.c
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 32 |
1 files changed, 18 insertions, 14 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index e19782f..d759d33 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -606,22 +606,19 @@ static inline int cpu_of(struct rq *rq) /* * Return the group to which this tasks belongs. * - * We use task_subsys_state_check() and extend the RCU verification with - * pi->lock and rq->lock because cpu_cgroup_attach() holds those locks for each - * task it moves into the cgroup. Therefore by holding either of those locks, - * we pin the task to the current cgroup. + * We cannot use task_subsys_state() and friends because the cgroup + * subsystem changes that value before the cgroup_subsys::attach() method + * is called, therefore we cannot pin it and might observe the wrong value. + * + * The same is true for autogroup's p->signal->autogroup->tg, the autogroup + * core changes this before calling sched_move_task(). + * + * Instead we use a 'copy' which is updated from sched_move_task() while + * holding both task_struct::pi_lock and rq::lock. */ static inline struct task_group *task_group(struct task_struct *p) { - struct task_group *tg; - struct cgroup_subsys_state *css; - - css = task_subsys_state_check(p, cpu_cgroup_subsys_id, - lockdep_is_held(&p->pi_lock) || - lockdep_is_held(&task_rq(p)->lock)); - tg = container_of(css, struct task_group, css); - - return autogroup_task_group(p, tg); + return p->sched_task_group; } /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ @@ -2207,7 +2204,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) * a task's CPU. ->pi_lock for waking tasks, rq->lock for runnable tasks. * * sched_move_task() holds both and thus holding either pins the cgroup, - * see set_task_rq(). + * see task_group(). * * Furthermore, all task_rq users should acquire both locks, see * task_rq_lock(). @@ -8557,6 +8554,7 @@ void sched_destroy_group(struct task_group *tg) */ void sched_move_task(struct task_struct *tsk) { + struct task_group *tg; int on_rq, running; unsigned long flags; struct rq *rq; @@ -8571,6 +8569,12 @@ void sched_move_task(struct task_struct *tsk) if (unlikely(running)) tsk->sched_class->put_prev_task(rq, tsk); + tg = container_of(task_subsys_state_check(tsk, cpu_cgroup_subsys_id, + lockdep_is_held(&tsk->sighand->siglock)), + struct task_group, css); + tg = autogroup_task_group(tsk, tg); + tsk->sched_task_group = tg; + #ifdef CONFIG_FAIR_GROUP_SCHED if (tsk->sched_class->task_move_group) tsk->sched_class->task_move_group(tsk, on_rq); |