NVMe: Defer the notices processing in the AER callback untill all the CQE entries have been processed.

When the format command is issued, the kioxia drives responds with "NS Attr change" notices.
In the callback function of the notice, the CQ Head Doorbell is updated twice with the same
value while issuing the Active NS list & identify NS commands.

Fixes:  #1701

Signed-off-by: G.Balaji <gbalajieie@gmail.com>
Change-Id: I8cc80fba0a226c22753e605ef3129602a9313ce7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7149
Community-CI: Broadcom CI
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
balaji 2021-04-17 13:55:03 +05:30 committed by Jim Harris
parent 6d6870c7b6
commit a2a82087b9
3 changed files with 45 additions and 1 deletions

View File

@ -2613,6 +2613,35 @@ nvme_ctrlr_process_async_event(struct spdk_nvme_ctrlr *ctrlr,
}
}
static void
nvme_ctrlr_queue_async_event(struct spdk_nvme_ctrlr *ctrlr,
const struct spdk_nvme_cpl *cpl)
{
struct spdk_nvme_ctrlr_aer_completion_list *nvme_event;
nvme_event = calloc(1, sizeof(*nvme_event));
if (!nvme_event) {
NVME_CTRLR_ERRLOG(ctrlr, "Alloc nvme event failed, ignore the event\n");
return;
}
nvme_event->cpl = *cpl;
STAILQ_INSERT_TAIL(&ctrlr->async_events, nvme_event, link);
}
void
nvme_ctrlr_complete_queued_async_events(struct spdk_nvme_ctrlr *ctrlr)
{
struct spdk_nvme_ctrlr_aer_completion_list *nvme_event, *nvme_event_tmp;
STAILQ_FOREACH_SAFE(nvme_event, &ctrlr->async_events, link, nvme_event_tmp) {
STAILQ_REMOVE(&ctrlr->async_events, nvme_event,
spdk_nvme_ctrlr_aer_completion_list, link);
nvme_ctrlr_process_async_event(ctrlr, &nvme_event->cpl);
free(nvme_event);
}
}
static void
nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl)
{
@ -2642,7 +2671,8 @@ nvme_ctrlr_async_event_cb(void *arg, const struct spdk_nvme_cpl *cpl)
return;
}
nvme_ctrlr_process_async_event(ctrlr, cpl);
/* Add the events to the list */
nvme_ctrlr_queue_async_event(ctrlr, cpl);
/* If the ctrlr was removed or in the destruct state, we should not send aer again */
if (ctrlr->is_removed || ctrlr->is_destructed) {
@ -3325,6 +3355,7 @@ nvme_ctrlr_construct(struct spdk_nvme_ctrlr *ctrlr)
TAILQ_INIT(&ctrlr->active_io_qpairs);
STAILQ_INIT(&ctrlr->queued_aborts);
STAILQ_INIT(&ctrlr->async_events);
ctrlr->outstanding_aborts = 0;
ctrlr->ana_log_page = NULL;
@ -3521,6 +3552,9 @@ spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr)
num_completions = rc;
rc = spdk_nvme_qpair_process_completions(ctrlr->adminq, 0);
nvme_ctrlr_complete_queued_async_events(ctrlr);
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
if (rc < 0) {

View File

@ -731,6 +731,11 @@ struct spdk_nvme_ctrlr_process {
uint64_t timeout_ticks;
};
struct spdk_nvme_ctrlr_aer_completion_list {
struct spdk_nvme_cpl cpl;
STAILQ_ENTRY(spdk_nvme_ctrlr_aer_completion_list) link;
};
/*
* One of these per allocated PCI device.
*/
@ -858,6 +863,8 @@ struct spdk_nvme_ctrlr {
/* maximum zone append size in bytes */
uint32_t max_zone_append_size;
STAILQ_HEAD(, spdk_nvme_ctrlr_aer_completion_list) async_events;
};
struct spdk_nvme_probe_ctx {
@ -1026,6 +1033,7 @@ void nvme_ctrlr_init_cap(struct spdk_nvme_ctrlr *ctrlr, const union spdk_nvme_ca
void nvme_ctrlr_process_async_event(struct spdk_nvme_ctrlr *ctrlr,
const struct spdk_nvme_cpl *cpl);
void nvme_ctrlr_disconnect_qpair(struct spdk_nvme_qpair *qpair);
void nvme_ctrlr_complete_queued_async_events(struct spdk_nvme_ctrlr *ctrlr);
int nvme_qpair_init(struct spdk_nvme_qpair *qpair, uint16_t id,
struct spdk_nvme_ctrlr *ctrlr,
enum spdk_nvme_qprio qprio,

View File

@ -58,6 +58,8 @@ DEFINE_STUB_V(nvme_transport_ctrlr_disconnect_qpair, (struct spdk_nvme_ctrlr *ct
struct spdk_nvme_qpair *qpair));
DEFINE_STUB_V(nvme_ctrlr_disconnect_qpair, (struct spdk_nvme_qpair *qpair));
DEFINE_STUB_V(nvme_ctrlr_complete_queued_async_events, (struct spdk_nvme_ctrlr *ctrlr));
void
nvme_ctrlr_fail(struct spdk_nvme_ctrlr *ctrlr, bool hot_remove)
{