nvme: add support for write uncorrectable command

Change-Id: I9fb7a998f7c13ce53cba630a895e8e11cf5f4a1c
Signed-off-by: Benjamin Saunders <bsaunders@google.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/467559
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Benjamin Saunders 2019-09-05 17:01:58 -07:00 committed by Jim Harris
parent 6956b0ec1e
commit 6bcd3588d1
5 changed files with 86 additions and 0 deletions

View File

@ -60,6 +60,8 @@ can support weighted round robin arbitration feature with submission queue.
Added `arbitration_burst` option for arbitration feature, and added three Added `arbitration_burst` option for arbitration feature, and added three
`low/medium/high_priority_weight` options for weighted round robin arbitration. `low/medium/high_priority_weight` options for weighted round robin arbitration.
Added `spdk_nvme_ns_cmd_write_uncorrectable`.
### iSCSI ### iSCSI
Portals may no longer be associated with a cpumask. The scheduling of Portals may no longer be associated with a cpumask. The scheduling of

View File

@ -1814,6 +1814,7 @@ enum spdk_nvme_ns_flags {
SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED = 0x20, /**< The extended lba format is supported, SPDK_NVME_NS_EXTENDED_LBA_SUPPORTED = 0x20, /**< The extended lba format is supported,
metadata is transferred as a contiguous metadata is transferred as a contiguous
part of the logical block that it is associated with */ part of the logical block that it is associated with */
SPDK_NVME_NS_WRITE_UNCORRECTABLE_SUPPORTED = 0x40, /**< The write uncorrectable command is supported */
}; };
/** /**
@ -1987,6 +1988,27 @@ int spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpai
spdk_nvme_cmd_cb cb_fn, void *cb_arg, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
uint32_t io_flags); uint32_t io_flags);
/**
* Submit a write uncorrectable I/O to the specified NVMe namespace.
*
* The command is submitted to a qpair allocated by spdk_nvme_ctrlr_alloc_io_qpair().
* The user must ensure that only one thread submits I/O on a given qpair at any
* given time.
*
* \param ns NVMe namespace to submit the write uncorrectable I/O.
* \param qpair I/O queue pair to submit the request.
* \param lba Starting LBA for this command.
* \param lba_count Length (in sectors) for the write uncorrectable operation.
* \param cb_fn Callback function to invoke when the I/O is completed.
* \param cb_arg Argument to pass to the callback function.
*
* \return 0 if successfully submitted, negated errno if an nvme_request structure
* cannot be allocated for the I/O request.
*/
int spdk_nvme_ns_cmd_write_uncorrectable(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
spdk_nvme_cmd_cb cb_fn, void *cb_arg);
/** /**
* \brief Submits a read I/O to the specified NVMe namespace. * \brief Submits a read I/O to the specified NVMe namespace.
* *

View File

@ -91,6 +91,10 @@ nvme_ns_set_identify_data(struct spdk_nvme_ns *ns)
ns->flags |= SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED; ns->flags |= SPDK_NVME_NS_WRITE_ZEROES_SUPPORTED;
} }
if (ns->ctrlr->cdata.oncs.write_unc) {
ns->flags |= SPDK_NVME_NS_WRITE_UNCORRECTABLE_SUPPORTED;
}
if (nsdata->nsrescap.raw) { if (nsdata->nsrescap.raw) {
ns->flags |= SPDK_NVME_NS_RESERVATION_SUPPORTED; ns->flags |= SPDK_NVME_NS_RESERVATION_SUPPORTED;
} }

View File

@ -778,6 +778,35 @@ spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *q
return nvme_qpair_submit_request(qpair, req); return nvme_qpair_submit_request(qpair, req);
} }
int
spdk_nvme_ns_cmd_write_uncorrectable(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
uint64_t lba, uint32_t lba_count,
spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
struct nvme_request *req;
struct spdk_nvme_cmd *cmd;
uint64_t *tmp_lba;
if (lba_count == 0 || lba_count > UINT16_MAX + 1) {
return -EINVAL;
}
req = nvme_allocate_request_null(qpair, cb_fn, cb_arg);
if (req == NULL) {
return -ENOMEM;
}
cmd = &req->cmd;
cmd->opc = SPDK_NVME_OPC_WRITE_UNCORRECTABLE;
cmd->nsid = ns->id;
tmp_lba = (uint64_t *)&cmd->cdw10;
*tmp_lba = lba;
cmd->cdw12 = lba_count - 1;
return nvme_qpair_submit_request(qpair, req);
}
int int
spdk_nvme_ns_cmd_dataset_management(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair, spdk_nvme_ns_cmd_dataset_management(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair,
uint32_t type, uint32_t type,

View File

@ -564,6 +564,33 @@ test_nvme_ns_cmd_write_zeroes(void)
cleanup_after_test(&qpair); cleanup_after_test(&qpair);
} }
static void
test_nvme_ns_cmd_write_uncorrectable(void)
{
struct spdk_nvme_ns ns = { 0 };
struct spdk_nvme_ctrlr ctrlr = { 0 };
struct spdk_nvme_qpair qpair;
spdk_nvme_cmd_cb cb_fn = NULL;
void *cb_arg = NULL;
uint64_t cmd_lba;
uint32_t cmd_lba_count;
int rc;
prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 0, false);
rc = spdk_nvme_ns_cmd_write_uncorrectable(&ns, &qpair, 0, 2, cb_fn, cb_arg);
SPDK_CU_ASSERT_FATAL(rc == 0);
SPDK_CU_ASSERT_FATAL(g_request != NULL);
CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE_UNCORRECTABLE);
CU_ASSERT(g_request->cmd.nsid == ns.id);
nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
CU_ASSERT_EQUAL(cmd_lba, 0);
CU_ASSERT_EQUAL(cmd_lba_count, 2);
nvme_free_request(g_request);
cleanup_after_test(&qpair);
}
static void static void
test_nvme_ns_cmd_dataset_management(void) test_nvme_ns_cmd_dataset_management(void)
{ {
@ -1405,6 +1432,8 @@ int main(int argc, char **argv)
test_nvme_ns_cmd_dataset_management) == NULL test_nvme_ns_cmd_dataset_management) == NULL
|| CU_add_test(suite, "io_flags", test_io_flags) == NULL || CU_add_test(suite, "io_flags", test_io_flags) == NULL
|| CU_add_test(suite, "nvme_ns_cmd_write_zeroes", test_nvme_ns_cmd_write_zeroes) == NULL || CU_add_test(suite, "nvme_ns_cmd_write_zeroes", test_nvme_ns_cmd_write_zeroes) == NULL
|| CU_add_test(suite, "nvme_ns_cmd_write_uncorrectable",
test_nvme_ns_cmd_write_uncorrectable) == NULL
|| CU_add_test(suite, "nvme_ns_cmd_reservation_register", || CU_add_test(suite, "nvme_ns_cmd_reservation_register",
test_nvme_ns_cmd_reservation_register) == NULL test_nvme_ns_cmd_reservation_register) == NULL
|| CU_add_test(suite, "nvme_ns_cmd_reservation_release", || CU_add_test(suite, "nvme_ns_cmd_reservation_release",