diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 02458ffdfb..abd9f8e0cb 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -1235,6 +1235,13 @@ spdk_nvmf_ctrlr_async_event_request(struct spdk_nvmf_request *req) return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } + if (ctrlr->reservation_event.bits.async_event_type == + SPDK_NVME_ASYNC_EVENT_TYPE_IO) { + rsp->cdw0 = ctrlr->reservation_event.raw; + ctrlr->reservation_event.raw = 0; + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + ctrlr->aer_req = req; return SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS; } @@ -2106,6 +2113,43 @@ spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr) return 0; } +void +spdk_nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr) +{ + struct spdk_nvmf_request *req; + struct spdk_nvme_cpl *rsp; + union spdk_nvme_async_event_completion event = {0}; + + if (!ctrlr->num_avail_log_pages) { + return; + } + event.bits.async_event_type = SPDK_NVME_ASYNC_EVENT_TYPE_IO; + event.bits.async_event_info = SPDK_NVME_ASYNC_EVENT_RESERVATION_LOG_AVAIL; + event.bits.log_page_identifier = SPDK_NVME_LOG_RESERVATION_NOTIFICATION; + + /* If there is no outstanding AER request, queue the event. Then + * if an AER is later submitted, this event can be sent as a + * response. + */ + if (!ctrlr->aer_req) { + if (ctrlr->reservation_event.bits.async_event_type == + SPDK_NVME_ASYNC_EVENT_TYPE_IO) { + return; + } + + ctrlr->reservation_event.raw = event.raw; + return; + } + + req = ctrlr->aer_req; + rsp = &req->rsp->nvme_cpl; + + rsp->cdw0 = event.raw; + + spdk_nvmf_request_complete(req); + ctrlr->aer_req = NULL; +} + void spdk_nvmf_qpair_free_aer(struct spdk_nvmf_qpair *qpair) { @@ -2152,6 +2196,8 @@ _nvmf_ctrlr_add_reservation_log(void *ctx) log->log.log_page_count = ctrlr->log_page_count; log->log.num_avail_log_pages = ctrlr->num_avail_log_pages++; TAILQ_INSERT_TAIL(&ctrlr->log_head, log, link); + + spdk_nvmf_ctrlr_async_event_reservation_notification(ctrlr); } void diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 252e3dc828..219ddb8134 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -273,6 +273,7 @@ struct spdk_nvmf_ctrlr { struct spdk_nvmf_request *aer_req; union spdk_nvme_async_event_completion notice_event; + union spdk_nvme_async_event_completion reservation_event; struct spdk_uuid hostid; uint16_t changed_ns_list_count; @@ -371,6 +372,7 @@ void spdk_nvmf_subsystem_remove_ctrlr(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *spdk_nvmf_subsystem_get_ctrlr(struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid); int spdk_nvmf_ctrlr_async_event_ns_notice(struct spdk_nvmf_ctrlr *ctrlr); +void spdk_nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr); void spdk_nvmf_ns_reservation_request(void *ctx); void spdk_nvmf_ctrlr_reservation_notice_log(struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvmf_ns *ns, diff --git a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c index 4e608a3527..8ca3ddc65f 100644 --- a/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c +++ b/test/unit/lib/nvmf/subsystem.c/subsystem_ut.c @@ -463,6 +463,11 @@ static struct spdk_nvmf_ctrlr g_ctrlr1_A, g_ctrlr2_A, g_ctrlr_B, g_ctrlr_C; static struct spdk_nvmf_ns g_ns; struct spdk_nvmf_subsystem_pg_ns_info g_ns_info; +void +spdk_nvmf_ctrlr_async_event_reservation_notification(struct spdk_nvmf_ctrlr *ctrlr) +{ +} + static void ut_reservation_init(void) {