block: splice plug list to local context
authorNeilBrown <neilb@suse.de>
Mon, 11 Apr 2011 12:13:10 +0000 (14:13 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Mon, 11 Apr 2011 12:13:10 +0000 (14:13 +0200)
commit109b81296c63228578d4760794d8dd46e02eddfb
tree2f723e1b69ab08e12528f677f04edbfc7473b7c5
parent4263a2f1dad8c8e7ce2352a0cbc882c2b0c044a9
block: splice plug list to local context

If the request_fn ends up blocking, we could be re-entering
the plug flush. Since the list is protected by explicitly
not allowing schedule events, this isn't a terribly good idea.

Additionally, it can cause us to recurse. As request_fn called by
__blk_run_queue is allowed to 'schedule()' (after dropping the queue
lock of course), it is possible to get a recursive call:

 schedule -> blk_flush_plug -> __blk_finish_plug -> flush_plug_list
      -> __blk_run_queue -> request_fn -> schedule

We must make sure that the second schedule does not call into
blk_flush_plug again.  So instead of leaving the list of requests on
blk_plug->list, move them to a separate list leaving blk_plug->list
empty.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
block/blk-core.c