block: don't kick empty queue in blk_drain_queue()
PATCH 1/1 block: don't kick empty queue in blk_drain_queue()
While probing, fd sets up queue, probes hardware and tears down the queue if probing fails. In the process, blk_drain_queue() kicks the queue which failed to finish initialization and fd is unhappy about that.
floppy0: no floppy controllers found
------------[ cut here ]------------ WARNING: at drivers/block/floppy.c:2929 do_fd_request+0xbf/0xd0() Hardware name: To Be Filled By O.E.M. VFS: do_fd_request called on non-open device Modules linked in: Pid: 1, comm: swapper Not tainted 3.2.0-rc4-00077-g5983fe2 #2 Call Trace: [<ffffffff81039a6a>] warn_slowpath_common+0x7a/0xb0 [<ffffffff81039b41>] warn_slowpath_fmt+0x41/0x50 [<ffffffff813d657f>] do_fd_request+0xbf/0xd0 [<ffffffff81322b95>] blk_drain_queue+0x65/0x80 [<ffffffff81322c93>] blk_cleanup_queue+0xe3/0x1a0 [<ffffffff818a809d>] floppy_init+0xdeb/0xe28 [<ffffffff818a72b2>] ? daring+0x6b/0x6b [<ffffffff810002af>] do_one_initcall+0x3f/0x170 [<ffffffff81884b34>] kernel_init+0x9d/0x11e [<ffffffff810317c2>] ? schedule_tail+0x22/0xa0 [<ffffffff815dbb14>] kernel_thread_helper+0x4/0x10 [<ffffffff81884a97>] ? start_kernel+0x2be/0x2be [<ffffffff815dbb10>] ? gs_change+0xb/0xb
Avoid it by making blk_drain_queue() kick queue iff dispatch queue has something on it.
--- block/blk-core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
block/blk-core.c +8 -1
@@ -366,7 +366,14 @@ void blk_drain_queue(struct request_queue *q, bool drain_all)if (drain_all)blk_throtl_drain (q); -__blk_run_queue (q); +/* +* This function might be called on a queue which failed +* driver init after queue creation. Some drivers +* (e.g. fd) get unhappy in such cases. Kick queue iff +* dispatch queue has something on it. +*/ +if (!list_empty (&q->queue_head)) +__blk_run_queue (q);if (drain_all) nr_rqs = q->rq.count[0 ] + q->rq.count[1 ];
Jens Axboe
maintainerQuoted 47 lines · Tejun Heo
While probing, fd sets up queue, probes hardware and tears down the queue if probing fails. In the process,
blk_drain_queue()kicks the queue which failed to finish initialization and fd is unhappy about that.floppy0: no floppy controllers found
------------[ cut here ]------------ WARNING: at drivers/block/floppy.c:2929 do_fd_request+0xbf/0xd0() Hardware name: To Be Filled By O.E.M. VFS: do_fd_request called on non-open device Modules linked in: Pid: 1, comm: swapper Not tainted 3.2.0-rc4-00077-g5983fe2 #2 Call Trace: [<ffffffff81039a6a>] warn_slowpath_common+0x7a/0xb0 [<ffffffff81039b41>] warn_slowpath_fmt+0x41/0x50 [<ffffffff813d657f>] do_fd_request+0xbf/0xd0 [<ffffffff81322b95>] blk_drain_queue+0x65/0x80 [<ffffffff81322c93>] blk_cleanup_queue+0xe3/0x1a0 [<ffffffff818a809d>] floppy_init+0xdeb/0xe28 [<ffffffff818a72b2>] ? daring+0x6b/0x6b [<ffffffff810002af>] do_one_initcall+0x3f/0x170 [<ffffffff81884b34>] kernel_init+0x9d/0x11e [<ffffffff810317c2>] ? schedule_tail+0x22/0xa0 [<ffffffff815dbb14>] kernel_thread_helper+0x4/0x10 [<ffffffff81884a97>] ? start_kernel+0x2be/0x2be [<ffffffff815dbb10>] ? gs_change+0xb/0xbAvoid it by making
blk_drain_queue()kick queue iff dispatch queue has something on it.Signed-off-by Tejun Heo <[email protected]>Reported-by Ralf Hildebrandt <[email protected]>Reported-by Wu Fengguang <[email protected]>Tested-by Sergei Trofimovich <[email protected]>--- block/blk-core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)block/blk-core.c +1
-1@@ -366,7 +366,14 @@ void blk_drain_queue(struct request_queue *q, bool drain_all)if (drain_all)blk_throtl_drain (q); -__blk_run_queue (q); +/*
block/blk-core.c void blk_drain_queue(struct request_queue *q, bool drain_all) · line 379
Quoted 10 lines
block/blk-core.c +7
-0+* This function might be called on a queue which failed +* driver init after queue creation. Some drivers +* (e.g. fd) get unhappy in such cases. Kick queue iff +* dispatch queue has something on it. +*/ +if (!list_empty (&q->queue_head)) +__blk_run_queue (q);if (drain_all) nr_rqs = q->rq.count[0 ] + q->rq.count[1 ];
Thanks, I'll queue this up. Coincidentally, it also exposed a bug in the fusion-io driver.
Signature · 1 line
Jens Axboe
Thanks! It fixed the problem for me.
Quoted 57 lines · Tejun Heo
While probing, fd sets up queue, probes hardware and tears down the queue if probing fails. In the process,
blk_drain_queue()kicks the queue which failed to finish initialization and fd is unhappy about that.floppy0: no floppy controllers found
------------[ cut here ]------------ WARNING: at drivers/block/floppy.c:2929 do_fd_request+0xbf/0xd0() Hardware name: To Be Filled By O.E.M. VFS: do_fd_request called on non-open device Modules linked in: Pid: 1, comm: swapper Not tainted 3.2.0-rc4-00077-g5983fe2 #2 Call Trace: [<ffffffff81039a6a>] warn_slowpath_common+0x7a/0xb0 [<ffffffff81039b41>] warn_slowpath_fmt+0x41/0x50 [<ffffffff813d657f>] do_fd_request+0xbf/0xd0 [<ffffffff81322b95>] blk_drain_queue+0x65/0x80 [<ffffffff81322c93>] blk_cleanup_queue+0xe3/0x1a0 [<ffffffff818a809d>] floppy_init+0xdeb/0xe28 [<ffffffff818a72b2>] ? daring+0x6b/0x6b [<ffffffff810002af>] do_one_initcall+0x3f/0x170 [<ffffffff81884b34>] kernel_init+0x9d/0x11e [<ffffffff810317c2>] ? schedule_tail+0x22/0xa0 [<ffffffff815dbb14>] kernel_thread_helper+0x4/0x10 [<ffffffff81884a97>] ? start_kernel+0x2be/0x2be [<ffffffff815dbb10>] ? gs_change+0xb/0xbAvoid it by making
blk_drain_queue()kick queue iff dispatch queue has something on it.Signed-off-by Tejun Heo <[email protected]>Reported-by Ralf Hildebrandt <[email protected]>Reported-by Wu Fengguang <[email protected]>Tested-by Sergei Trofimovich <[email protected]>--- block/blk-core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)block/blk-core.c +8
-1@@ -366,7 +366,14 @@ void blk_drain_queue(struct request_queue *q, bool drain_all)if (drain_all)blk_throtl_drain (q); -__blk_run_queue (q); +/* +* This function might be called on a queue which failed +* driver init after queue creation. Some drivers +* (e.g. fd) get unhappy in such cases. Kick queue iff +* dispatch queue has something on it. +*/ +if (!list_empty (&q->queue_head)) +__blk_run_queue (q);if (drain_all) nr_rqs = q->rq.count[0 ] + q->rq.count[1 ];