• NeilBrown's avatar
    sched: Prevent recursion in io_schedule() · 9cff8ade
    NeilBrown authored
    io_schedule() calls blk_flush_plug() which, depending on the
    contents of current->plug, can initiate arbitrary blk-io requests.
    
    Note that this contrasts with blk_schedule_flush_plug() which requires
    all non-trivial work to be handed off to a separate thread.
    
    This makes it possible for io_schedule() to recurse, and initiating
    block requests could possibly call mempool_alloc() which, in times of
    memory pressure, uses io_schedule().
    
    Apart from any stack usage issues, io_schedule() will not behave
    correctly when called recursively as delayacct_blkio_start() does
    not allow for repeated calls.
    
    So:
     - use ->in_iowait to detect recursion.  Set it earlier, and restore
       it to the old value.
     - move the call to "raw_rq" after the call to blk_flush_plug().
       As this is some sort of per-cpu thing, we want some chance that
       we are on the right CPU
     - When io_schedule() is called recurively, use blk_schedule_flush_plug()
       which cannot further recurse.
     - as this makes io_schedule() a lot more complex and as io_schedule()
       must match io_schedule_timeout(), but all the changes in io_schedule_timeout()
       and make io_schedule a simple wrapper for that.
    Signed-off-by: default avatarNeilBrown <neilb@suse.de>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    [ Moved the now rudimentary io_schedule() into sched.h. ]
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Tony Battersby <tonyb@cybernetics.com>
    Link: http://lkml.kernel.org/r/20150213162600.059fffb2@notabene.brownSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    9cff8ade
core.c 200 KB