diff options
-rw-r--r-- | kernel/sched/core.c | 12 | ||||
-rw-r--r-- | kernel/sched/sched.h | 6 |
2 files changed, 15 insertions, 3 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index a02b624fee6c..71b836034912 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -333,9 +333,12 @@ static inline struct rq *__task_rq_lock(struct task_struct *p) | |||
333 | for (;;) { | 333 | for (;;) { |
334 | rq = task_rq(p); | 334 | rq = task_rq(p); |
335 | raw_spin_lock(&rq->lock); | 335 | raw_spin_lock(&rq->lock); |
336 | if (likely(rq == task_rq(p))) | 336 | if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) |
337 | return rq; | 337 | return rq; |
338 | raw_spin_unlock(&rq->lock); | 338 | raw_spin_unlock(&rq->lock); |
339 | |||
340 | while (unlikely(task_on_rq_migrating(p))) | ||
341 | cpu_relax(); | ||
339 | } | 342 | } |
340 | } | 343 | } |
341 | 344 | ||
@@ -352,10 +355,13 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) | |||
352 | raw_spin_lock_irqsave(&p->pi_lock, *flags); | 355 | raw_spin_lock_irqsave(&p->pi_lock, *flags); |
353 | rq = task_rq(p); | 356 | rq = task_rq(p); |
354 | raw_spin_lock(&rq->lock); | 357 | raw_spin_lock(&rq->lock); |
355 | if (likely(rq == task_rq(p))) | 358 | if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) |
356 | return rq; | 359 | return rq; |
357 | raw_spin_unlock(&rq->lock); | 360 | raw_spin_unlock(&rq->lock); |
358 | raw_spin_unlock_irqrestore(&p->pi_lock, *flags); | 361 | raw_spin_unlock_irqrestore(&p->pi_lock, *flags); |
362 | |||
363 | while (unlikely(task_on_rq_migrating(p))) | ||
364 | cpu_relax(); | ||
359 | } | 365 | } |
360 | } | 366 | } |
361 | 367 | ||
@@ -1678,7 +1684,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) | |||
1678 | success = 1; /* we're going to change ->state */ | 1684 | success = 1; /* we're going to change ->state */ |
1679 | cpu = task_cpu(p); | 1685 | cpu = task_cpu(p); |
1680 | 1686 | ||
1681 | if (task_on_rq_queued(p) && ttwu_remote(p, wake_flags)) | 1687 | if (p->on_rq && ttwu_remote(p, wake_flags)) |
1682 | goto stat; | 1688 | goto stat; |
1683 | 1689 | ||
1684 | #ifdef CONFIG_SMP | 1690 | #ifdef CONFIG_SMP |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 26566d0c67ac..aa0f73ba3777 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -17,6 +17,7 @@ struct rq; | |||
17 | 17 | ||
18 | /* task_struct::on_rq states: */ | 18 | /* task_struct::on_rq states: */ |
19 | #define TASK_ON_RQ_QUEUED 1 | 19 | #define TASK_ON_RQ_QUEUED 1 |
20 | #define TASK_ON_RQ_MIGRATING 2 | ||
20 | 21 | ||
21 | extern __read_mostly int scheduler_running; | 22 | extern __read_mostly int scheduler_running; |
22 | 23 | ||
@@ -950,6 +951,11 @@ static inline int task_on_rq_queued(struct task_struct *p) | |||
950 | return p->on_rq == TASK_ON_RQ_QUEUED; | 951 | return p->on_rq == TASK_ON_RQ_QUEUED; |
951 | } | 952 | } |
952 | 953 | ||
954 | static inline int task_on_rq_migrating(struct task_struct *p) | ||
955 | { | ||
956 | return p->on_rq == TASK_ON_RQ_MIGRATING; | ||
957 | } | ||
958 | |||
953 | #ifndef prepare_arch_switch | 959 | #ifndef prepare_arch_switch |
954 | # define prepare_arch_switch(next) do { } while (0) | 960 | # define prepare_arch_switch(next) do { } while (0) |
955 | #endif | 961 | #endif |