From: Daniel J Blueman Date: Tue, 1 Jun 2010 13:06:13 +0000 (+0100) Subject: rcu: apply RCU protection to wake_affine() X-Git-Tag: v2.6.34.8~170 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9ecb99443a55d80019f4f2153de26d2715f6485;p=thirdparty%2Fkernel%2Fstable.git rcu: apply RCU protection to wake_affine() commit f3b577dec1f2ce32d2db6d2ca6badff7002512af upstream. The task_group() function returns a pointer that must be protected by either RCU, the ->alloc_lock, or the cgroup lock (see the rcu_dereference_check() in task_subsys_state(), which is invoked by task_group()). The wake_affine() function currently does none of these, which means that a concurrent update would be within its rights to free the structure returned by task_group(). Because wake_affine() uses this structure only to compute load-balancing heuristics, there is no reason to acquire either of the two locks. Therefore, this commit introduces an RCU read-side critical section that starts before the first call to task_group() and ends after the last use of the "tg" pointer returned from task_group(). Thanks to Li Zefan for pointing out the need to extend the RCU read-side critical section from that proposed by the original patch. Signed-off-by: Daniel J Blueman Signed-off-by: Paul E. McKenney Signed-off-by: Paul Gortmaker --- diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 461d312d54db4..94993ac575c0c 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1272,6 +1272,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync) * effect of the currently running task from the load * of the current CPU: */ + rcu_read_lock(); if (sync) { tg = task_group(current); weight = current->se.load.weight; @@ -1297,6 +1298,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync) balanced = !this_load || 100*(this_load + effective_load(tg, this_cpu, weight, weight)) <= imbalance*(load + effective_load(tg, prev_cpu, 0, weight)); + rcu_read_unlock(); /* * If the currently running task will sleep within