nvmf: add asynchronous event for reservation notificaiton

Now Host can get an asynchronous event notification when
registrants were unregistered/preempted or reservation was
released from the associate namespace, Host can send
get log page to clear related log pages and reservation
report to get the full overview of current reservation
configuration.

Change-Id: Idc57c19812490c7536503308989871515e9f2361
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/439935
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Changpeng Liu 2019-03-02 21:43:22 -05:00 committed by Jim Harris
parent dc61452d6e
commit 4fa486a1e3
3 changed files with 53 additions and 0 deletions

View File

@ -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

View File

@ -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,

View File

@ -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)
{