]> Pileus Git - ~andy/linux/blobdiff - kernel/sched/rt.c
sched/rt: Add missing rmb()
[~andy/linux] / kernel / sched / rt.c
index 01970c8e64df64def4585bf3bd517c3bdb8a9354..a848f526b941a1cbda606bd954b927d7e7a8eb76 100644 (file)
@@ -246,8 +246,10 @@ static inline void rt_set_overload(struct rq *rq)
         * if we should look at the mask. It would be a shame
         * if we looked at the mask, but the mask was not
         * updated yet.
+        *
+        * Matched by the barrier in pull_rt_task().
         */
-       wmb();
+       smp_wmb();
        atomic_inc(&rq->rd->rto_count);
 }
 
@@ -1169,13 +1171,10 @@ static void yield_task_rt(struct rq *rq)
 static int find_lowest_rq(struct task_struct *task);
 
 static int
-select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
+select_task_rq_rt(struct task_struct *p, int cpu, int sd_flag, int flags)
 {
        struct task_struct *curr;
        struct rq *rq;
-       int cpu;
-
-       cpu = task_cpu(p);
 
        if (p->nr_cpus_allowed == 1)
                goto out;
@@ -1213,8 +1212,7 @@ select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
         */
        if (curr && unlikely(rt_task(curr)) &&
            (curr->nr_cpus_allowed < 2 ||
-            curr->prio <= p->prio) &&
-           (p->nr_cpus_allowed > 1)) {
+            curr->prio <= p->prio)) {
                int target = find_lowest_rq(p);
 
                if (target != -1)
@@ -1630,6 +1628,12 @@ static int pull_rt_task(struct rq *this_rq)
        if (likely(!rt_overloaded(this_rq)))
                return 0;
 
+       /*
+        * Match the barrier from rt_set_overloaded; this guarantees that if we
+        * see overloaded we must also see the rto_mask bit.
+        */
+       smp_rmb();
+
        for_each_cpu(cpu, this_rq->rd->rto_mask) {
                if (this_cpu == cpu)
                        continue;