Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nvme-pci: fix sleeping function called from interrupt context

the nvme_handle_cqe() interrupt handler calls nvme_complete_async_event()
but the latter may call nvme_auth_stop() which is a blocking function.
Sleeping functions can't be called in interrupt context

BUG: sleeping function called from invalid context
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/15
Call Trace:
<IRQ>
__cancel_work_timer+0x31e/0x460
? nvme_change_ctrl_state+0xcf/0x3c0 [nvme_core]
? nvme_change_ctrl_state+0xcf/0x3c0 [nvme_core]
nvme_complete_async_event+0x365/0x480 [nvme_core]
nvme_poll_cq+0x262/0xe50 [nvme]

Fix the bug by moving nvme_auth_stop() to fw_act_work
(executed by the nvme_wq workqueue)

Fixes: f50fff73d620 ("nvme: implement In-Band authentication")
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Keith Busch <kbusch@kernel.org>

authored by

Maurizio Lombardi and committed by
Keith Busch
f6fe0b2d d3e8b185

+2 -1
+2 -1
drivers/nvme/host/core.c
··· 4137 4137 struct nvme_ctrl, fw_act_work); 4138 4138 unsigned long fw_act_timeout; 4139 4139 4140 + nvme_auth_stop(ctrl); 4141 + 4140 4142 if (ctrl->mtfa) 4141 4143 fw_act_timeout = jiffies + 4142 4144 msecs_to_jiffies(ctrl->mtfa * 100); ··· 4194 4192 * firmware activation. 4195 4193 */ 4196 4194 if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) { 4197 - nvme_auth_stop(ctrl); 4198 4195 requeue = false; 4199 4196 queue_work(nvme_wq, &ctrl->fw_act_work); 4200 4197 }