nvmet: fix oops in pt cmd execution
In the existing NVMeOF Passthru core command handling on failure of
nvme_alloc_request() it errors out with rq value set to NULL. In the
error handling path it calls blk_put_request() without checking if
rq is set to NULL or not which produces following Oops:-
[ 1457.346861] BUG: kernel NULL pointer dereference, address:
0000000000000000
[ 1457.347838] #PF: supervisor read access in kernel mode
[ 1457.348464] #PF: error_code(0x0000) - not-present page
[ 1457.349085] PGD 0 P4D 0
[ 1457.349402] Oops: 0000 [#1] SMP NOPTI
[ 1457.349851] CPU: 18 PID: 10782 Comm: kworker/18:2 Tainted: G OE 5.8.0-rc4nvme-5.9+ #35
[ 1457.350951] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.12.0-59-gc9ba5276e3214
[ 1457.352347] Workqueue: events nvme_loop_execute_work [nvme_loop]
[ 1457.353062] RIP: 0010:blk_mq_free_request+0xe/0x110
[ 1457.353651] Code: 3f ff ff ff 83 f8 01 75 0d 4c 89 e7 e8 1b db ff ff e9 2d ff ff ff 0f 0b eb ef 66 8
[ 1457.355975] RSP: 0018:
ffffc900035b7de0 EFLAGS:
00010282
[ 1457.356636] RAX:
0000000000000000 RBX:
0000000000000000 RCX:
0000000000000002
[ 1457.357526] RDX:
ffffffffa060bd05 RSI:
0000000000000000 RDI:
0000000000000000
[ 1457.358416] RBP:
0000000000000037 R08:
0000000000000000 R09:
0000000000000000
[ 1457.359317] R10:
0000000000000000 R11:
000000000000006d R12:
0000000000000000
[ 1457.360424] R13:
ffff8887ffa68600 R14:
0000000000000000 R15:
ffff8888150564c8
[ 1457.361322] FS:
0000000000000000(0000) GS:
ffff888814600000(0000) knlGS:
0000000000000000
[ 1457.362337] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 1457.363058] CR2:
0000000000000000 CR3:
000000081c0ac000 CR4:
00000000003406e0
[ 1457.363973] Call Trace:
[ 1457.364296] nvmet_passthru_execute_cmd+0x150/0x2c0 [nvmet]
[ 1457.364990] process_one_work+0x24e/0x5a0
[ 1457.365493] ? __schedule+0x353/0x840
[ 1457.365957] worker_thread+0x3c/0x380
[ 1457.366426] ? process_one_work+0x5a0/0x5a0
[ 1457.366948] kthread+0x135/0x150
[ 1457.367362] ? kthread_create_on_node+0x60/0x60
[ 1457.367934] ret_from_fork+0x22/0x30
[ 1457.368388] Modules linked in: nvme_loop(OE) nvmet(OE) nvme_fabrics(OE) null_blk nvme(OE) nvme_corer
[ 1457.368414] ata_piix crc32c_intel virtio_pci libata virtio_ring serio_raw t10_pi virtio floppy dm_]
[ 1457.380849] CR2:
0000000000000000
[ 1457.381288] ---[ end trace
c6cab61bfd1f68fd ]---
[ 1457.381861] RIP: 0010:blk_mq_free_request+0xe/0x110
[ 1457.382469] Code: 3f ff ff ff 83 f8 01 75 0d 4c 89 e7 e8 1b db ff ff e9 2d ff ff ff 0f 0b eb ef 66 8
[ 1457.384749] RSP: 0018:
ffffc900035b7de0 EFLAGS:
00010282
[ 1457.385393] RAX:
0000000000000000 RBX:
0000000000000000 RCX:
0000000000000002
[ 1457.386264] RDX:
ffffffffa060bd05 RSI:
0000000000000000 RDI:
0000000000000000
[ 1457.387142] RBP:
0000000000000037 R08:
0000000000000000 R09:
0000000000000000
[ 1457.388029] R10:
0000000000000000 R11:
000000000000006d R12:
0000000000000000
[ 1457.388914] R13:
ffff8887ffa68600 R14:
0000000000000000 R15:
ffff8888150564c8
[ 1457.389798] FS:
0000000000000000(0000) GS:
ffff888814600000(0000) knlGS:
0000000000000000
[ 1457.390796] CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
[ 1457.391508] CR2:
0000000000000000 CR3:
000000081c0ac000 CR4:
00000000003406e0
[ 1457.392525] Kernel panic - not syncing: Fatal exception
[ 1457.394138] Kernel Offset: disabled
[ 1457.394677] ---[ end Kernel panic - not syncing: Fatal exception ]---
We fix this Oops by adding a new goto label out_put_req and reordering
the blk_put_request call to avoid calling blk_put_request() with rq
value is set to NULL. Here we also update the rest of the code
accordingly.
Fixes: 06b7164dfdc0 ("nvmet: add passthru code to process commands")
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Jens Axboe <axboe@kernel.dk>