nvmf: support multi AER events in nvmf target

Add the AER events in nvmf target from one to four.

Change-Id: Ie31988b49d68bdbc28ab2e09c783e681d3017e2b
Signed-off-by: Jin Yu <jin.yu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2548
Community-CI: Mellanox Build Bot
Community-CI: Broadcom CI
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Aleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Jin Yu 2020-05-21 00:20:16 +08:00 committed by Tomasz Zawadzki
parent 3d857e3611
commit b7cc4dd7dd
3 changed files with 45 additions and 23 deletions

View File

@ -1479,8 +1479,8 @@ nvmf_ctrlr_async_event_request(struct spdk_nvmf_request *req)
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Async Event Request\n"); SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Async Event Request\n");
/* Only one asynchronous event is supported for now */ /* Four asynchronous events are supported for now */
if (ctrlr->aer_req != NULL) { if (ctrlr->nr_aer_reqs >= NVMF_MAX_ASYNC_EVENTS) {
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "AERL exceeded\n"); SPDK_DEBUGLOG(SPDK_LOG_NVMF, "AERL exceeded\n");
rsp->status.sct = SPDK_NVME_SCT_COMMAND_SPECIFIC; rsp->status.sct = SPDK_NVME_SCT_COMMAND_SPECIFIC;
rsp->status.sc = SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED; rsp->status.sc = SPDK_NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED;
@ -1505,7 +1505,7 @@ nvmf_ctrlr_async_event_request(struct spdk_nvmf_request *req)
sgroup = &req->qpair->group->sgroups[ctrlr->subsys->id]; sgroup = &req->qpair->group->sgroups[ctrlr->subsys->id];
sgroup->io_outstanding--; sgroup->io_outstanding--;
ctrlr->aer_req = req; ctrlr->aer_req[ctrlr->nr_aer_reqs++] = req;
return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS;
} }
@ -1843,6 +1843,7 @@ spdk_nvmf_ctrlr_identify_ctrlr(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvme_c
cdata->mdts = spdk_u32log2(transport->opts.max_io_size / 4096); cdata->mdts = spdk_u32log2(transport->opts.max_io_size / 4096);
cdata->cntlid = ctrlr->cntlid; cdata->cntlid = ctrlr->cntlid;
cdata->ver = ctrlr->vcprop.vs; cdata->ver = ctrlr->vcprop.vs;
cdata->aerl = NVMF_MAX_ASYNC_EVENTS - 1;
cdata->lpa.edlp = 1; cdata->lpa.edlp = 1;
cdata->elpe = 127; cdata->elpe = 127;
cdata->maxcmd = transport->opts.max_queue_depth; cdata->maxcmd = transport->opts.max_queue_depth;
@ -2052,19 +2053,29 @@ static struct spdk_nvmf_request *
nvmf_qpair_abort(struct spdk_nvmf_qpair *qpair, uint16_t cid) nvmf_qpair_abort(struct spdk_nvmf_qpair *qpair, uint16_t cid)
{ {
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr; struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
struct spdk_nvmf_request *req; struct spdk_nvmf_request *req = NULL;
int i;
if (nvmf_qpair_is_admin_queue(qpair)) { if (nvmf_qpair_is_admin_queue(qpair)) {
if (ctrlr->aer_req && ctrlr->aer_req->cmd->nvme_cmd.cid == cid) { for (i = 0; i < ctrlr->nr_aer_reqs; i++) {
if (ctrlr->aer_req[i]->cmd->nvme_cmd.cid == cid) {
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Aborting AER request\n"); SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Aborting AER request\n");
req = ctrlr->aer_req; req = ctrlr->aer_req[i];
ctrlr->aer_req = NULL; ctrlr->aer_req[i] = NULL;
return req; ctrlr->nr_aer_reqs--;
break;
}
}
/* Move the last req to the aborting position for making aer_reqs in continuous */
if (i < ctrlr->nr_aer_reqs) {
ctrlr->aer_req[i] = ctrlr->aer_req[ctrlr->nr_aer_reqs];
ctrlr->aer_req[ctrlr->nr_aer_reqs] = NULL;
} }
} }
/* TODO: track list of outstanding requests in qpair? */ /* TODO: track list of outstanding requests in qpair? */
return NULL; return req;
} }
static void static void
@ -2393,13 +2404,15 @@ nvmf_ctrlr_async_event_nofitification(struct spdk_nvmf_ctrlr *ctrlr,
struct spdk_nvmf_request *req; struct spdk_nvmf_request *req;
struct spdk_nvme_cpl *rsp; struct spdk_nvme_cpl *rsp;
req = ctrlr->aer_req; assert(ctrlr->nr_aer_reqs > 0);
req = ctrlr->aer_req[--ctrlr->nr_aer_reqs];
rsp = &req->rsp->nvme_cpl; rsp = &req->rsp->nvme_cpl;
rsp->cdw0 = event->raw; rsp->cdw0 = event->raw;
spdk_nvmf_request_complete(req); spdk_nvmf_request_complete(req);
ctrlr->aer_req = NULL; ctrlr->aer_req[ctrlr->nr_aer_reqs] = NULL;
return 0; return 0;
} }
@ -2422,7 +2435,7 @@ nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr)
* if an AER is later submitted, this event can be sent as a * if an AER is later submitted, this event can be sent as a
* response. * response.
*/ */
if (!ctrlr->aer_req) { if (ctrlr->nr_aer_reqs == 0) {
if (ctrlr->notice_event.bits.async_event_type == if (ctrlr->notice_event.bits.async_event_type ==
SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE) { SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE) {
return 0; return 0;
@ -2451,7 +2464,7 @@ nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr)
* if an AER is later submitted, this event can be sent as a * if an AER is later submitted, this event can be sent as a
* response. * response.
*/ */
if (!ctrlr->aer_req) { if (ctrlr->nr_aer_reqs == 0) {
if (ctrlr->reservation_event.bits.async_event_type == if (ctrlr->reservation_event.bits.async_event_type ==
SPDK_NVME_ASYNC_EVENT_TYPE_IO) { SPDK_NVME_ASYNC_EVENT_TYPE_IO) {
return; return;
@ -2468,26 +2481,31 @@ void
nvmf_qpair_free_aer(struct spdk_nvmf_qpair *qpair) nvmf_qpair_free_aer(struct spdk_nvmf_qpair *qpair)
{ {
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr; struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
int i;
if (!nvmf_qpair_is_admin_queue(qpair)) { if (!nvmf_qpair_is_admin_queue(qpair)) {
return; return;
} }
if (ctrlr->aer_req != NULL) { for (i = 0; i < ctrlr->nr_aer_reqs; i++) {
spdk_nvmf_request_free(ctrlr->aer_req); spdk_nvmf_request_free(ctrlr->aer_req[i]);
ctrlr->aer_req = NULL; ctrlr->aer_req[i] = NULL;
} }
ctrlr->nr_aer_reqs = 0;
} }
void void
nvmf_ctrlr_abort_aer(struct spdk_nvmf_ctrlr *ctrlr) nvmf_ctrlr_abort_aer(struct spdk_nvmf_ctrlr *ctrlr)
{ {
if (!ctrlr->aer_req) { int i;
return;
for (i = 0; i < ctrlr->nr_aer_reqs; i++) {
spdk_nvmf_request_complete(ctrlr->aer_req[i]);
ctrlr->aer_req[i] = NULL;
} }
spdk_nvmf_request_complete(ctrlr->aer_req); ctrlr->nr_aer_reqs = 0;
ctrlr->aer_req = NULL;
} }
static void static void

View File

@ -47,6 +47,8 @@
#include "spdk/util.h" #include "spdk/util.h"
#include "spdk/thread.h" #include "spdk/thread.h"
#define NVMF_MAX_ASYNC_EVENTS (4)
enum spdk_nvmf_subsystem_state { enum spdk_nvmf_subsystem_state {
SPDK_NVMF_SUBSYSTEM_INACTIVE = 0, SPDK_NVMF_SUBSYSTEM_INACTIVE = 0,
SPDK_NVMF_SUBSYSTEM_ACTIVATING, SPDK_NVMF_SUBSYSTEM_ACTIVATING,
@ -205,9 +207,10 @@ struct spdk_nvmf_ctrlr {
struct spdk_thread *thread; struct spdk_thread *thread;
struct spdk_bit_array *qpair_mask; struct spdk_bit_array *qpair_mask;
struct spdk_nvmf_request *aer_req; struct spdk_nvmf_request *aer_req[NVMF_MAX_ASYNC_EVENTS];
union spdk_nvme_async_event_completion notice_event; union spdk_nvme_async_event_completion notice_event;
union spdk_nvme_async_event_completion reservation_event; union spdk_nvme_async_event_completion reservation_event;
uint8_t nr_aer_reqs;
struct spdk_uuid hostid; struct spdk_uuid hostid;
uint16_t changed_ns_list_count; uint16_t changed_ns_list_count;

View File

@ -1300,7 +1300,8 @@ test_reservation_notification_log_page(void)
ctrlr.num_avail_log_pages = 0; ctrlr.num_avail_log_pages = 0;
req.cmd = &cmd; req.cmd = &cmd;
req.rsp = &rsp; req.rsp = &rsp;
ctrlr.aer_req = &req; ctrlr.aer_req[0] = &req;
ctrlr.nr_aer_reqs = 1;
req.qpair = &qpair; req.qpair = &qpair;
TAILQ_INIT(&qpair.outstanding); TAILQ_INIT(&qpair.outstanding);
qpair.ctrlr = NULL; qpair.ctrlr = NULL;