lkml.org 
[lkml]   [2010]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subjectsched: Fix wake up race with rt_mutex_setprio()
    rt_mutex_setprio() can race with try_to_wake_up():

    CPU 0 CPU 1
    try_to_wake_up(p)
    task_rq_lock(p)
    p->state = TASK_WAKING;
    task_rq_unlock() rt_mutex_setprio(p)
    task_rq_lock(p) <- succeeds (old CPU)
    newcpu = select_task_rq(p)
    set_task_cpu(p)

    task_rq_lock(p) <- succeeds (new CPU)

    activate_task(p) change sched_class(p)

    That way we end up with the task enqueued in the wrong sched class.

    Solve this by waiting for p->state != TASK_WAKING in rt_mutex_setprio().

    Debugged and tested in the preempt-rt tree.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    ---
    kernel/sched.c | 18 ++++++++++++++++++
    1 file changed, 18 insertions(+)

    Index: linux-2.6/kernel/sched.c
    ===================================================================
    --- linux-2.6.orig/kernel/sched.c
    +++ linux-2.6/kernel/sched.c
    @@ -6058,7 +6058,25 @@ void rt_mutex_setprio(struct task_struct

    BUG_ON(prio < 0 || prio > MAX_PRIO);

    +again:
    rq = task_rq_lock(p, &flags);
    +
    + /*
    + * Prevent a nasty race with ttwu(). ttwu() sets the task
    + * state to WAKING and drops the runqueue lock. So we can
    + * acquire the runqueue lock while ttwu() migrates the
    + * task. We need to wait until ttwu() set the target cpu and
    + * enqueued the task on whatever CPU it decided to select.
    + * Otherwise ttwu() might enqueue with the old class on
    + * another cpu while we are changing the class on the previous
    + * cpu.
    + */
    + if (unlikely(p->state == TASK_WAKING)) {
    + task_rq_unlock(rq, &flags);
    + cpu_relax();
    + goto again;
    + }
    +
    update_rq_clock(rq);

    oldprio = p->prio;

    \
     
     \ /
      Last update: 2010-02-14 20:49    [W:0.039 / U:29.652 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site