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");
/* Only one asynchronous event is supported for now */
if (ctrlr->aer_req != NULL) {
/* Four asynchronous events are supported for now */
if (ctrlr->nr_aer_reqs >= NVMF_MAX_ASYNC_EVENTS) {
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "AERL exceeded\n");
rsp->status.sct = SPDK_NVME_SCT_COMMAND_SPECIFIC;
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->io_outstanding--;
ctrlr->aer_req = req;
ctrlr->aer_req[ctrlr->nr_aer_reqs++] = req;
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->cntlid = ctrlr->cntlid;
cdata->ver = ctrlr->vcprop.vs;
cdata->aerl = NVMF_MAX_ASYNC_EVENTS - 1;
cdata->lpa.edlp = 1;
cdata->elpe = 127;
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)
{
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 (ctrlr->aer_req && ctrlr->aer_req->cmd->nvme_cmd.cid == cid) {
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "Aborting AER request\n");
req = ctrlr->aer_req;
ctrlr->aer_req = NULL;
return req;
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");
req = ctrlr->aer_req[i];
ctrlr->aer_req[i] = NULL;
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? */
return NULL;
return req;
}
static void
@ -2393,13 +2404,15 @@ nvmf_ctrlr_async_event_nofitification(struct spdk_nvmf_ctrlr *ctrlr,
struct spdk_nvmf_request *req;
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->cdw0 = event->raw;
spdk_nvmf_request_complete(req);
ctrlr->aer_req = NULL;
ctrlr->aer_req[ctrlr->nr_aer_reqs] = NULL;
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
* response.
*/
if (!ctrlr->aer_req) {
if (ctrlr->nr_aer_reqs == 0) {
if (ctrlr->notice_event.bits.async_event_type ==
SPDK_NVME_ASYNC_EVENT_TYPE_NOTICE) {
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
* response.
*/
if (!ctrlr->aer_req) {
if (ctrlr->nr_aer_reqs == 0) {
if (ctrlr->reservation_event.bits.async_event_type ==
SPDK_NVME_ASYNC_EVENT_TYPE_IO) {
return;
@ -2468,26 +2481,31 @@ void
nvmf_qpair_free_aer(struct spdk_nvmf_qpair *qpair)
{
struct spdk_nvmf_ctrlr *ctrlr = qpair->ctrlr;
int i;
if (!nvmf_qpair_is_admin_queue(qpair)) {
return;
}
if (ctrlr->aer_req != NULL) {
spdk_nvmf_request_free(ctrlr->aer_req);
ctrlr->aer_req = NULL;
for (i = 0; i < ctrlr->nr_aer_reqs; i++) {
spdk_nvmf_request_free(ctrlr->aer_req[i]);
ctrlr->aer_req[i] = NULL;
}
ctrlr->nr_aer_reqs = 0;
}
void
nvmf_ctrlr_abort_aer(struct spdk_nvmf_ctrlr *ctrlr)
{
if (!ctrlr->aer_req) {
return;
int i;
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->aer_req = NULL;
ctrlr->nr_aer_reqs = 0;
}
static void

View File

@ -47,6 +47,8 @@
#include "spdk/util.h"
#include "spdk/thread.h"
#define NVMF_MAX_ASYNC_EVENTS (4)
enum spdk_nvmf_subsystem_state {
SPDK_NVMF_SUBSYSTEM_INACTIVE = 0,
SPDK_NVMF_SUBSYSTEM_ACTIVATING,
@ -205,9 +207,10 @@ struct spdk_nvmf_ctrlr {
struct spdk_thread *thread;
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 reservation_event;
uint8_t nr_aer_reqs;
struct spdk_uuid hostid;
uint16_t changed_ns_list_count;

View File

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