[PATCH] block: fix Oops in blk_rq_poll_completion()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a NULL check before we poll on req->bio in blk_rq_poll_completion().
Without this patch blktests/nvme/047 fails :-

* Debug-diff:-

linux-block (for-next) # git diff
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1b304f66f4e8..31473f55b374 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1335,6 +1335,8 @@ EXPORT_SYMBOL_GPL(blk_rq_is_poll);
 static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
 {
        do {
+               if (!rq->bio)
+                       BUG_ON(1);
                bio_poll(rq->bio, NULL, 0);
                cond_resched();
        } while (!completion_done(wait));

* Terminal:-

linux-block (for-next) # cdblktests
blktests (master) # nvme_trtype=tcp ./check nvme/047
nvme/047 (test different queue types for fabric transports)
client_loop: send disconnect: Broken pipe

* Oops:-

[   42.354149] kernel BUG at block/blk-mq.c:1339! <------

Entering kdb (current=0xffff88814c70a840, pid 2460) on processor 21 Oops: (null)
due to oops @ 0xffffffff816ee9cf
CPU: 21 PID: 2460 Comm: nvme Tainted: G                 N 6.3.0-rc5lblk+ #5
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
RIP: 0010:blk_execute_rq+0x11f/0x1c0
Code: ff 0f 84 ad 00 00 00 31 d2 31 f6 e8 8b 4c ff ff e8 46 27 74 00 48 89 ef e8 1e 80 a6 ff 84 c0 75 b3 48 8b 7b 38 48 85 ff 75 dd <0f> 0b 0f 0b 48 c7 83 f0 00 00 00 50 bd 6e 81 48 89 e5 48 89 ab f8
RSP: 0018:ffffc9000172fbc8 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff88814d910000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ffffc9000172fbc8 R08: 00000009dc7ed61b R09: 0000000000000001
R10: ffff888166c36c78 R11: 0000000000000000 R12: 0000000000000001
R13: ffff88810a06d000 R14: 0000000000000400 R15: ffffc9000172fc68
FS:  00007f59b5d35b80(0000) GS:ffff8897df740000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f59b5e78d50 CR3: 000000010a9f2000 CR4: 0000000000350ee0
DR0: ffffffff8437a434 DR1: ffffffff8437a435 DR2: ffffffff8437a436
DR3: ffffffff8437a437 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 __nvme_submit_sync_cmd+0xa6/0x170 [nvme_core]
 nvmf_connect_io_queue+0x11c/0x220 [nvme_fabrics]
 ? nvme_tcp_start_queue+0x12e/0x1a0 [nvme_tcp]
 ? __local_bh_enable_ip+0x37/0x90
 nvme_tcp_start_queue+0x12e/0x1a0 [nvme_tcp]
 nvme_tcp_setup_ctrl+0x439/0x800 [nvme_tcp]
 nvme_tcp_create_ctrl+0x34b/0x450 [nvme_tcp]
 nvmf_dev_write+0x5db/0xe80 [nvme_fabrics]
 ? inode_security+0x22/0x60
 ? selinux_file_permission+0x108/0x150
 vfs_write+0xc5/0x3c0
 ? _raw_spin_unlock+0x15/0x30
 ? preempt_count_add+0x4d/0xa0
 ? fd_install+0x5c/0xe0
 ksys_write+0x5f/0xe0
 do_syscall_64+0x3b/0x90
 entry_SYSCALL_64_after_hwframe+0x72/0xdc
RIP: 0033:0x7f59b5e4b7a7
Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24
RSP: 002b:00007fff145e5938 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000001bbad00 RCX: 00007f59b5e4b7a7
RDX: 00000000000000b9 RSI: 0000000001bbad00 RDI: 0000000000000004
RBP: 0000000000000004 R08: 00000000000000b9 R09: 0000000001bbad00
R10: 00007f59b5d6f118 R11: 0000000000000246 R12: 0000000001bb97e0
R13: 00000000000000b9 R14: 00007f59b5f7811d R15: 00007f59b5f7802b
 </TASK>

[21]kdb>

Please note that this fix is generated purely based on tracing I/O path
with BUG_ON().

Signed-off-by: Chaitanya Kulkarni <kch@xxxxxxxxxx>
---
 block/blk-mq.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1b304f66f4e8..9cd5e890c9c9 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1335,7 +1335,8 @@ EXPORT_SYMBOL_GPL(blk_rq_is_poll);
 static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
 {
 	do {
-		bio_poll(rq->bio, NULL, 0);
+		if (rq->bio)
+			bio_poll(rq->bio, NULL, 0);
 		cond_resched();
 	} while (!completion_done(wait));
 }
-- 
2.40.0




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux