]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Jun 2010 19:17:40 +0000 (12:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Jun 2010 19:17:40 +0000 (12:17 -0700)
* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  sched: silence PROVE_RCU in sched_fork()
  idr: fix RCU lockdep splat in idr_get_next()
  rcu: apply RCU protection to wake_affine()

kernel/sched.c
kernel/sched_fair.c
lib/idr.c

index f8b8996228dd7d8de9ee49a845a193921f1b8a5d..a2d215d132f630ec8ed7dcf03af24b3c8524d966 100644 (file)
@@ -2494,7 +2494,16 @@ void sched_fork(struct task_struct *p, int clone_flags)
        if (p->sched_class->task_fork)
                p->sched_class->task_fork(p);
 
+       /*
+        * The child is not yet in the pid-hash so no cgroup attach races,
+        * and the cgroup is pinned to this child due to cgroup_fork()
+        * is ran before sched_fork().
+        *
+        * Silence PROVE_RCU.
+        */
+       rcu_read_lock();
        set_task_cpu(p, cpu);
+       rcu_read_unlock();
 
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
        if (likely(sched_info_on()))
index eed35eded6029c82d126ea24bbdfa2a5731ad8a9..a878b5332daad5d7db16625f298a4e963edac909 100644 (file)
@@ -1240,6 +1240,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;
@@ -1275,6 +1276,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
                balanced = this_eff_load <= prev_eff_load;
        } else
                balanced = true;
+       rcu_read_unlock();
 
        /*
         * If the currently running task will sleep within
index c1a2069017614e6f95a7c2a892fcca1c9c2a7ff1..7f1a4f0acf50e280f5505779bd90f2dda1b97960 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -602,7 +602,7 @@ void *idr_get_next(struct idr *idp, int *nextidp)
        /* find first ent */
        n = idp->layers * IDR_BITS;
        max = 1 << n;
-       p = rcu_dereference(idp->top);
+       p = rcu_dereference_raw(idp->top);
        if (!p)
                return NULL;
 
@@ -610,7 +610,7 @@ void *idr_get_next(struct idr *idp, int *nextidp)
                while (n > 0 && p) {
                        n -= IDR_BITS;
                        *paa++ = p;
-                       p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]);
+                       p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]);
                }
 
                if (p) {