Commit 83ab0aa0 authored by Thomas Gleixner's avatar Thomas Gleixner

sched: Don't use possibly stale sched_class

setscheduler() saves task->sched_class outside of the rq->lock held
region for a check after the setscheduler changes have become
effective. That might result in checking a stale value.

rtmutex_setprio() has the same problem, though it is protected by
p->pi_lock against setscheduler(), but for correctness sake (and to
avoid bad examples) it needs to be fixed as well.

Retrieve task->sched_class inside of the rq->lock held region.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Cc: stable@kernel.org
parent 6e40f5bb
...@@ -4249,7 +4249,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) ...@@ -4249,7 +4249,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
unsigned long flags; unsigned long flags;
int oldprio, on_rq, running; int oldprio, on_rq, running;
struct rq *rq; struct rq *rq;
const struct sched_class *prev_class = p->sched_class; const struct sched_class *prev_class;
BUG_ON(prio < 0 || prio > MAX_PRIO); BUG_ON(prio < 0 || prio > MAX_PRIO);
...@@ -4257,6 +4257,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) ...@@ -4257,6 +4257,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio)
update_rq_clock(rq); update_rq_clock(rq);
oldprio = p->prio; oldprio = p->prio;
prev_class = p->sched_class;
on_rq = p->se.on_rq; on_rq = p->se.on_rq;
running = task_current(rq, p); running = task_current(rq, p);
if (on_rq) if (on_rq)
...@@ -4476,7 +4477,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, ...@@ -4476,7 +4477,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
{ {
int retval, oldprio, oldpolicy = -1, on_rq, running; int retval, oldprio, oldpolicy = -1, on_rq, running;
unsigned long flags; unsigned long flags;
const struct sched_class *prev_class = p->sched_class; const struct sched_class *prev_class;
struct rq *rq; struct rq *rq;
int reset_on_fork; int reset_on_fork;
...@@ -4590,6 +4591,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, ...@@ -4590,6 +4591,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy,
p->sched_reset_on_fork = reset_on_fork; p->sched_reset_on_fork = reset_on_fork;
oldprio = p->prio; oldprio = p->prio;
prev_class = p->sched_class;
__setscheduler(rq, p, policy, param->sched_priority); __setscheduler(rq, p, policy, param->sched_priority);
if (running) if (running)
......
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