Commit a2a82087 authored by balaji's avatar balaji Committed by Jim Harris
Browse files

NVMe: Defer the notices processing in the AER callback untill all the CQE...


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: default avatarG.Balaji <gbalajieie@gmail.com>
Change-Id: I8cc80fba0a226c22753e605ef3129602a9313ce7
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7149


Community-CI: Broadcom CI
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 6d6870c7
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -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) {
+8 −0
Original line number Diff line number Diff line
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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)
{