lib/nvme: add hw support for fused operations
Change-Id: I2a184a2d60f18439947afa2d4855d51b92ed282e Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/476137 Community-CI: SPDK CI Jenkins <sys_sgci@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com>
This commit is contained in:
parent
8209c8cfa0
commit
1c5d980300
@ -464,6 +464,16 @@ enum spdk_nvme_cc_ams {
|
||||
SPDK_NVME_CC_AMS_VS = 0x7, /**< vendor specific */
|
||||
};
|
||||
|
||||
/**
|
||||
* Fused Operation
|
||||
*/
|
||||
enum spdk_nvme_cmd_fuse {
|
||||
SPDK_NVMF_CMD_FUSE_NONE = 0x0, /**< normal operation */
|
||||
SPDK_NVME_CMD_FUSE_FIRST = 0x1, /**< fused operation, first command */
|
||||
SPDK_NVME_CMD_FUSE_SECOND = 0x2, /**< fused operation, second command */
|
||||
/* 0x3 - reserved */
|
||||
};
|
||||
|
||||
/**
|
||||
* Data used by Set Features/Get Features \ref SPDK_NVME_FEAT_ARBITRATION
|
||||
*/
|
||||
@ -2821,6 +2831,10 @@ SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fw_commit) == 4, "Incorrect size");
|
||||
(cpl)->status.sc == SPDK_NVME_SC_APPLICATION_TAG_CHECK_ERROR || \
|
||||
(cpl)->status.sc == SPDK_NVME_SC_REFERENCE_TAG_CHECK_ERROR))
|
||||
|
||||
/** Set fused operation */
|
||||
#define SPDK_NVME_IO_FLAGS_FUSE_FIRST (1U << 0)
|
||||
#define SPDK_NVME_IO_FLAGS_FUSE_SECOND (1U << 1)
|
||||
#define SPDK_NVME_IO_FLAGS_FUSE_MASK (3U << 0)
|
||||
/** Enable protection information checking of the Logical Block Reference Tag field */
|
||||
#define SPDK_NVME_IO_FLAGS_PRCHK_REFTAG (1U << 26)
|
||||
/** Enable protection information checking of the Application Tag field */
|
||||
@ -2833,7 +2847,8 @@ SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fw_commit) == 4, "Incorrect size");
|
||||
#define SPDK_NVME_IO_FLAGS_LIMITED_RETRY (1U << 31)
|
||||
|
||||
/** Mask of valid io flags mask */
|
||||
#define SPDK_NVME_IO_FLAGS_VALID_MASK 0xFFFF0000
|
||||
#define SPDK_NVME_IO_FLAGS_VALID_MASK 0xFFFF0003
|
||||
#define SPDK_NVME_IO_FLAGS_CDW12_MASK 0xFFFF0000
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -165,8 +165,10 @@ _nvme_ns_cmd_setup_request(struct spdk_nvme_ns *ns, struct nvme_request *req,
|
||||
}
|
||||
}
|
||||
|
||||
cmd->fuse = (io_flags & SPDK_NVME_IO_FLAGS_FUSE_MASK);
|
||||
|
||||
cmd->cdw12 = lba_count - 1;
|
||||
cmd->cdw12 |= io_flags;
|
||||
cmd->cdw12 |= (io_flags & SPDK_NVME_IO_FLAGS_CDW12_MASK);
|
||||
|
||||
cmd->cdw15 = apptag_mask;
|
||||
cmd->cdw15 = (cmd->cdw15 << 16 | apptag);
|
||||
@ -828,7 +830,8 @@ spdk_nvme_ns_cmd_write_zeroes(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *q
|
||||
tmp_lba = (uint64_t *)&cmd->cdw10;
|
||||
*tmp_lba = lba;
|
||||
cmd->cdw12 = lba_count - 1;
|
||||
cmd->cdw12 |= io_flags;
|
||||
cmd->fuse = (io_flags & SPDK_NVME_IO_FLAGS_FUSE_MASK);
|
||||
cmd->cdw12 |= (io_flags & SPDK_NVME_IO_FLAGS_CDW12_MASK);
|
||||
|
||||
return nvme_qpair_submit_request(qpair, req);
|
||||
}
|
||||
|
@ -746,6 +746,53 @@ test_nvme_ns_cmd_comparev(void)
|
||||
cleanup_after_test(&qpair);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nvme_ns_cmd_compare_and_write(void)
|
||||
{
|
||||
struct spdk_nvme_ns ns;
|
||||
struct spdk_nvme_ctrlr ctrlr;
|
||||
struct spdk_nvme_qpair qpair;
|
||||
int rc = 0;
|
||||
uint64_t lba = 0x1000;
|
||||
uint32_t lba_count = 256;
|
||||
uint64_t cmd_lba;
|
||||
uint32_t cmd_lba_count;
|
||||
uint32_t sector_size = 512;
|
||||
|
||||
prepare_for_test(&ns, &ctrlr, &qpair, sector_size, 0, 128 * 1024, 0, false);
|
||||
|
||||
rc = spdk_nvme_ns_cmd_compare(&ns, &qpair, NULL, lba, lba_count, NULL, NULL,
|
||||
SPDK_NVME_IO_FLAGS_FUSE_FIRST);
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(rc == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_request != NULL);
|
||||
CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_COMPARE);
|
||||
CU_ASSERT(g_request->cmd.fuse == SPDK_NVME_CMD_FUSE_FIRST);
|
||||
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, lba);
|
||||
CU_ASSERT_EQUAL(cmd_lba_count, lba_count);
|
||||
|
||||
nvme_free_request(g_request);
|
||||
|
||||
rc = spdk_nvme_ns_cmd_write(&ns, &qpair, NULL, lba, lba_count, NULL, NULL,
|
||||
SPDK_NVME_IO_FLAGS_FUSE_SECOND);
|
||||
|
||||
SPDK_CU_ASSERT_FATAL(rc == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_request != NULL);
|
||||
CU_ASSERT(g_request->cmd.opc == SPDK_NVME_OPC_WRITE);
|
||||
CU_ASSERT(g_request->cmd.fuse == SPDK_NVME_CMD_FUSE_SECOND);
|
||||
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, lba);
|
||||
CU_ASSERT_EQUAL(cmd_lba_count, lba_count);
|
||||
|
||||
nvme_free_request(g_request);
|
||||
|
||||
cleanup_after_test(&qpair);
|
||||
}
|
||||
|
||||
static void
|
||||
test_io_flags(void)
|
||||
{
|
||||
@ -755,6 +802,8 @@ test_io_flags(void)
|
||||
void *payload;
|
||||
uint64_t lba;
|
||||
uint32_t lba_count;
|
||||
uint64_t cmd_lba;
|
||||
uint32_t cmd_lba_count;
|
||||
int rc;
|
||||
|
||||
prepare_for_test(&ns, &ctrlr, &qpair, 512, 0, 128 * 1024, 128 * 1024, false);
|
||||
@ -778,6 +827,21 @@ test_io_flags(void)
|
||||
CU_ASSERT((g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_LIMITED_RETRY) != 0);
|
||||
nvme_free_request(g_request);
|
||||
|
||||
rc = spdk_nvme_ns_cmd_write(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
|
||||
SPDK_NVME_IO_FLAGS_VALID_MASK);
|
||||
SPDK_CU_ASSERT_FATAL(rc == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_request != NULL);
|
||||
nvme_cmd_interpret_rw(&g_request->cmd, &cmd_lba, &cmd_lba_count);
|
||||
CU_ASSERT_EQUAL(cmd_lba_count, lba_count);
|
||||
CU_ASSERT_EQUAL(cmd_lba, lba);
|
||||
CU_ASSERT_EQUAL(g_request->cmd.cdw12 & SPDK_NVME_IO_FLAGS_CDW12_MASK,
|
||||
SPDK_NVME_IO_FLAGS_CDW12_MASK);
|
||||
nvme_free_request(g_request);
|
||||
|
||||
rc = spdk_nvme_ns_cmd_write(&ns, &qpair, payload, lba, lba_count, NULL, NULL,
|
||||
~SPDK_NVME_IO_FLAGS_VALID_MASK);
|
||||
CU_ASSERT(rc == -EINVAL);
|
||||
|
||||
free(payload);
|
||||
cleanup_after_test(&qpair);
|
||||
}
|
||||
@ -1447,6 +1511,7 @@ int main(int argc, char **argv)
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_writev", test_nvme_ns_cmd_writev) == NULL
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_write_with_md", test_nvme_ns_cmd_write_with_md) == NULL
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_comparev", test_nvme_ns_cmd_comparev) == NULL
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_compare_and_write", test_nvme_ns_cmd_compare_and_write) == NULL
|
||||
|| CU_add_test(suite, "nvme_ns_cmd_compare_with_md", test_nvme_ns_cmd_compare_with_md) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
|
Loading…
Reference in New Issue
Block a user