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 <kbusch@kernel.org> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
b7e97872a6
commit
371a982cd2
@ -4702,6 +4702,8 @@ static void nvme_fw_act_work(struct work_struct *work)
|
||||
nvme_start_queues(ctrl);
|
||||
/* read FW slot information to clear the AER */
|
||||
nvme_get_fw_slot_info(ctrl);
|
||||
|
||||
queue_work(nvme_wq, &ctrl->async_event_work);
|
||||
}
|
||||
|
||||
static u32 nvme_aer_type(u32 result)
|
||||
@ -4714,9 +4716,10 @@ static u32 nvme_aer_subtype(u32 result)
|
||||
return (result & 0xff00) >> 8;
|
||||
}
|
||||
|
||||
static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
|
||||
static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
|
||||
{
|
||||
u32 aer_notice_type = nvme_aer_subtype(result);
|
||||
bool requeue = true;
|
||||
|
||||
trace_nvme_async_event(ctrl, aer_notice_type);
|
||||
|
||||
@ -4733,6 +4736,7 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
|
||||
*/
|
||||
if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) {
|
||||
nvme_auth_stop(ctrl);
|
||||
requeue = false;
|
||||
queue_work(nvme_wq, &ctrl->fw_act_work);
|
||||
}
|
||||
break;
|
||||
@ -4749,6 +4753,7 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
|
||||
default:
|
||||
dev_warn(ctrl->device, "async event result %08x\n", result);
|
||||
}
|
||||
return requeue;
|
||||
}
|
||||
|
||||
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,
|
||||
u32 result = le32_to_cpu(res->u32);
|
||||
u32 aer_type = nvme_aer_type(result);
|
||||
u32 aer_subtype = nvme_aer_subtype(result);
|
||||
bool requeue = true;
|
||||
|
||||
if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS)
|
||||
return;
|
||||
|
||||
switch (aer_type) {
|
||||
case NVME_AER_NOTICE:
|
||||
nvme_handle_aen_notice(ctrl, result);
|
||||
requeue = nvme_handle_aen_notice(ctrl, result);
|
||||
break;
|
||||
case NVME_AER_ERROR:
|
||||
/*
|
||||
@ -4791,7 +4797,9 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
queue_work(nvme_wq, &ctrl->async_event_work);
|
||||
|
||||
if (requeue)
|
||||
queue_work(nvme_wq, &ctrl->async_event_work);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvme_complete_async_event);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user