From fb7ad4ac66b8c353331b397ba15d204c4ed6257c Mon Sep 17 00:00:00 2001 From: Ziye Yang Date: Thu, 1 Jun 2017 15:30:46 +0800 Subject: [PATCH] nvme_rdma: Support getting all log page entries Preivously, we can only get part of the log page entries due to the limitation of buffer. With this patch, we can get all. Change-Id: I81b8afc73c108dac65d1ff5fe8d03bda41fa29a1 Signed-off-by: Ziye Yang Reviewed-on: https://review.gerrithub.io/363323 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Ben Walker --- lib/nvme/nvme_rdma.c | 75 +++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/lib/nvme/nvme_rdma.c b/lib/nvme/nvme_rdma.c index 2c67ed333..efa1efca8 100644 --- a/lib/nvme/nvme_rdma.c +++ b/lib/nvme/nvme_rdma.c @@ -1058,13 +1058,13 @@ nvme_rdma_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr) static int nvme_fabrics_get_log_discovery_page(struct spdk_nvme_ctrlr *ctrlr, - void *log_page, uint32_t size) + void *log_page, uint32_t size, uint64_t offset) { struct nvme_completion_poll_status status; int rc; status.done = false; - rc = spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_DISCOVERY, 0, log_page, size, 0, + rc = spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_DISCOVERY, 0, log_page, size, offset, nvme_completion_poll_cb, &status); if (rc < 0) { return -1; @@ -1143,10 +1143,13 @@ nvme_rdma_ctrlr_scan(const struct spdk_nvme_transport_id *discovery_trid, struct spdk_nvme_ctrlr_opts discovery_opts; struct spdk_nvme_ctrlr *discovery_ctrlr; struct spdk_nvmf_discovery_log_page *log_page; + struct spdk_nvmf_discovery_log_page_entry *log_page_entry; union spdk_nvme_cc_register cc; char buffer[4096]; int rc; - uint64_t i, numrec, buffer_max_entries; + uint64_t i, numrec, buffer_max_entries_first, buffer_max_entries, log_page_offset = 0; + uint64_t remaining_num_rec = 0; + struct nvme_completion_poll_status status; spdk_nvme_ctrlr_opts_set_defaults(&discovery_opts); /* For discovery_ctrlr set the timeout to 0 */ @@ -1171,33 +1174,55 @@ nvme_rdma_ctrlr_scan(const struct spdk_nvme_transport_id *discovery_trid, return -1; } - rc = nvme_fabrics_get_log_discovery_page(discovery_ctrlr, buffer, sizeof(buffer)); - if (rc < 0) { - SPDK_TRACELOG(SPDK_TRACE_NVME, "nvme_fabrics_get_log_discovery_page error\n"); - nvme_ctrlr_destruct(discovery_ctrlr); - /* It is not a discovery_ctrlr info and try to directly connect it */ - rc = nvme_ctrlr_probe(discovery_trid, NULL, probe_cb, cb_ctx); + /* get the cdata info */ + status.done = false; + rc = nvme_ctrlr_cmd_identify_controller(discovery_ctrlr, &discovery_ctrlr->cdata, + nvme_completion_poll_cb, &status); + if (rc != 0) { + SPDK_ERRLOG("Failed to identify cdata\n"); return rc; } - log_page = (struct spdk_nvmf_discovery_log_page *)buffer; - - /* - * For now, only support retrieving one buffer of discovery entries. - * This could be extended to call Get Log Page multiple times as needed. - */ - buffer_max_entries = (sizeof(buffer) - offsetof(struct spdk_nvmf_discovery_log_page, entries[0])) / - sizeof(struct spdk_nvmf_discovery_log_page_entry); - numrec = spdk_min(log_page->numrec, buffer_max_entries); - if (numrec != log_page->numrec) { - SPDK_WARNLOG("Discovery service returned %" PRIu64 " entries," - "but buffer can only hold %" PRIu64 "\n", - log_page->numrec, numrec); + while (status.done == false) { + spdk_nvme_qpair_process_completions(discovery_ctrlr->adminq, 0); + } + if (spdk_nvme_cpl_is_error(&status.cpl)) { + SPDK_ERRLOG("nvme_identify_controller failed!\n"); + return -ENXIO; } - for (i = 0; i < numrec; i++) { - nvme_rdma_discovery_probe(&log_page->entries[i], cb_ctx, probe_cb); - } + buffer_max_entries_first = (sizeof(buffer) - offsetof(struct spdk_nvmf_discovery_log_page, + entries[0])) / + sizeof(struct spdk_nvmf_discovery_log_page_entry); + buffer_max_entries = sizeof(buffer) / sizeof(struct spdk_nvmf_discovery_log_page_entry); + do { + rc = nvme_fabrics_get_log_discovery_page(discovery_ctrlr, buffer, sizeof(buffer), log_page_offset); + if (rc < 0) { + SPDK_TRACELOG(SPDK_TRACE_NVME, "nvme_fabrics_get_log_discovery_page error\n"); + nvme_ctrlr_destruct(discovery_ctrlr); + /* It is not a discovery_ctrlr info and try to directly connect it */ + rc = nvme_ctrlr_probe(discovery_trid, NULL, probe_cb, cb_ctx); + return rc; + } + + if (!remaining_num_rec) { + log_page = (struct spdk_nvmf_discovery_log_page *)buffer; + remaining_num_rec = log_page->numrec; + log_page_offset = offsetof(struct spdk_nvmf_discovery_log_page, entries[0]); + log_page_entry = &log_page->entries[0]; + numrec = spdk_min(remaining_num_rec, buffer_max_entries_first); + } else { + numrec = spdk_min(remaining_num_rec, buffer_max_entries); + log_page_entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer; + } + + + for (i = 0; i < numrec; i++) { + nvme_rdma_discovery_probe(log_page_entry++, cb_ctx, probe_cb); + } + remaining_num_rec -= numrec; + log_page_offset += numrec * sizeof(struct spdk_nvmf_discovery_log_page_entry); + } while (remaining_num_rec != 0); nvme_ctrlr_destruct(discovery_ctrlr); return 0;