nvme: Add transport controller ready step
This step allows custom transports to perform extra actions or checks at controller initialization and fail initialization if required. Signed-off-by: Evgeniy Kochetov <evgeniik@nvidia.com> Change-Id: Ic7cadae5398a35903917ceace3828f4371be63a3 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12631 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
44cbea402e
commit
3dd0bc9e09
@ -3954,6 +3954,8 @@ struct spdk_nvme_transport_ops {
|
|||||||
int (*ctrlr_get_memory_domains)(const struct spdk_nvme_ctrlr *ctrlr,
|
int (*ctrlr_get_memory_domains)(const struct spdk_nvme_ctrlr *ctrlr,
|
||||||
struct spdk_memory_domain **domains,
|
struct spdk_memory_domain **domains,
|
||||||
int array_size);
|
int array_size);
|
||||||
|
|
||||||
|
int (*ctrlr_ready)(struct spdk_nvme_ctrlr *ctrlr);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1395,6 +1395,8 @@ nvme_ctrlr_state_string(enum nvme_ctrlr_state state)
|
|||||||
return "set host ID";
|
return "set host ID";
|
||||||
case NVME_CTRLR_STATE_WAIT_FOR_HOST_ID:
|
case NVME_CTRLR_STATE_WAIT_FOR_HOST_ID:
|
||||||
return "wait for set host ID";
|
return "wait for set host ID";
|
||||||
|
case NVME_CTRLR_STATE_TRANSPORT_READY:
|
||||||
|
return "transport ready";
|
||||||
case NVME_CTRLR_STATE_READY:
|
case NVME_CTRLR_STATE_READY:
|
||||||
return "ready";
|
return "ready";
|
||||||
case NVME_CTRLR_STATE_ERROR:
|
case NVME_CTRLR_STATE_ERROR:
|
||||||
@ -2906,7 +2908,7 @@ nvme_ctrlr_set_host_id_done(void *arg, const struct spdk_nvme_cpl *cpl)
|
|||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "Set Features - Host ID was successful\n");
|
NVME_CTRLR_DEBUGLOG(ctrlr, "Set Features - Host ID was successful\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_READY, NVME_TIMEOUT_INFINITE);
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_TRANSPORT_READY, ctrlr->opts.admin_timeout_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -2922,7 +2924,7 @@ nvme_ctrlr_set_host_id(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
* Set Features - Host Identifier after Connect, so we don't need to do anything here.
|
* Set Features - Host Identifier after Connect, so we don't need to do anything here.
|
||||||
*/
|
*/
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "NVMe-oF transport - not sending Set Features - Host ID\n");
|
NVME_CTRLR_DEBUGLOG(ctrlr, "NVMe-oF transport - not sending Set Features - Host ID\n");
|
||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_READY, NVME_TIMEOUT_INFINITE);
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_TRANSPORT_READY, ctrlr->opts.admin_timeout_ms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2939,7 +2941,7 @@ nvme_ctrlr_set_host_id(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
/* If the user specified an all-zeroes host identifier, don't send the command. */
|
/* If the user specified an all-zeroes host identifier, don't send the command. */
|
||||||
if (spdk_mem_all_zero(host_id, host_id_size)) {
|
if (spdk_mem_all_zero(host_id, host_id_size)) {
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "User did not specify host ID - not sending Set Features - Host ID\n");
|
NVME_CTRLR_DEBUGLOG(ctrlr, "User did not specify host ID - not sending Set Features - Host ID\n");
|
||||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_READY, NVME_TIMEOUT_INFINITE);
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_TRANSPORT_READY, ctrlr->opts.admin_timeout_ms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3948,6 +3950,16 @@ nvme_ctrlr_process_init(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
rc = nvme_ctrlr_set_host_id(ctrlr);
|
rc = nvme_ctrlr_set_host_id(ctrlr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NVME_CTRLR_STATE_TRANSPORT_READY:
|
||||||
|
rc = nvme_transport_ctrlr_ready(ctrlr);
|
||||||
|
if (rc) {
|
||||||
|
NVME_CTRLR_ERRLOG(ctrlr, "Transport controller ready step failed: rc %d\n", rc);
|
||||||
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_ERROR, NVME_TIMEOUT_INFINITE);
|
||||||
|
} else {
|
||||||
|
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_READY, NVME_TIMEOUT_INFINITE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case NVME_CTRLR_STATE_READY:
|
case NVME_CTRLR_STATE_READY:
|
||||||
NVME_CTRLR_DEBUGLOG(ctrlr, "Ctrlr already in ready state\n");
|
NVME_CTRLR_DEBUGLOG(ctrlr, "Ctrlr already in ready state\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -775,6 +775,11 @@ enum nvme_ctrlr_state {
|
|||||||
*/
|
*/
|
||||||
NVME_CTRLR_STATE_WAIT_FOR_HOST_ID,
|
NVME_CTRLR_STATE_WAIT_FOR_HOST_ID,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Let transport layer do its part of initialization.
|
||||||
|
*/
|
||||||
|
NVME_CTRLR_STATE_TRANSPORT_READY,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller initialization has completed and the controller is ready.
|
* Controller initialization has completed and the controller is ready.
|
||||||
*/
|
*/
|
||||||
@ -1470,6 +1475,7 @@ struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_tr
|
|||||||
int nvme_transport_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr);
|
int nvme_transport_ctrlr_destruct(struct spdk_nvme_ctrlr *ctrlr);
|
||||||
int nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx, bool direct_connect);
|
int nvme_transport_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx, bool direct_connect);
|
||||||
int nvme_transport_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr);
|
int nvme_transport_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr);
|
||||||
|
int nvme_transport_ctrlr_ready(struct spdk_nvme_ctrlr *ctrlr);
|
||||||
int nvme_transport_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value);
|
int nvme_transport_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value);
|
||||||
int nvme_transport_ctrlr_set_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value);
|
int nvme_transport_ctrlr_set_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value);
|
||||||
int nvme_transport_ctrlr_get_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value);
|
int nvme_transport_ctrlr_get_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value);
|
||||||
|
@ -141,6 +141,19 @@ nvme_transport_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr)
|
|||||||
return transport->ops.ctrlr_enable(ctrlr);
|
return transport->ops.ctrlr_enable(ctrlr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nvme_transport_ctrlr_ready(struct spdk_nvme_ctrlr *ctrlr)
|
||||||
|
{
|
||||||
|
const struct spdk_nvme_transport *transport = nvme_get_transport(ctrlr->trid.trstring);
|
||||||
|
|
||||||
|
assert(transport != NULL);
|
||||||
|
if (transport->ops.ctrlr_ready) {
|
||||||
|
return transport->ops.ctrlr_ready(ctrlr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nvme_transport_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value)
|
nvme_transport_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value)
|
||||||
{
|
{
|
||||||
|
@ -65,6 +65,14 @@ nvme_transport_ctrlr_get_memory_domains(const struct spdk_nvme_ctrlr *ctrlr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_RETURN_MOCK(nvme_transport_ctrlr_ready, int);
|
||||||
|
int
|
||||||
|
nvme_transport_ctrlr_ready(struct spdk_nvme_ctrlr *ctrlr)
|
||||||
|
{
|
||||||
|
HANDLE_RETURN_MOCK(nvme_transport_ctrlr_ready);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_transport_id *trid,
|
struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_transport_id *trid,
|
||||||
const struct spdk_nvme_ctrlr_opts *opts,
|
const struct spdk_nvme_ctrlr_opts *opts,
|
||||||
void *devhandle)
|
void *devhandle)
|
||||||
@ -3276,6 +3284,24 @@ test_nvme_ctrlr_get_memory_domains(void)
|
|||||||
MOCK_CLEAR(nvme_transport_ctrlr_get_memory_domains);
|
MOCK_CLEAR(nvme_transport_ctrlr_get_memory_domains);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nvme_transport_ctrlr_ready(void)
|
||||||
|
{
|
||||||
|
DECLARE_AND_CONSTRUCT_CTRLR();
|
||||||
|
|
||||||
|
/* Transport init succeeded */
|
||||||
|
ctrlr.state = NVME_CTRLR_STATE_TRANSPORT_READY;
|
||||||
|
SPDK_CU_ASSERT_FATAL(nvme_ctrlr_process_init(&ctrlr) == 0);
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_READY);
|
||||||
|
|
||||||
|
/* Transport init failed */
|
||||||
|
ctrlr.state = NVME_CTRLR_STATE_TRANSPORT_READY;
|
||||||
|
MOCK_SET(nvme_transport_ctrlr_ready, -1);
|
||||||
|
SPDK_CU_ASSERT_FATAL(nvme_ctrlr_process_init(&ctrlr) == -1);
|
||||||
|
CU_ASSERT(ctrlr.state == NVME_CTRLR_STATE_ERROR);
|
||||||
|
MOCK_CLEAR(nvme_transport_ctrlr_ready);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -3331,6 +3357,7 @@ main(int argc, char **argv)
|
|||||||
CU_ADD_TEST(suite, test_nvme_ctrlr_parse_ana_log_page);
|
CU_ADD_TEST(suite, test_nvme_ctrlr_parse_ana_log_page);
|
||||||
CU_ADD_TEST(suite, test_nvme_ctrlr_ana_resize);
|
CU_ADD_TEST(suite, test_nvme_ctrlr_ana_resize);
|
||||||
CU_ADD_TEST(suite, test_nvme_ctrlr_get_memory_domains);
|
CU_ADD_TEST(suite, test_nvme_ctrlr_get_memory_domains);
|
||||||
|
CU_ADD_TEST(suite, test_nvme_transport_ctrlr_ready);
|
||||||
|
|
||||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||||
CU_basic_run_tests();
|
CU_basic_run_tests();
|
||||||
|
Loading…
Reference in New Issue
Block a user