nvme-pci: rerun irq setup on IO queue init errors
If the driver is unable to create a subset of IO queues for any reason,
the read/write and polled queue sets will not match the actual allocated
hardware contexts. This leaves gaps in the CPU affinity mappings and
causes the following kernel panic after blk_mq_map_queue_type() returns
a NULL hctx.
BUG: unable to handle kernel NULL pointer dereference at
0000000000000198
#PF error: [normal kernel read fault]
PGD 0 P4D 0
Oops: 0000 [#1] SMP
CPU: 64 PID: 1171 Comm: kworker/u259:1 Not tainted 4.20.0+ #241
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-2.fc27 04/01/2014
Workqueue: nvme-wq nvme_scan_work [nvme_core]
RIP: 0010:blk_mq_init_allocated_queue+0x2d9/0x440
RSP: 0018:
ffffb1bf0abc3cd0 EFLAGS:
00010286
RAX:
000000000000001f RBX:
ffff8ea744cf0718 RCX:
0000000000000000
RDX:
0000000000000002 RSI:
000000000000007c RDI:
ffffffff9109a820
RBP:
ffff8ea7565f7008 R08:
000000000000001f R09:
000000000000003f
R10:
ffffb1bf0abc3c00 R11:
0000000000000000 R12:
000000000001d008
R13:
ffff8ea7565f7008 R14:
000000000000003f R15:
0000000000000001
FS:
0000000000000000(0000) GS:
ffff8ea757200000(0000) knlGS:
0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0:
0000000080050033
CR2:
0000000000000198 CR3:
0000000013058000 CR4:
00000000000006e0
DR0:
0000000000000000 DR1:
0000000000000000 DR2:
0000000000000000
DR3:
0000000000000000 DR6:
00000000fffe0ff0 DR7:
0000000000000400
Call Trace:
blk_mq_init_queue+0x35/0x60
nvme_validate_ns+0xc6/0x7c0 [nvme_core]
? nvme_identify_ctrl.isra.56+0x7e/0xc0 [nvme_core]
nvme_scan_work+0xc8/0x340 [nvme_core]
? __wake_up_common+0x6d/0x120
? try_to_wake_up+0x55/0x410
process_one_work+0x1e9/0x3d0
worker_thread+0x2d/0x3d0
? process_one_work+0x3d0/0x3d0
kthread+0x111/0x130
? kthread_park+0x90/0x90
ret_from_fork+0x1f/0x30
Modules linked in: nvme nvme_core serio_raw
CR2:
0000000000000198
Fix by re-running the interrupt vector setup from scratch using a reduced
count that may be successful until the created queues matches the irq
affinity plus polling queue sets.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>