lib/nvme: add two async API for Directive Send and Directive Receive.

Add two async API for Directive Send and Directive Receive.
	spdk_nvme_ctrlr_cmd_directive_send;
	spdk_nvme_ctrlr_cmd_directive_receive;

Signed-off-by: sunshihao <sunshihao@huawei.com>
Change-Id: Icb6974f74902df1512a5ffa9835188132634291b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5803
Community-CI: Broadcom CI
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
sunshihao520 2021-01-20 14:53:12 +08:00 committed by Jim Harris
parent e69af13dea
commit 5fba455d3e
7 changed files with 180 additions and 0 deletions

View File

@ -42,6 +42,9 @@ Updated DPDK submodule to DPDK 20.11.
Directives support was added to the NVMe driver.
Two async APIs 'spdk_nvme_ctrlr_cmd_directive_receive' and 'spdk_nvme_ctrlr_cmd_directive_send'
are added for Directive Send and Directive Receive command, respectively.
Added a new function `spdk_nvme_ctrlr_reset_subsystem` to perform a NVMe
subsystem reset. Note: The NVMf target does not support the subsystem reset yet.
Add a new function 'spdk_nvme_bytes_to_numd' to transfer bytes to number of

View File

@ -1912,6 +1912,62 @@ int spdk_nvme_ctrlr_security_receive(struct spdk_nvme_ctrlr *ctrlr, uint8_t secp
int spdk_nvme_ctrlr_security_send(struct spdk_nvme_ctrlr *ctrlr, uint8_t secp,
uint16_t spsp, uint8_t nssf, void *payload, size_t size);
/**
* Receive data related to a specific Directive Type from the controller.
*
* This function is thread safe and can be called at any point after spdk_nvme_probe().
*
* Call spdk_nvme_ctrlr_process_admin_completions() to poll for completion of
* commands submitted through this function.
*
* \param ctrlr NVMe controller to use for directive receive command submission.
* \param nsid Specific Namespace Identifier.
* \param doper Directive Operation defined in nvme_spec.h.
* \param dtype Directive Type defined in nvme_spec.h.
* \param dspec Directive Specific defined in nvme_spec.h.
* \param payload The pointer to the payload buffer.
* \param payload_size The size of payload buffer.
* \param cdw12 Command dword 12.
* \param cdw13 Command dword 13.
* \param cb_fn Callback function to invoke when the command has been completed.
* \param cb_arg Argument to pass to the callback function.
*
* \return 0 if successfully submitted, negated errno if resources could not be allocated
* for this request.
*/
int spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
/**
* Send data related to a specific Directive Type to the controller.
*
* This function is thread safe and can be called at any point after spdk_nvme_probe().
*
* Call spdk_nvme_ctrlr_process_admin_completions() to poll for completion of
* commands submitted through this function.
*
* \param ctrlr NVMe controller to use for directive send command submission.
* \param nsid Specific Namespace Identifier.
* \param doper Directive Operation defined in nvme_spec.h.
* \param dtype Directive Type defined in nvme_spec.h.
* \param dspec Directive Specific defined in nvme_spec.h.
* \param payload The pointer to the payload buffer.
* \param payload_size The size of payload buffer.
* \param cdw12 Command dword 12.
* \param cdw13 Command dword 13.
* \param cb_fn Callback function to invoke when the command has been completed.
* \param cb_arg Argument to pass to the callback function.
*
* \return 0 if successfully submitted, negated errno if resources could not be allocated
* for this request.
*/
int spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
/**
* Get supported flags of the controller.
*

View File

@ -1570,6 +1570,10 @@ nvme_ctrlr_identify_done(void *arg, const struct spdk_nvme_cpl *cpl)
ctrlr->flags |= SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED;
}
if (ctrlr->cdata.oacs.directives) {
ctrlr->flags |= SPDK_NVME_CTRLR_DIRECTIVES_SUPPORTED;
}
SPDK_DEBUGLOG(nvme, "fuses compare and write: %d\n", ctrlr->cdata.fuses.compare_and_write);
if (ctrlr->cdata.fuses.compare_and_write) {
ctrlr->flags |= SPDK_NVME_CTRLR_COMPARE_AND_WRITE_SUPPORTED;

View File

@ -965,3 +965,59 @@ nvme_ctrlr_cmd_sanitize(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
return rc;
}
static int
nvme_ctrlr_cmd_directive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
uint16_t opc_type, bool host_to_ctrlr)
{
struct nvme_request *req = NULL;
struct spdk_nvme_cmd *cmd = NULL;
int rc;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size,
cb_fn, cb_arg, host_to_ctrlr);
if (req == NULL) {
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return -ENOMEM;
}
cmd = &req->cmd;
cmd->opc = opc_type;
cmd->nsid = nsid;
cmd->cdw10 = (payload_size >> 2) - 1;
cmd->cdw11_bits.directive.doper = doper;
cmd->cdw11_bits.directive.dtype = dtype;
cmd->cdw11_bits.directive.dspec = dspec;
cmd->cdw12 = cdw12;
cmd->cdw13 = cdw13;
rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return rc;
}
int
spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
return nvme_ctrlr_cmd_directive(ctrlr, nsid, doper, dtype, dspec,
payload, payload_size, cdw12, cdw13, cb_fn, cb_arg,
SPDK_NVME_OPC_DIRECTIVE_SEND, true);
}
int
spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
return nvme_ctrlr_cmd_directive(ctrlr, nsid, doper, dtype, dspec,
payload, payload_size, cdw12, cdw13, cb_fn, cb_arg,
SPDK_NVME_OPC_DIRECTIVE_RECEIVE, false);
}

View File

@ -74,6 +74,8 @@
spdk_nvme_ctrlr_cmd_security_send;
spdk_nvme_ctrlr_security_receive;
spdk_nvme_ctrlr_security_send;
spdk_nvme_ctrlr_cmd_directive_receive;
spdk_nvme_ctrlr_cmd_directive_send;
spdk_nvme_ctrlr_get_flags;
spdk_nvme_ctrlr_attach_ns;
spdk_nvme_ctrlr_detach_ns;

View File

@ -439,6 +439,24 @@ nvme_ctrlr_cmd_format(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, struct spdk_
return 0;
}
int
spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
return 0;
}
int
spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
uint32_t doper, uint32_t dtype, uint32_t dspec,
void *payload, uint32_t payload_size, uint32_t cdw12,
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
return 0;
}
int
nvme_ctrlr_cmd_fw_commit(struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_fw_commit *fw_commit,
spdk_nvme_cmd_cb cb_fn, void *cb_arg)

View File

@ -61,6 +61,7 @@ uint64_t PRP_ENTRY_2 = 4096;
uint32_t format_nvme_nsid = 1;
uint32_t sanitize_nvme_nsid = 1;
uint32_t expected_host_id_size = 0xFF;
uint32_t directive_nsid = 1;
uint32_t expected_feature_ns = 2;
uint32_t expected_feature_cdw10 = SPDK_NVME_FEAT_LBA_RANGE_TYPE;
@ -325,6 +326,18 @@ static void verify_nvme_sanitize(struct nvme_request *req)
CU_ASSERT(req->cmd.nsid == sanitize_nvme_nsid);
}
static void verify_directive_receive(struct nvme_request *req)
{
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_DIRECTIVE_RECEIVE);
CU_ASSERT(req->cmd.nsid == directive_nsid);
}
static void verify_directive_send(struct nvme_request *req)
{
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_DIRECTIVE_SEND);
CU_ASSERT(req->cmd.nsid == directive_nsid);
}
struct nvme_request *
nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair, void *buffer, uint32_t payload_size,
spdk_nvme_cmd_cb cb_fn, void *cb_arg, bool host_to_controller)
@ -723,6 +736,33 @@ test_sanitize(void)
}
static void
test_directive_receive(void)
{
DECLARE_AND_CONSTRUCT_CTRLR();
verify_fn = verify_directive_receive;
spdk_nvme_ctrlr_cmd_directive_receive(&ctrlr, directive_nsid, 0, 0, 0, NULL, 0,
0, 0, NULL, NULL);
}
static void
test_directive_send(void)
{
DECLARE_AND_CONSTRUCT_CTRLR();
verify_fn = verify_directive_send;
spdk_nvme_ctrlr_cmd_directive_send(&ctrlr, directive_nsid, 0, 0, 0, NULL, 0,
0, 0, NULL, NULL);
}
static void
test_directive(void)
{
test_directive_receive();
test_directive_send();
}
int main(int argc, char **argv)
{
CU_pSuite suite = NULL;
@ -752,6 +792,7 @@ int main(int argc, char **argv)
CU_ADD_TEST(suite, test_fw_commit);
CU_ADD_TEST(suite, test_fw_image_download);
CU_ADD_TEST(suite, test_sanitize);
CU_ADD_TEST(suite, test_directive);
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();