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:
parent
3d857e3611
commit
b7cc4dd7dd
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user