From d6ec160211e207e8ea7f23e8bb7d1720723b6493 Mon Sep 17 00:00:00 2001 From: Liang Yan Date: Wed, 3 Feb 2016 09:31:02 +0800 Subject: [PATCH] spdk: Add sgl request unit test Change-Id: I07b253c394d82b92564bfbdea8014e75b8dbf9ce Signed-off-by: Liang Yan --- .../nvme/unit/nvme_qpair_c/nvme_qpair_ut.c | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c b/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c index cc4d4105a..875e3ffff 100644 --- a/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c +++ b/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c @@ -31,6 +31,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include + #include "spdk_cunit.h" #include "nvme/nvme_qpair.c" @@ -44,8 +47,12 @@ int32_t spdk_nvme_retry_count = 1; char outbuf[OUTBUF_SIZE]; +struct nvme_request *g_request = NULL; + bool fail_vtophys = false; +bool fail_next_sge = false; + uint64_t nvme_vtophys(void *buf) { if (fail_vtophys) { @@ -55,6 +62,43 @@ uint64_t nvme_vtophys(void *buf) } } +struct io_request { + uint64_t address_offset; + bool invalid_addr; +}; + +static void nvme_request_reset_sgl(void *cb_arg, uint32_t sgl_offset) +{ + struct io_request *req = (struct io_request *)cb_arg; + + req->address_offset = 0; + if (sgl_offset == 0) + req->invalid_addr = false; + else + req->invalid_addr = true; + + return; +} + +static int nvme_request_next_sge(void *cb_arg, uint64_t *address, uint32_t *length) +{ + struct io_request *req = (struct io_request *)cb_arg; + if (req->invalid_addr) + *address = 7; + else { + *address = 4096 * req->address_offset; + } + req->address_offset += 1; + *length = 4096; + + if (fail_next_sge) { + return - 1; + } else { + return 0; + } + +} + struct nvme_request * nvme_allocate_request(const struct nvme_payload *payload, uint32_t payload_size, spdk_nvme_cmd_cb cb_fn, @@ -281,6 +325,81 @@ test4(void) cleanup_submit_request_test(&qpair); } + +static void +test_sgl_req(void) +{ + struct nvme_qpair qpair = {}; + struct nvme_request *req; + struct spdk_nvme_ctrlr ctrlr = {}; + struct spdk_nvme_registers regs = {}; + struct nvme_payload payload = {}; + struct nvme_tracker *sgl_tr = NULL; + uint64_t i; + struct io_request io_req = {}; + + payload.type = NVME_PAYLOAD_TYPE_SGL; + payload.u.sgl.reset_sgl_fn = nvme_request_reset_sgl; + payload.u.sgl.next_sge_fn = nvme_request_next_sge; + payload.u.sgl.cb_arg = &io_req; + + prepare_submit_request_test(&qpair, &ctrlr, ®s); + req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); + SPDK_CU_ASSERT_FATAL(req != NULL); + req->cmd.opc = SPDK_NVME_OPC_WRITE; + req->cmd.cdw10 = 10000; + req->cmd.cdw12 = 255 | 0; + req->payload_offset = 1; + + nvme_qpair_submit_request(&qpair, req); + CU_ASSERT(req->cmd.psdt == SPDK_NVME_PSDT_PRP); + CU_ASSERT(req->cmd.dptr.prp.prp1 == 7); + CU_ASSERT(req->cmd.dptr.prp.prp2 == 4096); + + sgl_tr = LIST_FIRST(&qpair.outstanding_tr); + LIST_REMOVE(sgl_tr, list); + free(sgl_tr); + cleanup_submit_request_test(&qpair); + nvme_free_request(req); + + prepare_submit_request_test(&qpair, &ctrlr, ®s); + req = nvme_allocate_request(&payload, PAGE_SIZE, NULL, &io_req); + SPDK_CU_ASSERT_FATAL(req != NULL); + req->cmd.opc = SPDK_NVME_OPC_WRITE; + req->cmd.cdw10 = 10000; + req->cmd.cdw12 = 255 | 0; + spdk_nvme_retry_count = 1; + fail_next_sge = true; + + nvme_qpair_submit_request(&qpair, req); + CU_ASSERT(qpair.sq_tail == 0); + cleanup_submit_request_test(&qpair); + + fail_next_sge = false; + + prepare_submit_request_test(&qpair, &ctrlr, ®s); + req = nvme_allocate_request(&payload, 33 * PAGE_SIZE, NULL, &io_req); + SPDK_CU_ASSERT_FATAL(req != NULL); + req->cmd.opc = SPDK_NVME_OPC_WRITE; + req->cmd.cdw10 = 10000; + req->cmd.cdw12 = 255 | 0; + + nvme_qpair_submit_request(&qpair, req); + + CU_ASSERT(req->cmd.dptr.prp.prp1 == 0); + CU_ASSERT(qpair.sq_tail == 1); + sgl_tr = LIST_FIRST(&qpair.outstanding_tr); + CU_ASSERT(sgl_tr != NULL); + for (i = 0; i < 32; i++) { + CU_ASSERT(sgl_tr->prp[i] == (PAGE_SIZE * (i + 1))); + } + + LIST_REMOVE(sgl_tr, list); + free(sgl_tr); + cleanup_submit_request_test(&qpair); + nvme_free_request(req); +} + static void test_ctrlr_failed(void) { @@ -544,6 +663,7 @@ int main(int argc, char **argv) || CU_add_test(suite, "nvme_qpair_destroy", test_nvme_qpair_destroy) == NULL || CU_add_test(suite, "nvme_completion_is_retry", test_nvme_completion_is_retry) == NULL || CU_add_test(suite, "get_status_string", test_get_status_string) == NULL + || CU_add_test(suite, "sgl_request", test_sgl_req) == NULL ) { CU_cleanup_registry(); return CU_get_error();