Commit 134f7fee authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Greg Kroah-Hartman

sched: Fix cross-sched-class wakeup preemption

Commit: 1e5a7405 upstream

Instead of dealing with sched classes inside each check_preempt_curr()
implementation, pull out this logic into the generic wakeup preemption
path.

This fixes a hang in KVM (and others) where we are waiting for the
stop machine thread to run ...
Reported-by: default avatarMarkus Trippelsdorf <markus@trippelsdorf.de>
Tested-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
Tested-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1288891946.2039.31.camel@laptop>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarMike Galbraith <efault@gmx.de>
Acked-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent aa68c032
...@@ -594,11 +594,7 @@ struct rq { ...@@ -594,11 +594,7 @@ struct rq {
static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
static inline static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags);
void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
{
rq->curr->sched_class->check_preempt_curr(rq, p, flags);
}
static inline int cpu_of(struct rq *rq) static inline int cpu_of(struct rq *rq)
{ {
...@@ -2392,6 +2388,24 @@ void task_oncpu_function_call(struct task_struct *p, ...@@ -2392,6 +2388,24 @@ void task_oncpu_function_call(struct task_struct *p,
preempt_enable(); preempt_enable();
} }
static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
{
const struct sched_class *class;
if (p->sched_class == rq->curr->sched_class) {
rq->curr->sched_class->check_preempt_curr(rq, p, flags);
} else {
for_each_class(class) {
if (class == rq->curr->sched_class)
break;
if (class == p->sched_class) {
resched_task(rq->curr);
break;
}
}
}
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* /*
* ->cpus_allowed is protected by either TASK_WAKING or rq->lock held. * ->cpus_allowed is protected by either TASK_WAKING or rq->lock held.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment