sched/core: Fix set_user_nice()
Almost all scheduler functions update state with the following pattern: if (queued) dequeue_task(rq, p, DEQUEUE_SAVE); if (running) put_prev_task(rq, p); /* update state */ if (queued) enqueue_task(rq, p, ENQUEUE_RESTORE); if (running) set_curr_task(rq, p); set_user_nice() however misses the running part, cure this. This was found by asserting we never enqueue 'current'. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
b2bf6c314e
commit
49bd21efe7
1 changed files with 7 additions and 1 deletions
|
@ -3724,7 +3724,8 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
|
|||
|
||||
void set_user_nice(struct task_struct *p, long nice)
|
||||
{
|
||||
int old_prio, delta, queued;
|
||||
bool queued, running;
|
||||
int old_prio, delta;
|
||||
struct rq_flags rf;
|
||||
struct rq *rq;
|
||||
|
||||
|
@ -3746,8 +3747,11 @@ void set_user_nice(struct task_struct *p, long nice)
|
|||
goto out_unlock;
|
||||
}
|
||||
queued = task_on_rq_queued(p);
|
||||
running = task_current(rq, p);
|
||||
if (queued)
|
||||
dequeue_task(rq, p, DEQUEUE_SAVE);
|
||||
if (running)
|
||||
put_prev_task(rq, p);
|
||||
|
||||
p->static_prio = NICE_TO_PRIO(nice);
|
||||
set_load_weight(p);
|
||||
|
@ -3764,6 +3768,8 @@ void set_user_nice(struct task_struct *p, long nice)
|
|||
if (delta < 0 || (delta > 0 && task_running(rq, p)))
|
||||
resched_curr(rq);
|
||||
}
|
||||
if (running)
|
||||
set_curr_task(rq, p);
|
||||
out_unlock:
|
||||
task_rq_unlock(rq, p, &rf);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue