Skip to content

Commit 371a982

Browse files
keithbuschChristoph Hellwig
authored andcommitted
nvme: requeue aen after firmware activation
The driver prevents async event work while handling a processing paused event, but someone needs to restart it after the controller returns to a live state. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216400 Signed-off-by: Keith Busch <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent b7e9787 commit 371a982

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

drivers/nvme/host/core.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4702,6 +4702,8 @@ static void nvme_fw_act_work(struct work_struct *work)
47024702
nvme_start_queues(ctrl);
47034703
/* read FW slot information to clear the AER */
47044704
nvme_get_fw_slot_info(ctrl);
4705+
4706+
queue_work(nvme_wq, &ctrl->async_event_work);
47054707
}
47064708

47074709
static u32 nvme_aer_type(u32 result)
@@ -4714,9 +4716,10 @@ static u32 nvme_aer_subtype(u32 result)
47144716
return (result & 0xff00) >> 8;
47154717
}
47164718

4717-
static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
4719+
static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
47184720
{
47194721
u32 aer_notice_type = nvme_aer_subtype(result);
4722+
bool requeue = true;
47204723

47214724
trace_nvme_async_event(ctrl, aer_notice_type);
47224725

@@ -4733,6 +4736,7 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
47334736
*/
47344737
if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) {
47354738
nvme_auth_stop(ctrl);
4739+
requeue = false;
47364740
queue_work(nvme_wq, &ctrl->fw_act_work);
47374741
}
47384742
break;
@@ -4749,6 +4753,7 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
47494753
default:
47504754
dev_warn(ctrl->device, "async event result %08x\n", result);
47514755
}
4756+
return requeue;
47524757
}
47534758

47544759
static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl)
@@ -4764,13 +4769,14 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
47644769
u32 result = le32_to_cpu(res->u32);
47654770
u32 aer_type = nvme_aer_type(result);
47664771
u32 aer_subtype = nvme_aer_subtype(result);
4772+
bool requeue = true;
47674773

47684774
if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS)
47694775
return;
47704776

47714777
switch (aer_type) {
47724778
case NVME_AER_NOTICE:
4773-
nvme_handle_aen_notice(ctrl, result);
4779+
requeue = nvme_handle_aen_notice(ctrl, result);
47744780
break;
47754781
case NVME_AER_ERROR:
47764782
/*
@@ -4791,7 +4797,9 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
47914797
default:
47924798
break;
47934799
}
4794-
queue_work(nvme_wq, &ctrl->async_event_work);
4800+
4801+
if (requeue)
4802+
queue_work(nvme_wq, &ctrl->async_event_work);
47954803
}
47964804
EXPORT_SYMBOL_GPL(nvme_complete_async_event);
47974805

0 commit comments

Comments
 (0)