sched: Guarantee task priority in pick_next_task()
Michael spotted that the idle_balance() push down created a task
priority problem.
Previously, when we called idle_balance() before pick_next_task() it
wasn't a problem when -- because of the rq->lock droppage -- an rt/dl
task slipped in.
Similarly for pre_schedule(), rt pre-schedule could have a dl task
slip in.
But by pulling it into the pick_next_task() loop, we'll not try a
higher task priority again.
Cure this by creating a re-start condition in pick_next_task(); and
triggering this from pick_next_task_{rt,fair}().
It also fixes a live-lock where we get stuck in pick_next_task_fair()
due to idle_balance() seeing !0 nr_running but there not actually
being any fair tasks about.
Reported-by: Michael Wang <wangyun@linux.vnet.ibm.com>
Fixes: 38033c37fa
("sched: Push down pre_schedule() and idle_balance()")
Tested-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/20140224121218.GR15586@twins.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Este cometimento está contido em:

cometido por
Ingo Molnar

ascendente
06d50c65b1
cometimento
37e117c07b
@@ -1091,6 +1091,8 @@ static const u32 prio_to_wmult[40] = {
|
||||
|
||||
#define DEQUEUE_SLEEP 1
|
||||
|
||||
#define RETRY_TASK ((void *)-1UL)
|
||||
|
||||
struct sched_class {
|
||||
const struct sched_class *next;
|
||||
|
||||
@@ -1105,6 +1107,9 @@ struct sched_class {
|
||||
* It is the responsibility of the pick_next_task() method that will
|
||||
* return the next task to call put_prev_task() on the @prev task or
|
||||
* something equivalent.
|
||||
*
|
||||
* May return RETRY_TASK when it finds a higher prio class has runnable
|
||||
* tasks.
|
||||
*/
|
||||
struct task_struct * (*pick_next_task) (struct rq *rq,
|
||||
struct task_struct *prev);
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador