lkml.org 
[lkml]   [2011]   [Sep]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[062/244] sched: Move blk_schedule_flush_plug() out of __schedule()
    3.0-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Thomas Gleixner <tglx@linutronix.de>

    commit 9c40cef2b799f9b5e7fa5de4d2ad3a0168ba118c upstream.

    There is no real reason to run blk_schedule_flush_plug() with
    interrupts and preemption disabled.

    Move it into schedule() and call it when the task is going voluntarily
    to sleep. There might be false positives when the task is woken
    between that call and actually scheduling, but that's not really
    different from being woken immediately after switching away.

    This fixes a deadlock in the scheduler where the
    blk_schedule_flush_plug() callchain enables interrupts and thereby
    allows a wakeup to happen of the task that's going to sleep.

    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Tejun Heo <tj@kernel.org>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Link: http://lkml.kernel.org/n/tip-dwfxtra7yg1b5r65m32ywtct@git.kernel.org
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    kernel/sched.c | 25 +++++++++++++++----------
    1 file changed, 15 insertions(+), 10 deletions(-)

    --- a/kernel/sched.c
    +++ b/kernel/sched.c
    @@ -4285,16 +4285,6 @@ need_resched:
    if (to_wakeup)
    try_to_wake_up_local(to_wakeup);
    }
    -
    - /*
    - * If we are going to sleep and we have plugged IO
    - * queued, make sure to submit it to avoid deadlocks.
    - */
    - if (blk_needs_flush_plug(prev)) {
    - raw_spin_unlock(&rq->lock);
    - blk_schedule_flush_plug(prev);
    - raw_spin_lock(&rq->lock);
    - }
    }
    switch_count = &prev->nvcsw;
    }
    @@ -4333,8 +4323,23 @@ need_resched:
    goto need_resched;
    }

    +static inline void sched_submit_work(struct task_struct *tsk)
    +{
    + if (!tsk->state)
    + return;
    + /*
    + * If we are going to sleep and we have plugged IO queued,
    + * make sure to submit it to avoid deadlocks.
    + */
    + if (blk_needs_flush_plug(tsk))
    + blk_schedule_flush_plug(tsk);
    +}
    +
    asmlinkage void schedule(void)
    {
    + struct task_struct *tsk = current;
    +
    + sched_submit_work(tsk);
    __schedule();
    }
    EXPORT_SYMBOL(schedule);



    \
     
     \ /
      Last update: 2011-09-29 00:47    [W:0.028 / U:120.344 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site