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:
parent
6956b0ec1e
commit
6bcd3588d1
@ -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
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user