block: blk-flush shouldn't call directly into q->request_fn() __blk_run_queue()
authorTejun Heo <tj@kernel.org>
Wed, 2 Mar 2011 13:48:06 +0000 (08:48 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 7 Mar 2011 23:05:24 +0000 (15:05 -0800)
commit29bf78d4b4b15cdec995180cbf78e69a4c1c9d14
treedb308d86a1e4d4642f498624d21070072d3e1876
parent02d63a7def32bb4a58ea6e24f0edfce0aa653aaa
block: blk-flush shouldn't call directly into q->request_fn() __blk_run_queue()

commit 255bb490c8c27eed484d538efe6ef6a7473bd3f6 upstream.

blk-flush decomposes a flush into sequence of multiple requests.  On
completion of a request, the next one is queued; however, block layer
must not implicitly call into q->request_fn() directly from completion
path.  This makes the queue behave unexpectedly when seen from the
drivers and violates the assumption that q->request_fn() is called
with process context + queue_lock.

This patch makes blk-flush the following two changes to make sure
q->request_fn() is not called directly from request completion path.

- blk_flush_complete_seq_end_io() now asks __blk_run_queue() to always
  use kblockd instead of calling directly into q->request_fn().

- queue_next_fseq() uses ELEVATOR_INSERT_REQUEUE instead of
  ELEVATOR_INSERT_FRONT so that elv_insert() doesn't try to unplug the
  request queue directly.

Reported by Jan in the following threads.

 http://thread.gmane.org/gmane.linux.ide/48778
 http://thread.gmane.org/gmane.linux.ide/48786

stable: applicable to v2.6.37.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Jan Beulich <JBeulich@novell.com>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
block/blk-flush.c