* [PATCH v4 1/3] test/dma: use unit test framework
2023-11-13 12:53 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
@ 2023-11-13 12:53 ` Gowrishankar Muthukrishnan
2023-11-13 12:53 ` [PATCH v4 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
` (3 subsequent siblings)
4 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-13 12:53 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Use unit test framework to execute DMA tests.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
app/test/test_dmadev.c | 235 +++++++++++++++++++++++++------------
app/test/test_dmadev_api.c | 95 +++++----------
2 files changed, 193 insertions(+), 137 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 216f84b6bb..9f7e7aa866 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -21,8 +21,12 @@
#define TEST_RINGSIZE 512
#define COPY_LEN 1024
+static struct rte_dma_info info;
static struct rte_mempool *pool;
+static bool check_err_stats;
+static int16_t test_dev_id;
static uint16_t id_count;
+static uint16_t vchan;
enum {
TEST_PARAM_REMOTE_ADDR = 0,
@@ -49,6 +53,8 @@ struct dma_add_test dma_add_test[] = {
[TEST_M2D_AUTO_FREE] = {.name = "m2d_auto_free", .enabled = false},
};
+static bool dev_init;
+
static void
__rte_format_printf(3, 4)
print_err(const char *func, int lineno, const char *format, ...)
@@ -61,13 +67,28 @@ print_err(const char *func, int lineno, const char *format, ...)
va_end(ap);
}
+struct runtest_param {
+ const char name[NAME_MAX];
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ int iterations;
+};
+
static int
-runtest(const char *printable, int (*test_fn)(int16_t dev_id, uint16_t vchan), int iterations,
- int16_t dev_id, uint16_t vchan, bool check_err_stats)
+runtest(const void *args)
{
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ const struct runtest_param *param = args;
struct rte_dma_stats stats;
+ const char *printable;
+ int iterations;
+ int16_t dev_id;
int i;
+ printable = param->name;
+ iterations = param->iterations;
+ test_fn = param->test_fn;
+ dev_id = test_dev_id;
+
rte_dma_stats_reset(dev_id, vchan);
printf("DMA Dev %d: Running %s Tests %s\n", dev_id, printable,
check_err_stats ? " " : "(errors expected)");
@@ -837,7 +858,6 @@ test_m2d_auto_free(int16_t dev_id, uint16_t vchan)
};
uint32_t buf_cnt1, buf_cnt2;
struct rte_mempool_ops *ops;
- static bool dev_init;
uint16_t nb_done = 0;
bool dma_err = false;
int retry = 100;
@@ -918,26 +938,85 @@ test_m2d_auto_free(int16_t dev_id, uint16_t vchan)
}
static int
-test_dmadev_instance(int16_t dev_id)
+test_dmadev_burst_setup(void)
+{
+ if (rte_dma_burst_capacity(test_dev_id, vchan) < 64) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
+ test_dev_id);
+ return TEST_SKIPPED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_dmadev_err_handling_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ /* to test error handling we can provide null pointers for source or dest in copies. This
+ * requires VA mode in DPDK, since NULL(0) is a valid physical address.
+ * We also need hardware that can report errors back.
+ */
+ if (rte_eal_iova_mode() != RTE_IOVA_VA)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n",
+ test_dev_id);
+ else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: device does not report errors, skipping error handling tests\n",
+ test_dev_id);
+ else
+ ret = TEST_SUCCESS;
+
+ return ret;
+}
+
+static int
+test_dmadev_fill_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: No device fill support, skipping fill tests\n", test_dev_id);
+ ret = TEST_SKIPPED;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_autofree_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
+ dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
+ dev_init = false;
+ ret = TEST_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_setup(void)
{
-#define CHECK_ERRS true
+ int16_t dev_id = test_dev_id;
struct rte_dma_stats stats;
- struct rte_dma_info info;
const struct rte_dma_conf conf = { .nb_vchans = 1};
const struct rte_dma_vchan_conf qconf = {
.direction = RTE_DMA_DIR_MEM_TO_MEM,
.nb_desc = TEST_RINGSIZE,
};
- const int vchan = 0;
int ret;
ret = rte_dma_info_get(dev_id, &info);
if (ret != 0)
ERR_RETURN("Error with rte_dma_info_get()\n");
- printf("\n### Test dmadev instance %u [%s]\n",
- dev_id, info.dev_name);
-
if (info.max_vchans < 1)
ERR_RETURN("Error, no channels available on device id %u\n", dev_id);
@@ -976,74 +1055,82 @@ test_dmadev_instance(int16_t dev_id)
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
- /* run the test cases, use many iterations to ensure UINT16_MAX id wraparound */
- if (runtest("copy", test_enqueue_copies, 640, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run tests stopping/starting devices and check jobs still work after restart */
- if (runtest("stop-start", test_stop_start, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run some burst capacity tests */
- if (rte_dma_burst_capacity(dev_id, vchan) < 64)
- printf("DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
- dev_id);
- else if (runtest("burst capacity", test_burst_capacity, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* to test error handling we can provide null pointers for source or dest in copies. This
- * requires VA mode in DPDK, since NULL(0) is a valid physical address.
- * We also need hardware that can report errors back.
- */
- if (rte_eal_iova_mode() != RTE_IOVA_VA)
- printf("DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n", dev_id);
- else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
- printf("DMA Dev %u: device does not report errors, skipping error handling tests\n",
- dev_id);
- else if (runtest("error handling", test_completion_handling, 1,
- dev_id, vchan, !CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0)
- printf("DMA Dev %u: No device fill support, skipping fill tests\n", dev_id);
- else if (runtest("fill", test_enqueue_fill, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
- dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
- if (runtest("m2d_auto_free", test_m2d_auto_free, 128, dev_id, vchan,
- CHECK_ERRS) < 0)
- goto err;
- }
-
- rte_mempool_free(pool);
-
- if (rte_dma_stop(dev_id) < 0)
- ERR_RETURN("Error stopping device %u\n", dev_id);
+ check_err_stats = false;
+ vchan = 0;
- rte_dma_stats_reset(dev_id, vchan);
return 0;
+}
-err:
+static void
+test_dmadev_teardown(void)
+{
rte_mempool_free(pool);
- rte_dma_stop(dev_id);
- return -1;
+ rte_dma_stop(test_dev_id);
+ rte_dma_stats_reset(test_dev_id, vchan);
+ test_dev_id = -EINVAL;
}
static int
-test_apis(void)
+test_dmadev_instance(int16_t dev_id)
{
- const char *pmd = "dma_skeleton";
- int id;
+ struct rte_dma_info dev_info;
+ enum {
+ TEST_COPY = 0,
+ TEST_START,
+ TEST_BURST,
+ TEST_ERR,
+ TEST_FILL,
+ TEST_M2D,
+ TEST_END
+ };
+
+ static struct runtest_param param[] = {
+ {"copy", test_enqueue_copies, 640},
+ {"stop_start", test_stop_start, 1},
+ {"burst_capacity", test_burst_capacity, 1},
+ {"error_handling", test_completion_handling, 1},
+ {"fill", test_enqueue_fill, 1},
+ {"m2d_auto_free", test_m2d_auto_free, 128},
+ };
+
+ static struct unit_test_suite ts = {
+ .suite_name = "DMA dev instance testsuite",
+ .setup = test_dmadev_setup,
+ .teardown = test_dmadev_teardown,
+ .unit_test_cases = {
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY].name,
+ NULL, NULL,
+ runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_START].name,
+ NULL, NULL,
+ runtest, ¶m[TEST_START]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_BURST].name,
+ test_dmadev_burst_setup, NULL,
+ runtest, ¶m[TEST_BURST]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_ERR].name,
+ test_dmadev_err_handling_setup, NULL,
+ runtest, ¶m[TEST_ERR]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_FILL].name,
+ test_dmadev_fill_setup, NULL,
+ runtest, ¶m[TEST_FILL]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_M2D].name,
+ test_dmadev_autofree_setup, NULL,
+ runtest, ¶m[TEST_M2D]),
+ TEST_CASES_END()
+ }
+ };
+
int ret;
- /* attempt to create skeleton instance - ignore errors due to one being already present */
- rte_vdev_init(pmd, NULL);
- id = rte_dma_get_dev_id_by_name(pmd);
- if (id < 0)
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
return TEST_SKIPPED;
- printf("\n### Test dmadev infrastructure using skeleton driver\n");
- ret = test_dma_api(id);
+
+ test_dev_id = dev_id;
+ printf("\n### Test dmadev instance %u [%s]\n",
+ test_dev_id, dev_info.dev_name);
+
+ ret = unit_test_suite_runner(&ts);
+ test_dev_id = -EINVAL;
return ret;
}
@@ -1088,22 +1175,26 @@ parse_dma_env_var(void)
static int
test_dma(void)
{
+ const char *pmd = "dma_skeleton";
int i;
parse_dma_env_var();
- /* basic sanity on dmadev infrastructure */
- if (test_apis() < 0)
- ERR_RETURN("Error performing API tests\n");
+ /* attempt to create skeleton instance - ignore errors due to one being already present*/
+ rte_vdev_init(pmd, NULL);
if (rte_dma_count_avail() == 0)
return TEST_SKIPPED;
- RTE_DMA_FOREACH_DEV(i)
+ RTE_DMA_FOREACH_DEV(i) {
+ if (test_dma_api(i) < 0)
+ ERR_RETURN("Error performing API tests\n");
+
if (test_dmadev_instance(i) < 0)
ERR_RETURN("Error, test failure for device %d\n", i);
+ }
return 0;
}
-REGISTER_DRIVER_TEST(dmadev_autotest, test_dma);
+REGISTER_TEST_COMMAND(dmadev_autotest, test_dma);
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 4a181af90a..73d4db825a 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -9,31 +9,22 @@
#include <rte_test.h>
#include <rte_dmadev.h>
-extern int test_dma_api(uint16_t dev_id);
+#include "test.h"
-#define DMA_TEST_API_RUN(test) \
- testsuite_run_test(test, #test)
+extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
-#define TEST_SUCCESS 0
-#define TEST_FAILED -1
-
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
-static int total;
-static int passed;
-static int failed;
-
static int
-testsuite_setup(int16_t dev_id)
+testsuite_setup(void)
{
- test_dev_id = dev_id;
invalid_dev_id = -1;
src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
@@ -46,10 +37,6 @@ testsuite_setup(int16_t dev_id)
return -ENOMEM;
}
- total = 0;
- passed = 0;
- failed = 0;
-
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
@@ -71,25 +58,6 @@ testsuite_teardown(void)
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO);
}
-static void
-testsuite_run_test(int (*test)(void), const char *name)
-{
- int ret = 0;
-
- if (test) {
- ret = test();
- if (ret < 0) {
- failed++;
- printf("%s Failed\n", name);
- } else {
- passed++;
- printf("%s Passed\n", name);
- }
- }
-
- total++;
-}
-
static int
test_dma_get_dev_id_by_name(void)
{
@@ -301,7 +269,7 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = dev_info.max_vchans;
+ dev_conf.nb_vchans = 1;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
@@ -537,38 +505,35 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static struct unit_test_suite dma_api_testsuite = {
+ .suite_name = "DMA API Test Suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE(test_dma_get_dev_id_by_name),
+ TEST_CASE(test_dma_is_valid_dev),
+ TEST_CASE(test_dma_count),
+ TEST_CASE(test_dma_info_get),
+ TEST_CASE(test_dma_configure),
+ TEST_CASE(test_dma_vchan_setup),
+ TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_stats),
+ TEST_CASE(test_dma_dump),
+ TEST_CASE(test_dma_completed),
+ TEST_CASE(test_dma_completed_status),
+ TEST_CASES_END()
+ }
+};
+
int
test_dma_api(uint16_t dev_id)
{
- int ret = testsuite_setup(dev_id);
- if (ret) {
- printf("testsuite setup fail!\n");
- return -1;
- }
+ struct rte_dma_info dev_info;
- /* If the testcase exit successfully, ensure that the test dmadev exist
- * and the dmadev is in the stopped state.
- */
- DMA_TEST_API_RUN(test_dma_get_dev_id_by_name);
- DMA_TEST_API_RUN(test_dma_is_valid_dev);
- DMA_TEST_API_RUN(test_dma_count);
- DMA_TEST_API_RUN(test_dma_info_get);
- DMA_TEST_API_RUN(test_dma_configure);
- DMA_TEST_API_RUN(test_dma_vchan_setup);
- DMA_TEST_API_RUN(test_dma_start_stop);
- DMA_TEST_API_RUN(test_dma_stats);
- DMA_TEST_API_RUN(test_dma_dump);
- DMA_TEST_API_RUN(test_dma_completed);
- DMA_TEST_API_RUN(test_dma_completed_status);
-
- testsuite_teardown();
-
- printf("Total tests : %d\n", total);
- printf("Passed : %d\n", passed);
- printf("Failed : %d\n", failed);
-
- if (failed)
- return -1;
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
+ return TEST_SKIPPED;
- return 0;
+ printf("\n### Test dmadev infrastructure using %u [%s]\n", dev_id, dev_info.dev_name);
+ test_dev_id = dev_id;
+ return unit_test_suite_runner(&dma_api_testsuite);
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 2/3] test/dma: test multiple vchan
2023-11-13 12:53 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-13 12:53 ` [PATCH v4 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
@ 2023-11-13 12:53 ` Gowrishankar Muthukrishnan
2023-11-13 12:53 ` [PATCH v4 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
` (2 subsequent siblings)
4 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-13 12:53 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Support API with multiple vchan test.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
app/test/test_dmadev_api.c | 63 +++++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 73d4db825a..2b8a4eda62 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -260,7 +260,7 @@ test_dma_vchan_setup(void)
}
static int
-setup_one_vchan(void)
+setup_vchan(int nb_vchans)
{
struct rte_dma_vchan_conf vchan_conf = { 0 };
struct rte_dma_info dev_info = { 0 };
@@ -269,13 +269,15 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = 1;
+ dev_conf.nb_vchans = nb_vchans;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
vchan_conf.nb_desc = dev_info.min_desc;
- ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
- RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret);
+ for (int i = 0; i < nb_vchans; i++) {
+ ret = rte_dma_vchan_setup(test_dev_id, i, &vchan_conf);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan %d, %d", i, ret);
+ }
return TEST_SUCCESS;
}
@@ -294,7 +296,7 @@ test_dma_start_stop(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -312,6 +314,50 @@ test_dma_start_stop(void)
return TEST_SUCCESS;
}
+static int
+test_dma_reconfigure(void)
+{
+ struct rte_dma_conf dev_conf = { 0 };
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t cfg_vchans;
+ int ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ /* At least two vchans required for the test */
+ if (dev_info.max_vchans < 2)
+ return TEST_SKIPPED;
+
+ /* Setup one vchan for later test */
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ /* Check reconfigure and vchan setup after device stopped */
+ cfg_vchans = dev_conf.nb_vchans = (dev_info.max_vchans - 1);
+
+ ret = setup_vchan(cfg_vchans);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+ RTE_TEST_ASSERT_EQUAL(dev_info.nb_vchans, cfg_vchans, "incorrect reconfiguration");
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static int
test_dma_stats(void)
{
@@ -328,7 +374,7 @@ test_dma_stats(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
/* Check for invalid vchan */
@@ -400,7 +446,7 @@ test_dma_completed(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -459,7 +505,7 @@ test_dma_completed_status(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -517,6 +563,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_configure),
TEST_CASE(test_dma_vchan_setup),
TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_reconfigure),
TEST_CASE(test_dma_stats),
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v4 3/3] test/dma: add SG copy tests
2023-11-13 12:53 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-13 12:53 ` [PATCH v4 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
2023-11-13 12:53 ` [PATCH v4 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
@ 2023-11-13 12:53 ` Gowrishankar Muthukrishnan
2023-11-16 7:16 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests fengchengwen
2023-11-16 10:40 ` [PATCH v5 " Gowrishankar Muthukrishnan
4 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-13 12:53 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Add scatter-gather copy tests.
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
---
app/test/test_dmadev.c | 139 ++++++++++++++++++++++++++++++-
app/test/test_dmadev_api.c | 164 ++++++++++++++++++++++++++++++++++---
2 files changed, 289 insertions(+), 14 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 9f7e7aa866..cc9e71156d 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -19,7 +19,7 @@
#define ERR_RETURN(...) do { print_err(__func__, __LINE__, __VA_ARGS__); return -1; } while (0)
#define TEST_RINGSIZE 512
-#define COPY_LEN 1024
+#define COPY_LEN 2048
static struct rte_dma_info info;
static struct rte_mempool *pool;
@@ -393,6 +393,125 @@ test_stop_start(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_enqueue_sg_copies(int16_t dev_id, uint16_t vchan)
+{
+ unsigned int src_len, dst_len, n_sge, len, i, j, k;
+ char orig_src[COPY_LEN], orig_dst[COPY_LEN];
+ struct rte_dma_info info = { 0 };
+ enum rte_dma_status_code status;
+ uint16_t id, n_src, n_dst;
+
+ if (rte_dma_info_get(dev_id, &info) < 0)
+ ERR_RETURN("Failed to get dev info");
+
+ if (info.max_sges < 2)
+ ERR_RETURN("Test needs minimum 2 SG pointers");
+
+ n_sge = info.max_sges;
+
+ for (n_src = 1; n_src <= n_sge; n_src++) {
+ for (n_dst = 1; n_dst <= n_sge; n_dst++) {
+ /* Normalize SG buffer lengths */
+ len = COPY_LEN;
+ len -= (len % (n_src * n_dst));
+ dst_len = len / n_dst;
+ src_len = len / n_src;
+
+ struct rte_dma_sge sg_src[n_sge], sg_dst[n_sge];
+ struct rte_mbuf *src[n_sge], *dst[n_sge];
+ char *src_data[n_sge], *dst_data[n_sge];
+
+ for (i = 0 ; i < len; i++)
+ orig_src[i] = rte_rand() & 0xFF;
+
+ memset(orig_dst, 0, len);
+
+ for (i = 0; i < n_src; i++) {
+ src[i] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(src[i] != NULL);
+ sg_src[i].addr = rte_pktmbuf_iova(src[i]);
+ sg_src[i].length = src_len;
+ src_data[i] = rte_pktmbuf_mtod(src[i], char *);
+ }
+
+ for (k = 0; k < n_dst; k++) {
+ dst[k] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(dst[k] != NULL);
+ sg_dst[k].addr = rte_pktmbuf_iova(dst[k]);
+ sg_dst[k].length = dst_len;
+ dst_data[k] = rte_pktmbuf_mtod(dst[k], char *);
+ }
+
+ for (i = 0; i < n_src; i++) {
+ for (j = 0; j < src_len; j++)
+ src_data[i][j] = orig_src[i * src_len + j];
+ }
+
+ for (k = 0; k < n_dst; k++)
+ memset(dst_data[k], 0, dst_len);
+
+ printf("\tsrc segs: %2d [seg len: %4d] - dst segs: %2d [seg len : %4d]\n",
+ n_src, src_len, n_dst, dst_len);
+
+ id = rte_dma_copy_sg(dev_id, vchan, sg_src, sg_dst, n_src, n_dst,
+ RTE_DMA_OP_FLAG_SUBMIT);
+
+ if (id != id_count)
+ ERR_RETURN("Error with rte_dma_copy_sg, got %u, expected %u\n",
+ id, id_count);
+
+ /* Give time for copy to finish, then check it was done */
+ await_hw(dev_id, vchan);
+
+ for (k = 0; k < n_dst; k++)
+ memcpy((&orig_dst[0] + k * dst_len), dst_data[k], dst_len);
+
+ if (memcmp(orig_src, orig_dst, COPY_LEN))
+ ERR_RETURN("Data mismatch");
+
+ /* Verify completion */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 1)
+ ERR_RETURN("Error with rte_dma_completed\n");
+
+ /* Verify expected index(id_count) */
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed and id when no job done */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed when no job done\n");
+
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed_status and id when no job done */
+ id = ~id;
+ if (rte_dma_completed_status(dev_id, vchan, 1, &id, &status) != 0)
+ ERR_RETURN("Error with rte_dma_completed_status when no job done\n");
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, 0);
+
+ for (i = 0; i < n_src; i++)
+ rte_pktmbuf_free(src[i]);
+ for (i = 0; i < n_dst; i++)
+ rte_pktmbuf_free(dst[i]);
+
+ /* Verify that completion returns nothing more */
+ if (rte_dma_completed(dev_id, 0, 1, NULL, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed in empty check\n");
+
+ id_count++;
+ }
+ }
+ return 0;
+}
+
/* Failure handling test cases - global macros and variables for those tests*/
#define COMP_BURST_SZ 16
#define OPT_FENCE(idx) ((fence && idx == 8) ? RTE_DMA_OP_FLAG_FENCE : 0)
@@ -937,6 +1056,17 @@ test_m2d_auto_free(int16_t dev_id, uint16_t vchan)
return ret;
}
+static int
+test_dmadev_sg_copy_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ return ret;
+}
+
static int
test_dmadev_burst_setup(void)
{
@@ -1050,7 +1180,7 @@ test_dmadev_setup(void)
TEST_RINGSIZE * 2, /* n == num elements */
32, /* cache size */
0, /* priv size */
- 2048, /* data room size */
+ COPY_LEN + RTE_PKTMBUF_HEADROOM, /* data room size */
info.numa_node);
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
@@ -1076,6 +1206,7 @@ test_dmadev_instance(int16_t dev_id)
struct rte_dma_info dev_info;
enum {
TEST_COPY = 0,
+ TEST_COPY_SG,
TEST_START,
TEST_BURST,
TEST_ERR,
@@ -1086,6 +1217,7 @@ test_dmadev_instance(int16_t dev_id)
static struct runtest_param param[] = {
{"copy", test_enqueue_copies, 640},
+ {"sg_copy", test_enqueue_sg_copies, 1},
{"stop_start", test_stop_start, 1},
{"burst_capacity", test_burst_capacity, 1},
{"error_handling", test_completion_handling, 1},
@@ -1101,6 +1233,9 @@ test_dmadev_instance(int16_t dev_id)
TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY].name,
NULL, NULL,
runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY_SG].name,
+ test_dmadev_sg_copy_setup, NULL,
+ runtest, ¶m[TEST_COPY_SG]),
TEST_CASE_NAMED_WITH_DATA(param[TEST_START].name,
NULL, NULL,
runtest, ¶m[TEST_START]),
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 2b8a4eda62..a130e74b51 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -10,47 +10,75 @@
#include <rte_dmadev.h>
#include "test.h"
+#include "test_dmadev_api.h"
extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
+#define TEST_SG_MAX 64
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
+static char *src_sg[TEST_SG_MAX];
+static char *dst_sg[TEST_SG_MAX];
static int
testsuite_setup(void)
{
invalid_dev_id = -1;
-
- src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
- if (src == NULL)
- return -ENOMEM;
- dst = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
- if (dst == NULL) {
- rte_free(src);
- src = NULL;
- return -ENOMEM;
+ int i, rc = 0;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ src_sg[i] = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
+ if (src_sg[i] == NULL) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ dst_sg[i] = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
+ if (dst_sg[i] == NULL) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rc = -ENOMEM;
+ goto exit;
+ }
}
+ src = src_sg[0];
+ dst = dst_sg[0];
+
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT);
- return 0;
+ return rc;
+exit:
+ while (--i >= 0) {
+ rte_free(src_sg[i]);
+ rte_free(dst_sg[i]);
+ }
+
+ return rc;
}
static void
testsuite_teardown(void)
{
- rte_free(src);
+ int i;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rte_free(dst_sg[i]);
+ dst_sg[i] = NULL;
+ }
+
src = NULL;
- rte_free(dst);
dst = NULL;
/* Ensure the dmadev is stopped. */
rte_dma_stop(test_dev_id);
@@ -437,6 +465,37 @@ verify_memory(void)
return 0;
}
+static void
+sg_memory_setup(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++)
+ src_sg[i][j] = (char)j;
+
+ memset(dst_sg[i], 0, TEST_MEMCPY_SIZE);
+ }
+}
+
+static int
+sg_memory_verify(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++) {
+ if (src_sg[i][j] == dst_sg[i][j])
+ continue;
+
+ RTE_TEST_ASSERT_EQUAL(src_sg[i][j], dst_sg[i][j], "Failed to copy memory, %d %d",
+ src_sg[i][j], dst_sg[i][j]);
+ }
+ }
+
+ return 0;
+}
+
static int
test_dma_completed(void)
{
@@ -551,6 +610,86 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static int
+test_dma_sg(void)
+{
+ struct rte_dma_sge src_sge[TEST_SG_MAX], dst_sge[TEST_SG_MAX];
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t last_idx = -1;
+ bool has_error = true;
+ int n_sge, i, ret;
+ uint16_t cpl_ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
+
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ for (i = 0; i < n_sge; i++) {
+ src_sge[i].addr = rte_malloc_virt2iova(src_sg[i]);
+ src_sge[i].length = TEST_MEMCPY_SIZE;
+ dst_sge[i].addr = rte_malloc_virt2iova(dst_sg[i]);
+ dst_sge[i].length = TEST_MEMCPY_SIZE;
+ }
+
+ sg_memory_setup(n_sge);
+
+ /* Check enqueue without submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge, 0);
+ RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
+
+ /* Check DMA submit */
+ ret = rte_dma_submit(test_dev_id, 0);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ sg_memory_setup(n_sge);
+
+ /* Check for enqueue with submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge,
+ RTE_DMA_OP_FLAG_SUBMIT);
+ RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ /* Stop dmadev to make sure dmadev to a known state */
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite dma_api_testsuite = {
.suite_name = "DMA API Test Suite",
.setup = testsuite_setup,
@@ -568,6 +707,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
TEST_CASE(test_dma_completed_status),
+ TEST_CASE(test_dma_sg),
TEST_CASES_END()
}
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests
2023-11-13 12:53 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
` (2 preceding siblings ...)
2023-11-13 12:53 ` [PATCH v4 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
@ 2023-11-16 7:16 ` fengchengwen
2023-11-16 10:40 ` [PATCH v5 " Gowrishankar Muthukrishnan
4 siblings, 0 replies; 39+ messages in thread
From: fengchengwen @ 2023-11-16 7:16 UTC (permalink / raw)
To: Gowrishankar Muthukrishnan, dev
Cc: anoobj, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson
LGTM
Series-acked-by: Chengwen Feng <fengchengwen@huawei.com>
PS: since 'test/dma: fix for buffer auto free' already merged, I think you should resend v5 to fix the apply error.
On 2023/11/13 20:53, Gowrishankar Muthukrishnan wrote:
> This patch series reworks DMA tests to follow unit test framework
> followed by new vchan reconfig and SG tests.
>
> v4:
> - Suggestions from Fengchenwen addressed.
>
> Gowrishankar Muthukrishnan (3):
> test/dma: use unit test framework
> test/dma: test multiple vchan
> test/dma: add SG copy tests
>
> app/test/test_dmadev.c | 374 +++++++++++++++++++++++++++++--------
> app/test/test_dmadev_api.c | 316 +++++++++++++++++++++++--------
> 2 files changed, 534 insertions(+), 156 deletions(-)
>
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v5 0/3] test/dma: add vchan reconfig and SG tests
2023-11-13 12:53 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
` (3 preceding siblings ...)
2023-11-16 7:16 ` [PATCH v4 0/3] test/dma: add vchan reconfig and SG tests fengchengwen
@ 2023-11-16 10:40 ` Gowrishankar Muthukrishnan
2023-11-16 10:40 ` [PATCH v5 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
` (3 more replies)
4 siblings, 4 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:40 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
This patch series reworks DMA tests to follow unit test framework
followed by new vchan reconfig and SG tests.
v5:
- patch rebased.
Gowrishankar Muthukrishnan (3):
test/dma: use unit test framework
test/dma: test multiple vchan
test/dma: add SG copy tests
app/test/test_dmadev.c | 375 +++++++++++++++++++++++++++++--------
app/test/test_dmadev_api.c | 316 +++++++++++++++++++++++--------
2 files changed, 534 insertions(+), 157 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v5 1/3] test/dma: use unit test framework
2023-11-16 10:40 ` [PATCH v5 " Gowrishankar Muthukrishnan
@ 2023-11-16 10:40 ` Gowrishankar Muthukrishnan
2023-11-16 10:40 ` [PATCH v5 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
` (2 subsequent siblings)
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:40 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Use unit test framework to execute DMA tests.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev.c | 236 +++++++++++++++++++++++++------------
app/test/test_dmadev_api.c | 95 +++++----------
2 files changed, 193 insertions(+), 138 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 7581fc2b4c..a1505716d1 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -21,8 +21,12 @@
#define TEST_RINGSIZE 512
#define COPY_LEN 1024
+static struct rte_dma_info info;
static struct rte_mempool *pool;
+static bool check_err_stats;
+static int16_t test_dev_id;
static uint16_t id_count;
+static uint16_t vchan;
enum {
TEST_PARAM_REMOTE_ADDR = 0,
@@ -61,13 +65,28 @@ print_err(const char *func, int lineno, const char *format, ...)
va_end(ap);
}
+struct runtest_param {
+ const char name[NAME_MAX];
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ int iterations;
+};
+
static int
-runtest(const char *printable, int (*test_fn)(int16_t dev_id, uint16_t vchan), int iterations,
- int16_t dev_id, uint16_t vchan, bool check_err_stats)
+runtest(const void *args)
{
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ const struct runtest_param *param = args;
struct rte_dma_stats stats;
+ const char *printable;
+ int iterations;
+ int16_t dev_id;
int i;
+ printable = param->name;
+ iterations = param->iterations;
+ test_fn = param->test_fn;
+ dev_id = test_dev_id;
+
rte_dma_stats_reset(dev_id, vchan);
printf("DMA Dev %d: Running %s Tests %s\n", dev_id, printable,
check_err_stats ? " " : "(errors expected)");
@@ -911,26 +930,87 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
}
static int
-test_dmadev_instance(int16_t dev_id)
+test_dmadev_burst_setup(void)
+{
+ if (rte_dma_burst_capacity(test_dev_id, vchan) < 64) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
+ test_dev_id);
+ return TEST_SKIPPED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_dmadev_err_handling_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ /* to test error handling we can provide null pointers for source or dest in copies. This
+ * requires VA mode in DPDK, since NULL(0) is a valid physical address.
+ * We also need hardware that can report errors back.
+ */
+ if (rte_eal_iova_mode() != RTE_IOVA_VA)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n",
+ test_dev_id);
+ else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: device does not report errors, skipping error handling tests\n",
+ test_dev_id);
+ else
+ ret = TEST_SUCCESS;
+
+ return ret;
+}
+
+static int
+test_dmadev_fill_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: No device fill support, skipping fill tests\n", test_dev_id);
+ ret = TEST_SKIPPED;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_autofree_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
+ dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
+ if (prepare_m2d_auto_free(test_dev_id, vchan) != 0)
+ return ret;
+
+ ret = TEST_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_setup(void)
{
-#define CHECK_ERRS true
+ int16_t dev_id = test_dev_id;
struct rte_dma_stats stats;
- struct rte_dma_info info;
const struct rte_dma_conf conf = { .nb_vchans = 1};
const struct rte_dma_vchan_conf qconf = {
.direction = RTE_DMA_DIR_MEM_TO_MEM,
.nb_desc = TEST_RINGSIZE,
};
- const int vchan = 0;
int ret;
ret = rte_dma_info_get(dev_id, &info);
if (ret != 0)
ERR_RETURN("Error with rte_dma_info_get()\n");
- printf("\n### Test dmadev instance %u [%s]\n",
- dev_id, info.dev_name);
-
if (info.max_vchans < 1)
ERR_RETURN("Error, no channels available on device id %u\n", dev_id);
@@ -969,76 +1049,82 @@ test_dmadev_instance(int16_t dev_id)
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
- /* run the test cases, use many iterations to ensure UINT16_MAX id wraparound */
- if (runtest("copy", test_enqueue_copies, 640, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run tests stopping/starting devices and check jobs still work after restart */
- if (runtest("stop-start", test_stop_start, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run some burst capacity tests */
- if (rte_dma_burst_capacity(dev_id, vchan) < 64)
- printf("DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
- dev_id);
- else if (runtest("burst capacity", test_burst_capacity, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* to test error handling we can provide null pointers for source or dest in copies. This
- * requires VA mode in DPDK, since NULL(0) is a valid physical address.
- * We also need hardware that can report errors back.
- */
- if (rte_eal_iova_mode() != RTE_IOVA_VA)
- printf("DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n", dev_id);
- else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
- printf("DMA Dev %u: device does not report errors, skipping error handling tests\n",
- dev_id);
- else if (runtest("error handling", test_completion_handling, 1,
- dev_id, vchan, !CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0)
- printf("DMA Dev %u: No device fill support, skipping fill tests\n", dev_id);
- else if (runtest("fill", test_enqueue_fill, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
- dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
- if (prepare_m2d_auto_free(dev_id, vchan) != 0)
- goto err;
- if (runtest("m2d_auto_free", test_m2d_auto_free, 128, dev_id, vchan,
- CHECK_ERRS) < 0)
- goto err;
- }
-
- rte_mempool_free(pool);
-
- if (rte_dma_stop(dev_id) < 0)
- ERR_RETURN("Error stopping device %u\n", dev_id);
+ check_err_stats = false;
+ vchan = 0;
- rte_dma_stats_reset(dev_id, vchan);
return 0;
+}
-err:
+static void
+test_dmadev_teardown(void)
+{
rte_mempool_free(pool);
- rte_dma_stop(dev_id);
- return -1;
+ rte_dma_stop(test_dev_id);
+ rte_dma_stats_reset(test_dev_id, vchan);
+ test_dev_id = -EINVAL;
}
static int
-test_apis(void)
+test_dmadev_instance(int16_t dev_id)
{
- const char *pmd = "dma_skeleton";
- int id;
+ struct rte_dma_info dev_info;
+ enum {
+ TEST_COPY = 0,
+ TEST_START,
+ TEST_BURST,
+ TEST_ERR,
+ TEST_FILL,
+ TEST_M2D,
+ TEST_END
+ };
+
+ static struct runtest_param param[] = {
+ {"copy", test_enqueue_copies, 640},
+ {"stop_start", test_stop_start, 1},
+ {"burst_capacity", test_burst_capacity, 1},
+ {"error_handling", test_completion_handling, 1},
+ {"fill", test_enqueue_fill, 1},
+ {"m2d_auto_free", test_m2d_auto_free, 128},
+ };
+
+ static struct unit_test_suite ts = {
+ .suite_name = "DMA dev instance testsuite",
+ .setup = test_dmadev_setup,
+ .teardown = test_dmadev_teardown,
+ .unit_test_cases = {
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY].name,
+ NULL, NULL,
+ runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_START].name,
+ NULL, NULL,
+ runtest, ¶m[TEST_START]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_BURST].name,
+ test_dmadev_burst_setup, NULL,
+ runtest, ¶m[TEST_BURST]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_ERR].name,
+ test_dmadev_err_handling_setup, NULL,
+ runtest, ¶m[TEST_ERR]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_FILL].name,
+ test_dmadev_fill_setup, NULL,
+ runtest, ¶m[TEST_FILL]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_M2D].name,
+ test_dmadev_autofree_setup, NULL,
+ runtest, ¶m[TEST_M2D]),
+ TEST_CASES_END()
+ }
+ };
+
int ret;
- /* attempt to create skeleton instance - ignore errors due to one being already present */
- rte_vdev_init(pmd, NULL);
- id = rte_dma_get_dev_id_by_name(pmd);
- if (id < 0)
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
return TEST_SKIPPED;
- printf("\n### Test dmadev infrastructure using skeleton driver\n");
- ret = test_dma_api(id);
+
+ test_dev_id = dev_id;
+ printf("\n### Test dmadev instance %u [%s]\n",
+ test_dev_id, dev_info.dev_name);
+
+ ret = unit_test_suite_runner(&ts);
+ test_dev_id = -EINVAL;
return ret;
}
@@ -1083,22 +1169,26 @@ parse_dma_env_var(void)
static int
test_dma(void)
{
+ const char *pmd = "dma_skeleton";
int i;
parse_dma_env_var();
- /* basic sanity on dmadev infrastructure */
- if (test_apis() < 0)
- ERR_RETURN("Error performing API tests\n");
+ /* attempt to create skeleton instance - ignore errors due to one being already present*/
+ rte_vdev_init(pmd, NULL);
if (rte_dma_count_avail() == 0)
return TEST_SKIPPED;
- RTE_DMA_FOREACH_DEV(i)
+ RTE_DMA_FOREACH_DEV(i) {
+ if (test_dma_api(i) < 0)
+ ERR_RETURN("Error performing API tests\n");
+
if (test_dmadev_instance(i) < 0)
ERR_RETURN("Error, test failure for device %d\n", i);
+ }
return 0;
}
-REGISTER_DRIVER_TEST(dmadev_autotest, test_dma);
+REGISTER_TEST_COMMAND(dmadev_autotest, test_dma);
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 4a181af90a..73d4db825a 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -9,31 +9,22 @@
#include <rte_test.h>
#include <rte_dmadev.h>
-extern int test_dma_api(uint16_t dev_id);
+#include "test.h"
-#define DMA_TEST_API_RUN(test) \
- testsuite_run_test(test, #test)
+extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
-#define TEST_SUCCESS 0
-#define TEST_FAILED -1
-
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
-static int total;
-static int passed;
-static int failed;
-
static int
-testsuite_setup(int16_t dev_id)
+testsuite_setup(void)
{
- test_dev_id = dev_id;
invalid_dev_id = -1;
src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
@@ -46,10 +37,6 @@ testsuite_setup(int16_t dev_id)
return -ENOMEM;
}
- total = 0;
- passed = 0;
- failed = 0;
-
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
@@ -71,25 +58,6 @@ testsuite_teardown(void)
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO);
}
-static void
-testsuite_run_test(int (*test)(void), const char *name)
-{
- int ret = 0;
-
- if (test) {
- ret = test();
- if (ret < 0) {
- failed++;
- printf("%s Failed\n", name);
- } else {
- passed++;
- printf("%s Passed\n", name);
- }
- }
-
- total++;
-}
-
static int
test_dma_get_dev_id_by_name(void)
{
@@ -301,7 +269,7 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = dev_info.max_vchans;
+ dev_conf.nb_vchans = 1;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
@@ -537,38 +505,35 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static struct unit_test_suite dma_api_testsuite = {
+ .suite_name = "DMA API Test Suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE(test_dma_get_dev_id_by_name),
+ TEST_CASE(test_dma_is_valid_dev),
+ TEST_CASE(test_dma_count),
+ TEST_CASE(test_dma_info_get),
+ TEST_CASE(test_dma_configure),
+ TEST_CASE(test_dma_vchan_setup),
+ TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_stats),
+ TEST_CASE(test_dma_dump),
+ TEST_CASE(test_dma_completed),
+ TEST_CASE(test_dma_completed_status),
+ TEST_CASES_END()
+ }
+};
+
int
test_dma_api(uint16_t dev_id)
{
- int ret = testsuite_setup(dev_id);
- if (ret) {
- printf("testsuite setup fail!\n");
- return -1;
- }
+ struct rte_dma_info dev_info;
- /* If the testcase exit successfully, ensure that the test dmadev exist
- * and the dmadev is in the stopped state.
- */
- DMA_TEST_API_RUN(test_dma_get_dev_id_by_name);
- DMA_TEST_API_RUN(test_dma_is_valid_dev);
- DMA_TEST_API_RUN(test_dma_count);
- DMA_TEST_API_RUN(test_dma_info_get);
- DMA_TEST_API_RUN(test_dma_configure);
- DMA_TEST_API_RUN(test_dma_vchan_setup);
- DMA_TEST_API_RUN(test_dma_start_stop);
- DMA_TEST_API_RUN(test_dma_stats);
- DMA_TEST_API_RUN(test_dma_dump);
- DMA_TEST_API_RUN(test_dma_completed);
- DMA_TEST_API_RUN(test_dma_completed_status);
-
- testsuite_teardown();
-
- printf("Total tests : %d\n", total);
- printf("Passed : %d\n", passed);
- printf("Failed : %d\n", failed);
-
- if (failed)
- return -1;
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
+ return TEST_SKIPPED;
- return 0;
+ printf("\n### Test dmadev infrastructure using %u [%s]\n", dev_id, dev_info.dev_name);
+ test_dev_id = dev_id;
+ return unit_test_suite_runner(&dma_api_testsuite);
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v5 2/3] test/dma: test multiple vchan
2023-11-16 10:40 ` [PATCH v5 " Gowrishankar Muthukrishnan
2023-11-16 10:40 ` [PATCH v5 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
@ 2023-11-16 10:40 ` Gowrishankar Muthukrishnan
2023-11-16 10:40 ` [PATCH v5 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:40 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Support API with multiple vchan test.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev_api.c | 63 +++++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 73d4db825a..2b8a4eda62 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -260,7 +260,7 @@ test_dma_vchan_setup(void)
}
static int
-setup_one_vchan(void)
+setup_vchan(int nb_vchans)
{
struct rte_dma_vchan_conf vchan_conf = { 0 };
struct rte_dma_info dev_info = { 0 };
@@ -269,13 +269,15 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = 1;
+ dev_conf.nb_vchans = nb_vchans;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
vchan_conf.nb_desc = dev_info.min_desc;
- ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
- RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret);
+ for (int i = 0; i < nb_vchans; i++) {
+ ret = rte_dma_vchan_setup(test_dev_id, i, &vchan_conf);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan %d, %d", i, ret);
+ }
return TEST_SUCCESS;
}
@@ -294,7 +296,7 @@ test_dma_start_stop(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -312,6 +314,50 @@ test_dma_start_stop(void)
return TEST_SUCCESS;
}
+static int
+test_dma_reconfigure(void)
+{
+ struct rte_dma_conf dev_conf = { 0 };
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t cfg_vchans;
+ int ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ /* At least two vchans required for the test */
+ if (dev_info.max_vchans < 2)
+ return TEST_SKIPPED;
+
+ /* Setup one vchan for later test */
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ /* Check reconfigure and vchan setup after device stopped */
+ cfg_vchans = dev_conf.nb_vchans = (dev_info.max_vchans - 1);
+
+ ret = setup_vchan(cfg_vchans);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+ RTE_TEST_ASSERT_EQUAL(dev_info.nb_vchans, cfg_vchans, "incorrect reconfiguration");
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static int
test_dma_stats(void)
{
@@ -328,7 +374,7 @@ test_dma_stats(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
/* Check for invalid vchan */
@@ -400,7 +446,7 @@ test_dma_completed(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -459,7 +505,7 @@ test_dma_completed_status(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -517,6 +563,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_configure),
TEST_CASE(test_dma_vchan_setup),
TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_reconfigure),
TEST_CASE(test_dma_stats),
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v5 3/3] test/dma: add SG copy tests
2023-11-16 10:40 ` [PATCH v5 " Gowrishankar Muthukrishnan
2023-11-16 10:40 ` [PATCH v5 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
2023-11-16 10:40 ` [PATCH v5 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
@ 2023-11-16 10:40 ` Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:40 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Add scatter-gather copy tests.
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev.c | 139 ++++++++++++++++++++++++++++++-
app/test/test_dmadev_api.c | 164 ++++++++++++++++++++++++++++++++++---
2 files changed, 289 insertions(+), 14 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index a1505716d1..2a7eea698f 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -19,7 +19,7 @@
#define ERR_RETURN(...) do { print_err(__func__, __LINE__, __VA_ARGS__); return -1; } while (0)
#define TEST_RINGSIZE 512
-#define COPY_LEN 1024
+#define COPY_LEN 2048
static struct rte_dma_info info;
static struct rte_mempool *pool;
@@ -391,6 +391,125 @@ test_stop_start(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_enqueue_sg_copies(int16_t dev_id, uint16_t vchan)
+{
+ unsigned int src_len, dst_len, n_sge, len, i, j, k;
+ char orig_src[COPY_LEN], orig_dst[COPY_LEN];
+ struct rte_dma_info info = { 0 };
+ enum rte_dma_status_code status;
+ uint16_t id, n_src, n_dst;
+
+ if (rte_dma_info_get(dev_id, &info) < 0)
+ ERR_RETURN("Failed to get dev info");
+
+ if (info.max_sges < 2)
+ ERR_RETURN("Test needs minimum 2 SG pointers");
+
+ n_sge = info.max_sges;
+
+ for (n_src = 1; n_src <= n_sge; n_src++) {
+ for (n_dst = 1; n_dst <= n_sge; n_dst++) {
+ /* Normalize SG buffer lengths */
+ len = COPY_LEN;
+ len -= (len % (n_src * n_dst));
+ dst_len = len / n_dst;
+ src_len = len / n_src;
+
+ struct rte_dma_sge sg_src[n_sge], sg_dst[n_sge];
+ struct rte_mbuf *src[n_sge], *dst[n_sge];
+ char *src_data[n_sge], *dst_data[n_sge];
+
+ for (i = 0 ; i < len; i++)
+ orig_src[i] = rte_rand() & 0xFF;
+
+ memset(orig_dst, 0, len);
+
+ for (i = 0; i < n_src; i++) {
+ src[i] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(src[i] != NULL);
+ sg_src[i].addr = rte_pktmbuf_iova(src[i]);
+ sg_src[i].length = src_len;
+ src_data[i] = rte_pktmbuf_mtod(src[i], char *);
+ }
+
+ for (k = 0; k < n_dst; k++) {
+ dst[k] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(dst[k] != NULL);
+ sg_dst[k].addr = rte_pktmbuf_iova(dst[k]);
+ sg_dst[k].length = dst_len;
+ dst_data[k] = rte_pktmbuf_mtod(dst[k], char *);
+ }
+
+ for (i = 0; i < n_src; i++) {
+ for (j = 0; j < src_len; j++)
+ src_data[i][j] = orig_src[i * src_len + j];
+ }
+
+ for (k = 0; k < n_dst; k++)
+ memset(dst_data[k], 0, dst_len);
+
+ printf("\tsrc segs: %2d [seg len: %4d] - dst segs: %2d [seg len : %4d]\n",
+ n_src, src_len, n_dst, dst_len);
+
+ id = rte_dma_copy_sg(dev_id, vchan, sg_src, sg_dst, n_src, n_dst,
+ RTE_DMA_OP_FLAG_SUBMIT);
+
+ if (id != id_count)
+ ERR_RETURN("Error with rte_dma_copy_sg, got %u, expected %u\n",
+ id, id_count);
+
+ /* Give time for copy to finish, then check it was done */
+ await_hw(dev_id, vchan);
+
+ for (k = 0; k < n_dst; k++)
+ memcpy((&orig_dst[0] + k * dst_len), dst_data[k], dst_len);
+
+ if (memcmp(orig_src, orig_dst, COPY_LEN))
+ ERR_RETURN("Data mismatch");
+
+ /* Verify completion */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 1)
+ ERR_RETURN("Error with rte_dma_completed\n");
+
+ /* Verify expected index(id_count) */
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed and id when no job done */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed when no job done\n");
+
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed_status and id when no job done */
+ id = ~id;
+ if (rte_dma_completed_status(dev_id, vchan, 1, &id, &status) != 0)
+ ERR_RETURN("Error with rte_dma_completed_status when no job done\n");
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, 0);
+
+ for (i = 0; i < n_src; i++)
+ rte_pktmbuf_free(src[i]);
+ for (i = 0; i < n_dst; i++)
+ rte_pktmbuf_free(dst[i]);
+
+ /* Verify that completion returns nothing more */
+ if (rte_dma_completed(dev_id, 0, 1, NULL, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed in empty check\n");
+
+ id_count++;
+ }
+ }
+ return 0;
+}
+
/* Failure handling test cases - global macros and variables for those tests*/
#define COMP_BURST_SZ 16
#define OPT_FENCE(idx) ((fence && idx == 8) ? RTE_DMA_OP_FLAG_FENCE : 0)
@@ -929,6 +1048,17 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_dmadev_sg_copy_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ return ret;
+}
+
static int
test_dmadev_burst_setup(void)
{
@@ -1044,7 +1174,7 @@ test_dmadev_setup(void)
TEST_RINGSIZE * 2, /* n == num elements */
32, /* cache size */
0, /* priv size */
- 2048, /* data room size */
+ COPY_LEN + RTE_PKTMBUF_HEADROOM, /* data room size */
info.numa_node);
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
@@ -1070,6 +1200,7 @@ test_dmadev_instance(int16_t dev_id)
struct rte_dma_info dev_info;
enum {
TEST_COPY = 0,
+ TEST_COPY_SG,
TEST_START,
TEST_BURST,
TEST_ERR,
@@ -1080,6 +1211,7 @@ test_dmadev_instance(int16_t dev_id)
static struct runtest_param param[] = {
{"copy", test_enqueue_copies, 640},
+ {"sg_copy", test_enqueue_sg_copies, 1},
{"stop_start", test_stop_start, 1},
{"burst_capacity", test_burst_capacity, 1},
{"error_handling", test_completion_handling, 1},
@@ -1095,6 +1227,9 @@ test_dmadev_instance(int16_t dev_id)
TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY].name,
NULL, NULL,
runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY_SG].name,
+ test_dmadev_sg_copy_setup, NULL,
+ runtest, ¶m[TEST_COPY_SG]),
TEST_CASE_NAMED_WITH_DATA(param[TEST_START].name,
NULL, NULL,
runtest, ¶m[TEST_START]),
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 2b8a4eda62..a130e74b51 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -10,47 +10,75 @@
#include <rte_dmadev.h>
#include "test.h"
+#include "test_dmadev_api.h"
extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
+#define TEST_SG_MAX 64
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
+static char *src_sg[TEST_SG_MAX];
+static char *dst_sg[TEST_SG_MAX];
static int
testsuite_setup(void)
{
invalid_dev_id = -1;
-
- src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
- if (src == NULL)
- return -ENOMEM;
- dst = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
- if (dst == NULL) {
- rte_free(src);
- src = NULL;
- return -ENOMEM;
+ int i, rc = 0;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ src_sg[i] = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
+ if (src_sg[i] == NULL) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ dst_sg[i] = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
+ if (dst_sg[i] == NULL) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rc = -ENOMEM;
+ goto exit;
+ }
}
+ src = src_sg[0];
+ dst = dst_sg[0];
+
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT);
- return 0;
+ return rc;
+exit:
+ while (--i >= 0) {
+ rte_free(src_sg[i]);
+ rte_free(dst_sg[i]);
+ }
+
+ return rc;
}
static void
testsuite_teardown(void)
{
- rte_free(src);
+ int i;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rte_free(dst_sg[i]);
+ dst_sg[i] = NULL;
+ }
+
src = NULL;
- rte_free(dst);
dst = NULL;
/* Ensure the dmadev is stopped. */
rte_dma_stop(test_dev_id);
@@ -437,6 +465,37 @@ verify_memory(void)
return 0;
}
+static void
+sg_memory_setup(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++)
+ src_sg[i][j] = (char)j;
+
+ memset(dst_sg[i], 0, TEST_MEMCPY_SIZE);
+ }
+}
+
+static int
+sg_memory_verify(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++) {
+ if (src_sg[i][j] == dst_sg[i][j])
+ continue;
+
+ RTE_TEST_ASSERT_EQUAL(src_sg[i][j], dst_sg[i][j], "Failed to copy memory, %d %d",
+ src_sg[i][j], dst_sg[i][j]);
+ }
+ }
+
+ return 0;
+}
+
static int
test_dma_completed(void)
{
@@ -551,6 +610,86 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static int
+test_dma_sg(void)
+{
+ struct rte_dma_sge src_sge[TEST_SG_MAX], dst_sge[TEST_SG_MAX];
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t last_idx = -1;
+ bool has_error = true;
+ int n_sge, i, ret;
+ uint16_t cpl_ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
+
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ for (i = 0; i < n_sge; i++) {
+ src_sge[i].addr = rte_malloc_virt2iova(src_sg[i]);
+ src_sge[i].length = TEST_MEMCPY_SIZE;
+ dst_sge[i].addr = rte_malloc_virt2iova(dst_sg[i]);
+ dst_sge[i].length = TEST_MEMCPY_SIZE;
+ }
+
+ sg_memory_setup(n_sge);
+
+ /* Check enqueue without submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge, 0);
+ RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
+
+ /* Check DMA submit */
+ ret = rte_dma_submit(test_dev_id, 0);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ sg_memory_setup(n_sge);
+
+ /* Check for enqueue with submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge,
+ RTE_DMA_OP_FLAG_SUBMIT);
+ RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ /* Stop dmadev to make sure dmadev to a known state */
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite dma_api_testsuite = {
.suite_name = "DMA API Test Suite",
.setup = testsuite_setup,
@@ -568,6 +707,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
TEST_CASE(test_dma_completed_status),
+ TEST_CASE(test_dma_sg),
TEST_CASES_END()
}
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests
2023-11-16 10:40 ` [PATCH v5 " Gowrishankar Muthukrishnan
` (2 preceding siblings ...)
2023-11-16 10:40 ` [PATCH v5 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
@ 2023-11-16 10:59 ` Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
` (3 more replies)
3 siblings, 4 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:59 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
This patch series reworks DMA tests to follow unit test framework
followed by new vchan reconfig and SG tests.
v6:
- fixed coding style warning (to use REGISTER_DRIVER_TEST).
Gowrishankar Muthukrishnan (3):
test/dma: use unit test framework
test/dma: test multiple vchan
test/dma: add SG copy tests
app/test/test_dmadev.c | 373 +++++++++++++++++++++++++++++--------
app/test/test_dmadev_api.c | 316 +++++++++++++++++++++++--------
2 files changed, 533 insertions(+), 156 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v6 1/3] test/dma: use unit test framework
2023-11-16 10:59 ` [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
@ 2023-11-16 10:59 ` Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
` (2 subsequent siblings)
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:59 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Use unit test framework to execute DMA tests.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev.c | 234 +++++++++++++++++++++++++------------
app/test/test_dmadev_api.c | 95 +++++----------
2 files changed, 192 insertions(+), 137 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 7581fc2b4c..f4a40190e5 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -21,8 +21,12 @@
#define TEST_RINGSIZE 512
#define COPY_LEN 1024
+static struct rte_dma_info info;
static struct rte_mempool *pool;
+static bool check_err_stats;
+static int16_t test_dev_id;
static uint16_t id_count;
+static uint16_t vchan;
enum {
TEST_PARAM_REMOTE_ADDR = 0,
@@ -61,13 +65,28 @@ print_err(const char *func, int lineno, const char *format, ...)
va_end(ap);
}
+struct runtest_param {
+ const char name[NAME_MAX];
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ int iterations;
+};
+
static int
-runtest(const char *printable, int (*test_fn)(int16_t dev_id, uint16_t vchan), int iterations,
- int16_t dev_id, uint16_t vchan, bool check_err_stats)
+runtest(const void *args)
{
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ const struct runtest_param *param = args;
struct rte_dma_stats stats;
+ const char *printable;
+ int iterations;
+ int16_t dev_id;
int i;
+ printable = param->name;
+ iterations = param->iterations;
+ test_fn = param->test_fn;
+ dev_id = test_dev_id;
+
rte_dma_stats_reset(dev_id, vchan);
printf("DMA Dev %d: Running %s Tests %s\n", dev_id, printable,
check_err_stats ? " " : "(errors expected)");
@@ -911,26 +930,87 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
}
static int
-test_dmadev_instance(int16_t dev_id)
+test_dmadev_burst_setup(void)
+{
+ if (rte_dma_burst_capacity(test_dev_id, vchan) < 64) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
+ test_dev_id);
+ return TEST_SKIPPED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_dmadev_err_handling_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ /* to test error handling we can provide null pointers for source or dest in copies. This
+ * requires VA mode in DPDK, since NULL(0) is a valid physical address.
+ * We also need hardware that can report errors back.
+ */
+ if (rte_eal_iova_mode() != RTE_IOVA_VA)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n",
+ test_dev_id);
+ else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: device does not report errors, skipping error handling tests\n",
+ test_dev_id);
+ else
+ ret = TEST_SUCCESS;
+
+ return ret;
+}
+
+static int
+test_dmadev_fill_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: No device fill support, skipping fill tests\n", test_dev_id);
+ ret = TEST_SKIPPED;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_autofree_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
+ dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
+ if (prepare_m2d_auto_free(test_dev_id, vchan) != 0)
+ return ret;
+
+ ret = TEST_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_setup(void)
{
-#define CHECK_ERRS true
+ int16_t dev_id = test_dev_id;
struct rte_dma_stats stats;
- struct rte_dma_info info;
const struct rte_dma_conf conf = { .nb_vchans = 1};
const struct rte_dma_vchan_conf qconf = {
.direction = RTE_DMA_DIR_MEM_TO_MEM,
.nb_desc = TEST_RINGSIZE,
};
- const int vchan = 0;
int ret;
ret = rte_dma_info_get(dev_id, &info);
if (ret != 0)
ERR_RETURN("Error with rte_dma_info_get()\n");
- printf("\n### Test dmadev instance %u [%s]\n",
- dev_id, info.dev_name);
-
if (info.max_vchans < 1)
ERR_RETURN("Error, no channels available on device id %u\n", dev_id);
@@ -969,76 +1049,82 @@ test_dmadev_instance(int16_t dev_id)
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
- /* run the test cases, use many iterations to ensure UINT16_MAX id wraparound */
- if (runtest("copy", test_enqueue_copies, 640, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run tests stopping/starting devices and check jobs still work after restart */
- if (runtest("stop-start", test_stop_start, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run some burst capacity tests */
- if (rte_dma_burst_capacity(dev_id, vchan) < 64)
- printf("DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
- dev_id);
- else if (runtest("burst capacity", test_burst_capacity, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* to test error handling we can provide null pointers for source or dest in copies. This
- * requires VA mode in DPDK, since NULL(0) is a valid physical address.
- * We also need hardware that can report errors back.
- */
- if (rte_eal_iova_mode() != RTE_IOVA_VA)
- printf("DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n", dev_id);
- else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
- printf("DMA Dev %u: device does not report errors, skipping error handling tests\n",
- dev_id);
- else if (runtest("error handling", test_completion_handling, 1,
- dev_id, vchan, !CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0)
- printf("DMA Dev %u: No device fill support, skipping fill tests\n", dev_id);
- else if (runtest("fill", test_enqueue_fill, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
- dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
- if (prepare_m2d_auto_free(dev_id, vchan) != 0)
- goto err;
- if (runtest("m2d_auto_free", test_m2d_auto_free, 128, dev_id, vchan,
- CHECK_ERRS) < 0)
- goto err;
- }
-
- rte_mempool_free(pool);
-
- if (rte_dma_stop(dev_id) < 0)
- ERR_RETURN("Error stopping device %u\n", dev_id);
+ check_err_stats = false;
+ vchan = 0;
- rte_dma_stats_reset(dev_id, vchan);
return 0;
+}
-err:
+static void
+test_dmadev_teardown(void)
+{
rte_mempool_free(pool);
- rte_dma_stop(dev_id);
- return -1;
+ rte_dma_stop(test_dev_id);
+ rte_dma_stats_reset(test_dev_id, vchan);
+ test_dev_id = -EINVAL;
}
static int
-test_apis(void)
+test_dmadev_instance(int16_t dev_id)
{
- const char *pmd = "dma_skeleton";
- int id;
+ struct rte_dma_info dev_info;
+ enum {
+ TEST_COPY = 0,
+ TEST_START,
+ TEST_BURST,
+ TEST_ERR,
+ TEST_FILL,
+ TEST_M2D,
+ TEST_END
+ };
+
+ static struct runtest_param param[] = {
+ {"copy", test_enqueue_copies, 640},
+ {"stop_start", test_stop_start, 1},
+ {"burst_capacity", test_burst_capacity, 1},
+ {"error_handling", test_completion_handling, 1},
+ {"fill", test_enqueue_fill, 1},
+ {"m2d_auto_free", test_m2d_auto_free, 128},
+ };
+
+ static struct unit_test_suite ts = {
+ .suite_name = "DMA dev instance testsuite",
+ .setup = test_dmadev_setup,
+ .teardown = test_dmadev_teardown,
+ .unit_test_cases = {
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY].name,
+ NULL, NULL,
+ runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_START].name,
+ NULL, NULL,
+ runtest, ¶m[TEST_START]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_BURST].name,
+ test_dmadev_burst_setup, NULL,
+ runtest, ¶m[TEST_BURST]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_ERR].name,
+ test_dmadev_err_handling_setup, NULL,
+ runtest, ¶m[TEST_ERR]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_FILL].name,
+ test_dmadev_fill_setup, NULL,
+ runtest, ¶m[TEST_FILL]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_M2D].name,
+ test_dmadev_autofree_setup, NULL,
+ runtest, ¶m[TEST_M2D]),
+ TEST_CASES_END()
+ }
+ };
+
int ret;
- /* attempt to create skeleton instance - ignore errors due to one being already present */
- rte_vdev_init(pmd, NULL);
- id = rte_dma_get_dev_id_by_name(pmd);
- if (id < 0)
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
return TEST_SKIPPED;
- printf("\n### Test dmadev infrastructure using skeleton driver\n");
- ret = test_dma_api(id);
+
+ test_dev_id = dev_id;
+ printf("\n### Test dmadev instance %u [%s]\n",
+ test_dev_id, dev_info.dev_name);
+
+ ret = unit_test_suite_runner(&ts);
+ test_dev_id = -EINVAL;
return ret;
}
@@ -1083,20 +1169,24 @@ parse_dma_env_var(void)
static int
test_dma(void)
{
+ const char *pmd = "dma_skeleton";
int i;
parse_dma_env_var();
- /* basic sanity on dmadev infrastructure */
- if (test_apis() < 0)
- ERR_RETURN("Error performing API tests\n");
+ /* attempt to create skeleton instance - ignore errors due to one being already present*/
+ rte_vdev_init(pmd, NULL);
if (rte_dma_count_avail() == 0)
return TEST_SKIPPED;
- RTE_DMA_FOREACH_DEV(i)
+ RTE_DMA_FOREACH_DEV(i) {
+ if (test_dma_api(i) < 0)
+ ERR_RETURN("Error performing API tests\n");
+
if (test_dmadev_instance(i) < 0)
ERR_RETURN("Error, test failure for device %d\n", i);
+ }
return 0;
}
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 4a181af90a..73d4db825a 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -9,31 +9,22 @@
#include <rte_test.h>
#include <rte_dmadev.h>
-extern int test_dma_api(uint16_t dev_id);
+#include "test.h"
-#define DMA_TEST_API_RUN(test) \
- testsuite_run_test(test, #test)
+extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
-#define TEST_SUCCESS 0
-#define TEST_FAILED -1
-
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
-static int total;
-static int passed;
-static int failed;
-
static int
-testsuite_setup(int16_t dev_id)
+testsuite_setup(void)
{
- test_dev_id = dev_id;
invalid_dev_id = -1;
src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
@@ -46,10 +37,6 @@ testsuite_setup(int16_t dev_id)
return -ENOMEM;
}
- total = 0;
- passed = 0;
- failed = 0;
-
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
@@ -71,25 +58,6 @@ testsuite_teardown(void)
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO);
}
-static void
-testsuite_run_test(int (*test)(void), const char *name)
-{
- int ret = 0;
-
- if (test) {
- ret = test();
- if (ret < 0) {
- failed++;
- printf("%s Failed\n", name);
- } else {
- passed++;
- printf("%s Passed\n", name);
- }
- }
-
- total++;
-}
-
static int
test_dma_get_dev_id_by_name(void)
{
@@ -301,7 +269,7 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = dev_info.max_vchans;
+ dev_conf.nb_vchans = 1;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
@@ -537,38 +505,35 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static struct unit_test_suite dma_api_testsuite = {
+ .suite_name = "DMA API Test Suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE(test_dma_get_dev_id_by_name),
+ TEST_CASE(test_dma_is_valid_dev),
+ TEST_CASE(test_dma_count),
+ TEST_CASE(test_dma_info_get),
+ TEST_CASE(test_dma_configure),
+ TEST_CASE(test_dma_vchan_setup),
+ TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_stats),
+ TEST_CASE(test_dma_dump),
+ TEST_CASE(test_dma_completed),
+ TEST_CASE(test_dma_completed_status),
+ TEST_CASES_END()
+ }
+};
+
int
test_dma_api(uint16_t dev_id)
{
- int ret = testsuite_setup(dev_id);
- if (ret) {
- printf("testsuite setup fail!\n");
- return -1;
- }
+ struct rte_dma_info dev_info;
- /* If the testcase exit successfully, ensure that the test dmadev exist
- * and the dmadev is in the stopped state.
- */
- DMA_TEST_API_RUN(test_dma_get_dev_id_by_name);
- DMA_TEST_API_RUN(test_dma_is_valid_dev);
- DMA_TEST_API_RUN(test_dma_count);
- DMA_TEST_API_RUN(test_dma_info_get);
- DMA_TEST_API_RUN(test_dma_configure);
- DMA_TEST_API_RUN(test_dma_vchan_setup);
- DMA_TEST_API_RUN(test_dma_start_stop);
- DMA_TEST_API_RUN(test_dma_stats);
- DMA_TEST_API_RUN(test_dma_dump);
- DMA_TEST_API_RUN(test_dma_completed);
- DMA_TEST_API_RUN(test_dma_completed_status);
-
- testsuite_teardown();
-
- printf("Total tests : %d\n", total);
- printf("Passed : %d\n", passed);
- printf("Failed : %d\n", failed);
-
- if (failed)
- return -1;
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
+ return TEST_SKIPPED;
- return 0;
+ printf("\n### Test dmadev infrastructure using %u [%s]\n", dev_id, dev_info.dev_name);
+ test_dev_id = dev_id;
+ return unit_test_suite_runner(&dma_api_testsuite);
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v6 2/3] test/dma: test multiple vchan
2023-11-16 10:59 ` [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
@ 2023-11-16 10:59 ` Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:59 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Support API with multiple vchan test.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev_api.c | 63 +++++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 73d4db825a..2b8a4eda62 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -260,7 +260,7 @@ test_dma_vchan_setup(void)
}
static int
-setup_one_vchan(void)
+setup_vchan(int nb_vchans)
{
struct rte_dma_vchan_conf vchan_conf = { 0 };
struct rte_dma_info dev_info = { 0 };
@@ -269,13 +269,15 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = 1;
+ dev_conf.nb_vchans = nb_vchans;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
vchan_conf.nb_desc = dev_info.min_desc;
- ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
- RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret);
+ for (int i = 0; i < nb_vchans; i++) {
+ ret = rte_dma_vchan_setup(test_dev_id, i, &vchan_conf);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan %d, %d", i, ret);
+ }
return TEST_SUCCESS;
}
@@ -294,7 +296,7 @@ test_dma_start_stop(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -312,6 +314,50 @@ test_dma_start_stop(void)
return TEST_SUCCESS;
}
+static int
+test_dma_reconfigure(void)
+{
+ struct rte_dma_conf dev_conf = { 0 };
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t cfg_vchans;
+ int ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ /* At least two vchans required for the test */
+ if (dev_info.max_vchans < 2)
+ return TEST_SKIPPED;
+
+ /* Setup one vchan for later test */
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ /* Check reconfigure and vchan setup after device stopped */
+ cfg_vchans = dev_conf.nb_vchans = (dev_info.max_vchans - 1);
+
+ ret = setup_vchan(cfg_vchans);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+ RTE_TEST_ASSERT_EQUAL(dev_info.nb_vchans, cfg_vchans, "incorrect reconfiguration");
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static int
test_dma_stats(void)
{
@@ -328,7 +374,7 @@ test_dma_stats(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
/* Check for invalid vchan */
@@ -400,7 +446,7 @@ test_dma_completed(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -459,7 +505,7 @@ test_dma_completed_status(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -517,6 +563,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_configure),
TEST_CASE(test_dma_vchan_setup),
TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_reconfigure),
TEST_CASE(test_dma_stats),
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v6 3/3] test/dma: add SG copy tests
2023-11-16 10:59 ` [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
2023-11-16 10:59 ` [PATCH v6 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
@ 2023-11-16 10:59 ` Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 10:59 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Add scatter-gather copy tests.
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev.c | 139 ++++++++++++++++++++++++++++++-
app/test/test_dmadev_api.c | 164 ++++++++++++++++++++++++++++++++++---
2 files changed, 289 insertions(+), 14 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index f4a40190e5..d426ea0a85 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -19,7 +19,7 @@
#define ERR_RETURN(...) do { print_err(__func__, __LINE__, __VA_ARGS__); return -1; } while (0)
#define TEST_RINGSIZE 512
-#define COPY_LEN 1024
+#define COPY_LEN 2048
static struct rte_dma_info info;
static struct rte_mempool *pool;
@@ -391,6 +391,125 @@ test_stop_start(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_enqueue_sg_copies(int16_t dev_id, uint16_t vchan)
+{
+ unsigned int src_len, dst_len, n_sge, len, i, j, k;
+ char orig_src[COPY_LEN], orig_dst[COPY_LEN];
+ struct rte_dma_info info = { 0 };
+ enum rte_dma_status_code status;
+ uint16_t id, n_src, n_dst;
+
+ if (rte_dma_info_get(dev_id, &info) < 0)
+ ERR_RETURN("Failed to get dev info");
+
+ if (info.max_sges < 2)
+ ERR_RETURN("Test needs minimum 2 SG pointers");
+
+ n_sge = info.max_sges;
+
+ for (n_src = 1; n_src <= n_sge; n_src++) {
+ for (n_dst = 1; n_dst <= n_sge; n_dst++) {
+ /* Normalize SG buffer lengths */
+ len = COPY_LEN;
+ len -= (len % (n_src * n_dst));
+ dst_len = len / n_dst;
+ src_len = len / n_src;
+
+ struct rte_dma_sge sg_src[n_sge], sg_dst[n_sge];
+ struct rte_mbuf *src[n_sge], *dst[n_sge];
+ char *src_data[n_sge], *dst_data[n_sge];
+
+ for (i = 0 ; i < len; i++)
+ orig_src[i] = rte_rand() & 0xFF;
+
+ memset(orig_dst, 0, len);
+
+ for (i = 0; i < n_src; i++) {
+ src[i] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(src[i] != NULL);
+ sg_src[i].addr = rte_pktmbuf_iova(src[i]);
+ sg_src[i].length = src_len;
+ src_data[i] = rte_pktmbuf_mtod(src[i], char *);
+ }
+
+ for (k = 0; k < n_dst; k++) {
+ dst[k] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(dst[k] != NULL);
+ sg_dst[k].addr = rte_pktmbuf_iova(dst[k]);
+ sg_dst[k].length = dst_len;
+ dst_data[k] = rte_pktmbuf_mtod(dst[k], char *);
+ }
+
+ for (i = 0; i < n_src; i++) {
+ for (j = 0; j < src_len; j++)
+ src_data[i][j] = orig_src[i * src_len + j];
+ }
+
+ for (k = 0; k < n_dst; k++)
+ memset(dst_data[k], 0, dst_len);
+
+ printf("\tsrc segs: %2d [seg len: %4d] - dst segs: %2d [seg len : %4d]\n",
+ n_src, src_len, n_dst, dst_len);
+
+ id = rte_dma_copy_sg(dev_id, vchan, sg_src, sg_dst, n_src, n_dst,
+ RTE_DMA_OP_FLAG_SUBMIT);
+
+ if (id != id_count)
+ ERR_RETURN("Error with rte_dma_copy_sg, got %u, expected %u\n",
+ id, id_count);
+
+ /* Give time for copy to finish, then check it was done */
+ await_hw(dev_id, vchan);
+
+ for (k = 0; k < n_dst; k++)
+ memcpy((&orig_dst[0] + k * dst_len), dst_data[k], dst_len);
+
+ if (memcmp(orig_src, orig_dst, COPY_LEN))
+ ERR_RETURN("Data mismatch");
+
+ /* Verify completion */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 1)
+ ERR_RETURN("Error with rte_dma_completed\n");
+
+ /* Verify expected index(id_count) */
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed and id when no job done */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed when no job done\n");
+
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed_status and id when no job done */
+ id = ~id;
+ if (rte_dma_completed_status(dev_id, vchan, 1, &id, &status) != 0)
+ ERR_RETURN("Error with rte_dma_completed_status when no job done\n");
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, 0);
+
+ for (i = 0; i < n_src; i++)
+ rte_pktmbuf_free(src[i]);
+ for (i = 0; i < n_dst; i++)
+ rte_pktmbuf_free(dst[i]);
+
+ /* Verify that completion returns nothing more */
+ if (rte_dma_completed(dev_id, 0, 1, NULL, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed in empty check\n");
+
+ id_count++;
+ }
+ }
+ return 0;
+}
+
/* Failure handling test cases - global macros and variables for those tests*/
#define COMP_BURST_SZ 16
#define OPT_FENCE(idx) ((fence && idx == 8) ? RTE_DMA_OP_FLAG_FENCE : 0)
@@ -929,6 +1048,17 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_dmadev_sg_copy_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ return ret;
+}
+
static int
test_dmadev_burst_setup(void)
{
@@ -1044,7 +1174,7 @@ test_dmadev_setup(void)
TEST_RINGSIZE * 2, /* n == num elements */
32, /* cache size */
0, /* priv size */
- 2048, /* data room size */
+ COPY_LEN + RTE_PKTMBUF_HEADROOM, /* data room size */
info.numa_node);
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
@@ -1070,6 +1200,7 @@ test_dmadev_instance(int16_t dev_id)
struct rte_dma_info dev_info;
enum {
TEST_COPY = 0,
+ TEST_COPY_SG,
TEST_START,
TEST_BURST,
TEST_ERR,
@@ -1080,6 +1211,7 @@ test_dmadev_instance(int16_t dev_id)
static struct runtest_param param[] = {
{"copy", test_enqueue_copies, 640},
+ {"sg_copy", test_enqueue_sg_copies, 1},
{"stop_start", test_stop_start, 1},
{"burst_capacity", test_burst_capacity, 1},
{"error_handling", test_completion_handling, 1},
@@ -1095,6 +1227,9 @@ test_dmadev_instance(int16_t dev_id)
TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY].name,
NULL, NULL,
runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA(param[TEST_COPY_SG].name,
+ test_dmadev_sg_copy_setup, NULL,
+ runtest, ¶m[TEST_COPY_SG]),
TEST_CASE_NAMED_WITH_DATA(param[TEST_START].name,
NULL, NULL,
runtest, ¶m[TEST_START]),
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 2b8a4eda62..a130e74b51 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -10,47 +10,75 @@
#include <rte_dmadev.h>
#include "test.h"
+#include "test_dmadev_api.h"
extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
+#define TEST_SG_MAX 64
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
+static char *src_sg[TEST_SG_MAX];
+static char *dst_sg[TEST_SG_MAX];
static int
testsuite_setup(void)
{
invalid_dev_id = -1;
-
- src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
- if (src == NULL)
- return -ENOMEM;
- dst = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
- if (dst == NULL) {
- rte_free(src);
- src = NULL;
- return -ENOMEM;
+ int i, rc = 0;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ src_sg[i] = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
+ if (src_sg[i] == NULL) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ dst_sg[i] = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
+ if (dst_sg[i] == NULL) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rc = -ENOMEM;
+ goto exit;
+ }
}
+ src = src_sg[0];
+ dst = dst_sg[0];
+
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT);
- return 0;
+ return rc;
+exit:
+ while (--i >= 0) {
+ rte_free(src_sg[i]);
+ rte_free(dst_sg[i]);
+ }
+
+ return rc;
}
static void
testsuite_teardown(void)
{
- rte_free(src);
+ int i;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rte_free(dst_sg[i]);
+ dst_sg[i] = NULL;
+ }
+
src = NULL;
- rte_free(dst);
dst = NULL;
/* Ensure the dmadev is stopped. */
rte_dma_stop(test_dev_id);
@@ -437,6 +465,37 @@ verify_memory(void)
return 0;
}
+static void
+sg_memory_setup(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++)
+ src_sg[i][j] = (char)j;
+
+ memset(dst_sg[i], 0, TEST_MEMCPY_SIZE);
+ }
+}
+
+static int
+sg_memory_verify(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++) {
+ if (src_sg[i][j] == dst_sg[i][j])
+ continue;
+
+ RTE_TEST_ASSERT_EQUAL(src_sg[i][j], dst_sg[i][j], "Failed to copy memory, %d %d",
+ src_sg[i][j], dst_sg[i][j]);
+ }
+ }
+
+ return 0;
+}
+
static int
test_dma_completed(void)
{
@@ -551,6 +610,86 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static int
+test_dma_sg(void)
+{
+ struct rte_dma_sge src_sge[TEST_SG_MAX], dst_sge[TEST_SG_MAX];
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t last_idx = -1;
+ bool has_error = true;
+ int n_sge, i, ret;
+ uint16_t cpl_ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
+
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ for (i = 0; i < n_sge; i++) {
+ src_sge[i].addr = rte_malloc_virt2iova(src_sg[i]);
+ src_sge[i].length = TEST_MEMCPY_SIZE;
+ dst_sge[i].addr = rte_malloc_virt2iova(dst_sg[i]);
+ dst_sge[i].length = TEST_MEMCPY_SIZE;
+ }
+
+ sg_memory_setup(n_sge);
+
+ /* Check enqueue without submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge, 0);
+ RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
+
+ /* Check DMA submit */
+ ret = rte_dma_submit(test_dev_id, 0);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ sg_memory_setup(n_sge);
+
+ /* Check for enqueue with submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge,
+ RTE_DMA_OP_FLAG_SUBMIT);
+ RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ /* Stop dmadev to make sure dmadev to a known state */
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite dma_api_testsuite = {
.suite_name = "DMA API Test Suite",
.setup = testsuite_setup,
@@ -568,6 +707,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
TEST_CASE(test_dma_completed_status),
+ TEST_CASE(test_dma_sg),
TEST_CASES_END()
}
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests
2023-11-16 10:59 ` [PATCH v6 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
` (2 preceding siblings ...)
2023-11-16 10:59 ` [PATCH v6 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
@ 2023-11-16 13:27 ` Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
` (3 more replies)
3 siblings, 4 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 13:27 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
This patch series reworks DMA tests to follow unit test framework
followed by new vchan reconfig and SG tests.
v7:
- Addressed compilation issue in Windows platform.
Gowrishankar Muthukrishnan (3):
test/dma: use unit test framework
test/dma: test multiple vchan
test/dma: add SG copy tests
app/test/test_dmadev.c | 373 +++++++++++++++++++++++++++++--------
app/test/test_dmadev_api.c | 316 +++++++++++++++++++++++--------
2 files changed, 533 insertions(+), 156 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v7 1/3] test/dma: use unit test framework
2023-11-16 13:27 ` [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
@ 2023-11-16 13:27 ` Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
` (2 subsequent siblings)
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 13:27 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Use unit test framework to execute DMA tests.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
v7:
- Used string const in unit_test_cases name member to avoid
compilation failure in Windows platform.
---
app/test/test_dmadev.c | 234 +++++++++++++++++++++++++------------
app/test/test_dmadev_api.c | 95 +++++----------
2 files changed, 192 insertions(+), 137 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 7581fc2b4c..2d20e716d2 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -21,8 +21,12 @@
#define TEST_RINGSIZE 512
#define COPY_LEN 1024
+static struct rte_dma_info info;
static struct rte_mempool *pool;
+static bool check_err_stats;
+static int16_t test_dev_id;
static uint16_t id_count;
+static uint16_t vchan;
enum {
TEST_PARAM_REMOTE_ADDR = 0,
@@ -61,13 +65,28 @@ print_err(const char *func, int lineno, const char *format, ...)
va_end(ap);
}
+struct runtest_param {
+ const char name[NAME_MAX];
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ int iterations;
+};
+
static int
-runtest(const char *printable, int (*test_fn)(int16_t dev_id, uint16_t vchan), int iterations,
- int16_t dev_id, uint16_t vchan, bool check_err_stats)
+runtest(const void *args)
{
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ const struct runtest_param *param = args;
struct rte_dma_stats stats;
+ const char *printable;
+ int iterations;
+ int16_t dev_id;
int i;
+ printable = param->name;
+ iterations = param->iterations;
+ test_fn = param->test_fn;
+ dev_id = test_dev_id;
+
rte_dma_stats_reset(dev_id, vchan);
printf("DMA Dev %d: Running %s Tests %s\n", dev_id, printable,
check_err_stats ? " " : "(errors expected)");
@@ -911,26 +930,87 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
}
static int
-test_dmadev_instance(int16_t dev_id)
+test_dmadev_burst_setup(void)
+{
+ if (rte_dma_burst_capacity(test_dev_id, vchan) < 64) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
+ test_dev_id);
+ return TEST_SKIPPED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_dmadev_err_handling_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ /* to test error handling we can provide null pointers for source or dest in copies. This
+ * requires VA mode in DPDK, since NULL(0) is a valid physical address.
+ * We also need hardware that can report errors back.
+ */
+ if (rte_eal_iova_mode() != RTE_IOVA_VA)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n",
+ test_dev_id);
+ else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: device does not report errors, skipping error handling tests\n",
+ test_dev_id);
+ else
+ ret = TEST_SUCCESS;
+
+ return ret;
+}
+
+static int
+test_dmadev_fill_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: No device fill support, skipping fill tests\n", test_dev_id);
+ ret = TEST_SKIPPED;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_autofree_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
+ dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
+ if (prepare_m2d_auto_free(test_dev_id, vchan) != 0)
+ return ret;
+
+ ret = TEST_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_setup(void)
{
-#define CHECK_ERRS true
+ int16_t dev_id = test_dev_id;
struct rte_dma_stats stats;
- struct rte_dma_info info;
const struct rte_dma_conf conf = { .nb_vchans = 1};
const struct rte_dma_vchan_conf qconf = {
.direction = RTE_DMA_DIR_MEM_TO_MEM,
.nb_desc = TEST_RINGSIZE,
};
- const int vchan = 0;
int ret;
ret = rte_dma_info_get(dev_id, &info);
if (ret != 0)
ERR_RETURN("Error with rte_dma_info_get()\n");
- printf("\n### Test dmadev instance %u [%s]\n",
- dev_id, info.dev_name);
-
if (info.max_vchans < 1)
ERR_RETURN("Error, no channels available on device id %u\n", dev_id);
@@ -969,76 +1049,82 @@ test_dmadev_instance(int16_t dev_id)
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
- /* run the test cases, use many iterations to ensure UINT16_MAX id wraparound */
- if (runtest("copy", test_enqueue_copies, 640, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run tests stopping/starting devices and check jobs still work after restart */
- if (runtest("stop-start", test_stop_start, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run some burst capacity tests */
- if (rte_dma_burst_capacity(dev_id, vchan) < 64)
- printf("DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
- dev_id);
- else if (runtest("burst capacity", test_burst_capacity, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* to test error handling we can provide null pointers for source or dest in copies. This
- * requires VA mode in DPDK, since NULL(0) is a valid physical address.
- * We also need hardware that can report errors back.
- */
- if (rte_eal_iova_mode() != RTE_IOVA_VA)
- printf("DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n", dev_id);
- else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
- printf("DMA Dev %u: device does not report errors, skipping error handling tests\n",
- dev_id);
- else if (runtest("error handling", test_completion_handling, 1,
- dev_id, vchan, !CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0)
- printf("DMA Dev %u: No device fill support, skipping fill tests\n", dev_id);
- else if (runtest("fill", test_enqueue_fill, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
- dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
- if (prepare_m2d_auto_free(dev_id, vchan) != 0)
- goto err;
- if (runtest("m2d_auto_free", test_m2d_auto_free, 128, dev_id, vchan,
- CHECK_ERRS) < 0)
- goto err;
- }
-
- rte_mempool_free(pool);
-
- if (rte_dma_stop(dev_id) < 0)
- ERR_RETURN("Error stopping device %u\n", dev_id);
+ check_err_stats = false;
+ vchan = 0;
- rte_dma_stats_reset(dev_id, vchan);
return 0;
+}
-err:
+static void
+test_dmadev_teardown(void)
+{
rte_mempool_free(pool);
- rte_dma_stop(dev_id);
- return -1;
+ rte_dma_stop(test_dev_id);
+ rte_dma_stats_reset(test_dev_id, vchan);
+ test_dev_id = -EINVAL;
}
static int
-test_apis(void)
+test_dmadev_instance(int16_t dev_id)
{
- const char *pmd = "dma_skeleton";
- int id;
+ struct rte_dma_info dev_info;
+ enum {
+ TEST_COPY = 0,
+ TEST_START,
+ TEST_BURST,
+ TEST_ERR,
+ TEST_FILL,
+ TEST_M2D,
+ TEST_END
+ };
+
+ static struct runtest_param param[] = {
+ {"copy", test_enqueue_copies, 640},
+ {"stop_start", test_stop_start, 1},
+ {"burst_capacity", test_burst_capacity, 1},
+ {"error_handling", test_completion_handling, 1},
+ {"fill", test_enqueue_fill, 1},
+ {"m2d_auto_free", test_m2d_auto_free, 128},
+ };
+
+ static struct unit_test_suite ts = {
+ .suite_name = "DMA dev instance testsuite",
+ .setup = test_dmadev_setup,
+ .teardown = test_dmadev_teardown,
+ .unit_test_cases = {
+ TEST_CASE_NAMED_WITH_DATA("copy",
+ NULL, NULL,
+ runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA("stop_start",
+ NULL, NULL,
+ runtest, ¶m[TEST_START]),
+ TEST_CASE_NAMED_WITH_DATA("burst_capacity",
+ test_dmadev_burst_setup, NULL,
+ runtest, ¶m[TEST_BURST]),
+ TEST_CASE_NAMED_WITH_DATA("error_handling",
+ test_dmadev_err_handling_setup, NULL,
+ runtest, ¶m[TEST_ERR]),
+ TEST_CASE_NAMED_WITH_DATA("fill",
+ test_dmadev_fill_setup, NULL,
+ runtest, ¶m[TEST_FILL]),
+ TEST_CASE_NAMED_WITH_DATA("m2d_autofree",
+ test_dmadev_autofree_setup, NULL,
+ runtest, ¶m[TEST_M2D]),
+ TEST_CASES_END()
+ }
+ };
+
int ret;
- /* attempt to create skeleton instance - ignore errors due to one being already present */
- rte_vdev_init(pmd, NULL);
- id = rte_dma_get_dev_id_by_name(pmd);
- if (id < 0)
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
return TEST_SKIPPED;
- printf("\n### Test dmadev infrastructure using skeleton driver\n");
- ret = test_dma_api(id);
+
+ test_dev_id = dev_id;
+ printf("\n### Test dmadev instance %u [%s]\n",
+ test_dev_id, dev_info.dev_name);
+
+ ret = unit_test_suite_runner(&ts);
+ test_dev_id = -EINVAL;
return ret;
}
@@ -1083,20 +1169,24 @@ parse_dma_env_var(void)
static int
test_dma(void)
{
+ const char *pmd = "dma_skeleton";
int i;
parse_dma_env_var();
- /* basic sanity on dmadev infrastructure */
- if (test_apis() < 0)
- ERR_RETURN("Error performing API tests\n");
+ /* attempt to create skeleton instance - ignore errors due to one being already present*/
+ rte_vdev_init(pmd, NULL);
if (rte_dma_count_avail() == 0)
return TEST_SKIPPED;
- RTE_DMA_FOREACH_DEV(i)
+ RTE_DMA_FOREACH_DEV(i) {
+ if (test_dma_api(i) < 0)
+ ERR_RETURN("Error performing API tests\n");
+
if (test_dmadev_instance(i) < 0)
ERR_RETURN("Error, test failure for device %d\n", i);
+ }
return 0;
}
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 4a181af90a..73d4db825a 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -9,31 +9,22 @@
#include <rte_test.h>
#include <rte_dmadev.h>
-extern int test_dma_api(uint16_t dev_id);
+#include "test.h"
-#define DMA_TEST_API_RUN(test) \
- testsuite_run_test(test, #test)
+extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
-#define TEST_SUCCESS 0
-#define TEST_FAILED -1
-
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
-static int total;
-static int passed;
-static int failed;
-
static int
-testsuite_setup(int16_t dev_id)
+testsuite_setup(void)
{
- test_dev_id = dev_id;
invalid_dev_id = -1;
src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
@@ -46,10 +37,6 @@ testsuite_setup(int16_t dev_id)
return -ENOMEM;
}
- total = 0;
- passed = 0;
- failed = 0;
-
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
@@ -71,25 +58,6 @@ testsuite_teardown(void)
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO);
}
-static void
-testsuite_run_test(int (*test)(void), const char *name)
-{
- int ret = 0;
-
- if (test) {
- ret = test();
- if (ret < 0) {
- failed++;
- printf("%s Failed\n", name);
- } else {
- passed++;
- printf("%s Passed\n", name);
- }
- }
-
- total++;
-}
-
static int
test_dma_get_dev_id_by_name(void)
{
@@ -301,7 +269,7 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = dev_info.max_vchans;
+ dev_conf.nb_vchans = 1;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
@@ -537,38 +505,35 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static struct unit_test_suite dma_api_testsuite = {
+ .suite_name = "DMA API Test Suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE(test_dma_get_dev_id_by_name),
+ TEST_CASE(test_dma_is_valid_dev),
+ TEST_CASE(test_dma_count),
+ TEST_CASE(test_dma_info_get),
+ TEST_CASE(test_dma_configure),
+ TEST_CASE(test_dma_vchan_setup),
+ TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_stats),
+ TEST_CASE(test_dma_dump),
+ TEST_CASE(test_dma_completed),
+ TEST_CASE(test_dma_completed_status),
+ TEST_CASES_END()
+ }
+};
+
int
test_dma_api(uint16_t dev_id)
{
- int ret = testsuite_setup(dev_id);
- if (ret) {
- printf("testsuite setup fail!\n");
- return -1;
- }
+ struct rte_dma_info dev_info;
- /* If the testcase exit successfully, ensure that the test dmadev exist
- * and the dmadev is in the stopped state.
- */
- DMA_TEST_API_RUN(test_dma_get_dev_id_by_name);
- DMA_TEST_API_RUN(test_dma_is_valid_dev);
- DMA_TEST_API_RUN(test_dma_count);
- DMA_TEST_API_RUN(test_dma_info_get);
- DMA_TEST_API_RUN(test_dma_configure);
- DMA_TEST_API_RUN(test_dma_vchan_setup);
- DMA_TEST_API_RUN(test_dma_start_stop);
- DMA_TEST_API_RUN(test_dma_stats);
- DMA_TEST_API_RUN(test_dma_dump);
- DMA_TEST_API_RUN(test_dma_completed);
- DMA_TEST_API_RUN(test_dma_completed_status);
-
- testsuite_teardown();
-
- printf("Total tests : %d\n", total);
- printf("Passed : %d\n", passed);
- printf("Failed : %d\n", failed);
-
- if (failed)
- return -1;
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
+ return TEST_SKIPPED;
- return 0;
+ printf("\n### Test dmadev infrastructure using %u [%s]\n", dev_id, dev_info.dev_name);
+ test_dev_id = dev_id;
+ return unit_test_suite_runner(&dma_api_testsuite);
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v7 2/3] test/dma: test multiple vchan
2023-11-16 13:27 ` [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
@ 2023-11-16 13:27 ` Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 13:27 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Support API with multiple vchan test.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev_api.c | 63 +++++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 73d4db825a..2b8a4eda62 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -260,7 +260,7 @@ test_dma_vchan_setup(void)
}
static int
-setup_one_vchan(void)
+setup_vchan(int nb_vchans)
{
struct rte_dma_vchan_conf vchan_conf = { 0 };
struct rte_dma_info dev_info = { 0 };
@@ -269,13 +269,15 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = 1;
+ dev_conf.nb_vchans = nb_vchans;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
vchan_conf.nb_desc = dev_info.min_desc;
- ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
- RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret);
+ for (int i = 0; i < nb_vchans; i++) {
+ ret = rte_dma_vchan_setup(test_dev_id, i, &vchan_conf);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan %d, %d", i, ret);
+ }
return TEST_SUCCESS;
}
@@ -294,7 +296,7 @@ test_dma_start_stop(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -312,6 +314,50 @@ test_dma_start_stop(void)
return TEST_SUCCESS;
}
+static int
+test_dma_reconfigure(void)
+{
+ struct rte_dma_conf dev_conf = { 0 };
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t cfg_vchans;
+ int ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ /* At least two vchans required for the test */
+ if (dev_info.max_vchans < 2)
+ return TEST_SKIPPED;
+
+ /* Setup one vchan for later test */
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ /* Check reconfigure and vchan setup after device stopped */
+ cfg_vchans = dev_conf.nb_vchans = (dev_info.max_vchans - 1);
+
+ ret = setup_vchan(cfg_vchans);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+ RTE_TEST_ASSERT_EQUAL(dev_info.nb_vchans, cfg_vchans, "incorrect reconfiguration");
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static int
test_dma_stats(void)
{
@@ -328,7 +374,7 @@ test_dma_stats(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
/* Check for invalid vchan */
@@ -400,7 +446,7 @@ test_dma_completed(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -459,7 +505,7 @@ test_dma_completed_status(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -517,6 +563,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_configure),
TEST_CASE(test_dma_vchan_setup),
TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_reconfigure),
TEST_CASE(test_dma_stats),
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v7 3/3] test/dma: add SG copy tests
2023-11-16 13:27 ` [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
2023-11-16 13:27 ` [PATCH v7 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
@ 2023-11-16 13:27 ` Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
3 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 13:27 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Add scatter-gather copy tests.
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev.c | 139 ++++++++++++++++++++++++++++++-
app/test/test_dmadev_api.c | 164 ++++++++++++++++++++++++++++++++++---
2 files changed, 289 insertions(+), 14 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 2d20e716d2..d7cbb9a861 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -19,7 +19,7 @@
#define ERR_RETURN(...) do { print_err(__func__, __LINE__, __VA_ARGS__); return -1; } while (0)
#define TEST_RINGSIZE 512
-#define COPY_LEN 1024
+#define COPY_LEN 2048
static struct rte_dma_info info;
static struct rte_mempool *pool;
@@ -391,6 +391,125 @@ test_stop_start(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_enqueue_sg_copies(int16_t dev_id, uint16_t vchan)
+{
+ unsigned int src_len, dst_len, n_sge, len, i, j, k;
+ char orig_src[COPY_LEN], orig_dst[COPY_LEN];
+ struct rte_dma_info info = { 0 };
+ enum rte_dma_status_code status;
+ uint16_t id, n_src, n_dst;
+
+ if (rte_dma_info_get(dev_id, &info) < 0)
+ ERR_RETURN("Failed to get dev info");
+
+ if (info.max_sges < 2)
+ ERR_RETURN("Test needs minimum 2 SG pointers");
+
+ n_sge = info.max_sges;
+
+ for (n_src = 1; n_src <= n_sge; n_src++) {
+ for (n_dst = 1; n_dst <= n_sge; n_dst++) {
+ /* Normalize SG buffer lengths */
+ len = COPY_LEN;
+ len -= (len % (n_src * n_dst));
+ dst_len = len / n_dst;
+ src_len = len / n_src;
+
+ struct rte_dma_sge sg_src[n_sge], sg_dst[n_sge];
+ struct rte_mbuf *src[n_sge], *dst[n_sge];
+ char *src_data[n_sge], *dst_data[n_sge];
+
+ for (i = 0 ; i < len; i++)
+ orig_src[i] = rte_rand() & 0xFF;
+
+ memset(orig_dst, 0, len);
+
+ for (i = 0; i < n_src; i++) {
+ src[i] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(src[i] != NULL);
+ sg_src[i].addr = rte_pktmbuf_iova(src[i]);
+ sg_src[i].length = src_len;
+ src_data[i] = rte_pktmbuf_mtod(src[i], char *);
+ }
+
+ for (k = 0; k < n_dst; k++) {
+ dst[k] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(dst[k] != NULL);
+ sg_dst[k].addr = rte_pktmbuf_iova(dst[k]);
+ sg_dst[k].length = dst_len;
+ dst_data[k] = rte_pktmbuf_mtod(dst[k], char *);
+ }
+
+ for (i = 0; i < n_src; i++) {
+ for (j = 0; j < src_len; j++)
+ src_data[i][j] = orig_src[i * src_len + j];
+ }
+
+ for (k = 0; k < n_dst; k++)
+ memset(dst_data[k], 0, dst_len);
+
+ printf("\tsrc segs: %2d [seg len: %4d] - dst segs: %2d [seg len : %4d]\n",
+ n_src, src_len, n_dst, dst_len);
+
+ id = rte_dma_copy_sg(dev_id, vchan, sg_src, sg_dst, n_src, n_dst,
+ RTE_DMA_OP_FLAG_SUBMIT);
+
+ if (id != id_count)
+ ERR_RETURN("Error with rte_dma_copy_sg, got %u, expected %u\n",
+ id, id_count);
+
+ /* Give time for copy to finish, then check it was done */
+ await_hw(dev_id, vchan);
+
+ for (k = 0; k < n_dst; k++)
+ memcpy((&orig_dst[0] + k * dst_len), dst_data[k], dst_len);
+
+ if (memcmp(orig_src, orig_dst, COPY_LEN))
+ ERR_RETURN("Data mismatch");
+
+ /* Verify completion */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 1)
+ ERR_RETURN("Error with rte_dma_completed\n");
+
+ /* Verify expected index(id_count) */
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed and id when no job done */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed when no job done\n");
+
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed_status and id when no job done */
+ id = ~id;
+ if (rte_dma_completed_status(dev_id, vchan, 1, &id, &status) != 0)
+ ERR_RETURN("Error with rte_dma_completed_status when no job done\n");
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, 0);
+
+ for (i = 0; i < n_src; i++)
+ rte_pktmbuf_free(src[i]);
+ for (i = 0; i < n_dst; i++)
+ rte_pktmbuf_free(dst[i]);
+
+ /* Verify that completion returns nothing more */
+ if (rte_dma_completed(dev_id, 0, 1, NULL, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed in empty check\n");
+
+ id_count++;
+ }
+ }
+ return 0;
+}
+
/* Failure handling test cases - global macros and variables for those tests*/
#define COMP_BURST_SZ 16
#define OPT_FENCE(idx) ((fence && idx == 8) ? RTE_DMA_OP_FLAG_FENCE : 0)
@@ -929,6 +1048,17 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_dmadev_sg_copy_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ return ret;
+}
+
static int
test_dmadev_burst_setup(void)
{
@@ -1044,7 +1174,7 @@ test_dmadev_setup(void)
TEST_RINGSIZE * 2, /* n == num elements */
32, /* cache size */
0, /* priv size */
- 2048, /* data room size */
+ COPY_LEN + RTE_PKTMBUF_HEADROOM, /* data room size */
info.numa_node);
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
@@ -1070,6 +1200,7 @@ test_dmadev_instance(int16_t dev_id)
struct rte_dma_info dev_info;
enum {
TEST_COPY = 0,
+ TEST_COPY_SG,
TEST_START,
TEST_BURST,
TEST_ERR,
@@ -1080,6 +1211,7 @@ test_dmadev_instance(int16_t dev_id)
static struct runtest_param param[] = {
{"copy", test_enqueue_copies, 640},
+ {"sg_copy", test_enqueue_sg_copies, 1},
{"stop_start", test_stop_start, 1},
{"burst_capacity", test_burst_capacity, 1},
{"error_handling", test_completion_handling, 1},
@@ -1095,6 +1227,9 @@ test_dmadev_instance(int16_t dev_id)
TEST_CASE_NAMED_WITH_DATA("copy",
NULL, NULL,
runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA("sg_copy",
+ test_dmadev_sg_copy_setup, NULL,
+ runtest, ¶m[TEST_COPY_SG]),
TEST_CASE_NAMED_WITH_DATA("stop_start",
NULL, NULL,
runtest, ¶m[TEST_START]),
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 2b8a4eda62..a130e74b51 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -10,47 +10,75 @@
#include <rte_dmadev.h>
#include "test.h"
+#include "test_dmadev_api.h"
extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
+#define TEST_SG_MAX 64
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
+static char *src_sg[TEST_SG_MAX];
+static char *dst_sg[TEST_SG_MAX];
static int
testsuite_setup(void)
{
invalid_dev_id = -1;
-
- src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
- if (src == NULL)
- return -ENOMEM;
- dst = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
- if (dst == NULL) {
- rte_free(src);
- src = NULL;
- return -ENOMEM;
+ int i, rc = 0;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ src_sg[i] = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
+ if (src_sg[i] == NULL) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ dst_sg[i] = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
+ if (dst_sg[i] == NULL) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rc = -ENOMEM;
+ goto exit;
+ }
}
+ src = src_sg[0];
+ dst = dst_sg[0];
+
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT);
- return 0;
+ return rc;
+exit:
+ while (--i >= 0) {
+ rte_free(src_sg[i]);
+ rte_free(dst_sg[i]);
+ }
+
+ return rc;
}
static void
testsuite_teardown(void)
{
- rte_free(src);
+ int i;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rte_free(dst_sg[i]);
+ dst_sg[i] = NULL;
+ }
+
src = NULL;
- rte_free(dst);
dst = NULL;
/* Ensure the dmadev is stopped. */
rte_dma_stop(test_dev_id);
@@ -437,6 +465,37 @@ verify_memory(void)
return 0;
}
+static void
+sg_memory_setup(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++)
+ src_sg[i][j] = (char)j;
+
+ memset(dst_sg[i], 0, TEST_MEMCPY_SIZE);
+ }
+}
+
+static int
+sg_memory_verify(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++) {
+ if (src_sg[i][j] == dst_sg[i][j])
+ continue;
+
+ RTE_TEST_ASSERT_EQUAL(src_sg[i][j], dst_sg[i][j], "Failed to copy memory, %d %d",
+ src_sg[i][j], dst_sg[i][j]);
+ }
+ }
+
+ return 0;
+}
+
static int
test_dma_completed(void)
{
@@ -551,6 +610,86 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static int
+test_dma_sg(void)
+{
+ struct rte_dma_sge src_sge[TEST_SG_MAX], dst_sge[TEST_SG_MAX];
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t last_idx = -1;
+ bool has_error = true;
+ int n_sge, i, ret;
+ uint16_t cpl_ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
+
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ for (i = 0; i < n_sge; i++) {
+ src_sge[i].addr = rte_malloc_virt2iova(src_sg[i]);
+ src_sge[i].length = TEST_MEMCPY_SIZE;
+ dst_sge[i].addr = rte_malloc_virt2iova(dst_sg[i]);
+ dst_sge[i].length = TEST_MEMCPY_SIZE;
+ }
+
+ sg_memory_setup(n_sge);
+
+ /* Check enqueue without submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge, 0);
+ RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
+
+ /* Check DMA submit */
+ ret = rte_dma_submit(test_dev_id, 0);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ sg_memory_setup(n_sge);
+
+ /* Check for enqueue with submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge,
+ RTE_DMA_OP_FLAG_SUBMIT);
+ RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ /* Stop dmadev to make sure dmadev to a known state */
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite dma_api_testsuite = {
.suite_name = "DMA API Test Suite",
.setup = testsuite_setup,
@@ -568,6 +707,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
TEST_CASE(test_dma_completed_status),
+ TEST_CASE(test_dma_sg),
TEST_CASES_END()
}
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests
2023-11-16 13:27 ` [PATCH v7 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
` (2 preceding siblings ...)
2023-11-16 13:27 ` [PATCH v7 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
@ 2023-11-16 17:45 ` Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
` (4 more replies)
3 siblings, 5 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 17:45 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
This patch series reworks DMA tests to follow unit test framework
followed by new vchan reconfig and SG tests.
v8:
- Addressed compilation issue in Windows platform.
Gowrishankar Muthukrishnan (3):
test/dma: use unit test framework
test/dma: test multiple vchan
test/dma: add SG copy tests
app/test/test_dmadev.c | 374 +++++++++++++++++++++++++++++--------
app/test/test_dmadev_api.c | 316 +++++++++++++++++++++++--------
2 files changed, 534 insertions(+), 156 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v8 1/3] test/dma: use unit test framework
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
@ 2023-11-16 17:45 ` Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
` (3 subsequent siblings)
4 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 17:45 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Use unit test framework to execute DMA tests.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
v8:
- Used local macro instead of NAME_MAX, due to compilation
issue in Windows.
---
app/test/test_dmadev.c | 235 +++++++++++++++++++++++++------------
app/test/test_dmadev_api.c | 95 +++++----------
2 files changed, 193 insertions(+), 137 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 7581fc2b4c..94673720c4 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -18,11 +18,16 @@
#define ERR_RETURN(...) do { print_err(__func__, __LINE__, __VA_ARGS__); return -1; } while (0)
+#define TEST_NAME_MAX_LEN 80
#define TEST_RINGSIZE 512
#define COPY_LEN 1024
+static struct rte_dma_info info;
static struct rte_mempool *pool;
+static bool check_err_stats;
+static int16_t test_dev_id;
static uint16_t id_count;
+static uint16_t vchan;
enum {
TEST_PARAM_REMOTE_ADDR = 0,
@@ -61,13 +66,28 @@ print_err(const char *func, int lineno, const char *format, ...)
va_end(ap);
}
+struct runtest_param {
+ const char name[TEST_NAME_MAX_LEN];
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ int iterations;
+};
+
static int
-runtest(const char *printable, int (*test_fn)(int16_t dev_id, uint16_t vchan), int iterations,
- int16_t dev_id, uint16_t vchan, bool check_err_stats)
+runtest(const void *args)
{
+ int (*test_fn)(int16_t dev_id, uint16_t vchan);
+ const struct runtest_param *param = args;
struct rte_dma_stats stats;
+ const char *printable;
+ int iterations;
+ int16_t dev_id;
int i;
+ printable = param->name;
+ iterations = param->iterations;
+ test_fn = param->test_fn;
+ dev_id = test_dev_id;
+
rte_dma_stats_reset(dev_id, vchan);
printf("DMA Dev %d: Running %s Tests %s\n", dev_id, printable,
check_err_stats ? " " : "(errors expected)");
@@ -911,26 +931,87 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
}
static int
-test_dmadev_instance(int16_t dev_id)
+test_dmadev_burst_setup(void)
+{
+ if (rte_dma_burst_capacity(test_dev_id, vchan) < 64) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
+ test_dev_id);
+ return TEST_SKIPPED;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_dmadev_err_handling_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ /* to test error handling we can provide null pointers for source or dest in copies. This
+ * requires VA mode in DPDK, since NULL(0) is a valid physical address.
+ * We also need hardware that can report errors back.
+ */
+ if (rte_eal_iova_mode() != RTE_IOVA_VA)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n",
+ test_dev_id);
+ else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: device does not report errors, skipping error handling tests\n",
+ test_dev_id);
+ else
+ ret = TEST_SUCCESS;
+
+ return ret;
+}
+
+static int
+test_dmadev_fill_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0) {
+ RTE_LOG(ERR, USER1,
+ "DMA Dev %u: No device fill support, skipping fill tests\n", test_dev_id);
+ ret = TEST_SKIPPED;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_autofree_setup(void)
+{
+ int ret = TEST_SKIPPED;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
+ dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
+ if (prepare_m2d_auto_free(test_dev_id, vchan) != 0)
+ return ret;
+
+ ret = TEST_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int
+test_dmadev_setup(void)
{
-#define CHECK_ERRS true
+ int16_t dev_id = test_dev_id;
struct rte_dma_stats stats;
- struct rte_dma_info info;
const struct rte_dma_conf conf = { .nb_vchans = 1};
const struct rte_dma_vchan_conf qconf = {
.direction = RTE_DMA_DIR_MEM_TO_MEM,
.nb_desc = TEST_RINGSIZE,
};
- const int vchan = 0;
int ret;
ret = rte_dma_info_get(dev_id, &info);
if (ret != 0)
ERR_RETURN("Error with rte_dma_info_get()\n");
- printf("\n### Test dmadev instance %u [%s]\n",
- dev_id, info.dev_name);
-
if (info.max_vchans < 1)
ERR_RETURN("Error, no channels available on device id %u\n", dev_id);
@@ -969,76 +1050,82 @@ test_dmadev_instance(int16_t dev_id)
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
- /* run the test cases, use many iterations to ensure UINT16_MAX id wraparound */
- if (runtest("copy", test_enqueue_copies, 640, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run tests stopping/starting devices and check jobs still work after restart */
- if (runtest("stop-start", test_stop_start, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* run some burst capacity tests */
- if (rte_dma_burst_capacity(dev_id, vchan) < 64)
- printf("DMA Dev %u: insufficient burst capacity (64 required), skipping tests\n",
- dev_id);
- else if (runtest("burst capacity", test_burst_capacity, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- /* to test error handling we can provide null pointers for source or dest in copies. This
- * requires VA mode in DPDK, since NULL(0) is a valid physical address.
- * We also need hardware that can report errors back.
- */
- if (rte_eal_iova_mode() != RTE_IOVA_VA)
- printf("DMA Dev %u: DPDK not in VA mode, skipping error handling tests\n", dev_id);
- else if ((info.dev_capa & RTE_DMA_CAPA_HANDLES_ERRORS) == 0)
- printf("DMA Dev %u: device does not report errors, skipping error handling tests\n",
- dev_id);
- else if (runtest("error handling", test_completion_handling, 1,
- dev_id, vchan, !CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_OPS_FILL) == 0)
- printf("DMA Dev %u: No device fill support, skipping fill tests\n", dev_id);
- else if (runtest("fill", test_enqueue_fill, 1, dev_id, vchan, CHECK_ERRS) < 0)
- goto err;
-
- if ((info.dev_capa & RTE_DMA_CAPA_M2D_AUTO_FREE) &&
- dma_add_test[TEST_M2D_AUTO_FREE].enabled == true) {
- if (prepare_m2d_auto_free(dev_id, vchan) != 0)
- goto err;
- if (runtest("m2d_auto_free", test_m2d_auto_free, 128, dev_id, vchan,
- CHECK_ERRS) < 0)
- goto err;
- }
-
- rte_mempool_free(pool);
-
- if (rte_dma_stop(dev_id) < 0)
- ERR_RETURN("Error stopping device %u\n", dev_id);
+ check_err_stats = false;
+ vchan = 0;
- rte_dma_stats_reset(dev_id, vchan);
return 0;
+}
-err:
+static void
+test_dmadev_teardown(void)
+{
rte_mempool_free(pool);
- rte_dma_stop(dev_id);
- return -1;
+ rte_dma_stop(test_dev_id);
+ rte_dma_stats_reset(test_dev_id, vchan);
+ test_dev_id = -EINVAL;
}
static int
-test_apis(void)
+test_dmadev_instance(int16_t dev_id)
{
- const char *pmd = "dma_skeleton";
- int id;
+ struct rte_dma_info dev_info;
+ enum {
+ TEST_COPY = 0,
+ TEST_START,
+ TEST_BURST,
+ TEST_ERR,
+ TEST_FILL,
+ TEST_M2D,
+ TEST_END
+ };
+
+ static struct runtest_param param[] = {
+ {"copy", test_enqueue_copies, 640},
+ {"stop_start", test_stop_start, 1},
+ {"burst_capacity", test_burst_capacity, 1},
+ {"error_handling", test_completion_handling, 1},
+ {"fill", test_enqueue_fill, 1},
+ {"m2d_auto_free", test_m2d_auto_free, 128},
+ };
+
+ static struct unit_test_suite ts = {
+ .suite_name = "DMA dev instance testsuite",
+ .setup = test_dmadev_setup,
+ .teardown = test_dmadev_teardown,
+ .unit_test_cases = {
+ TEST_CASE_NAMED_WITH_DATA("copy",
+ NULL, NULL,
+ runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA("stop_start",
+ NULL, NULL,
+ runtest, ¶m[TEST_START]),
+ TEST_CASE_NAMED_WITH_DATA("burst_capacity",
+ test_dmadev_burst_setup, NULL,
+ runtest, ¶m[TEST_BURST]),
+ TEST_CASE_NAMED_WITH_DATA("error_handling",
+ test_dmadev_err_handling_setup, NULL,
+ runtest, ¶m[TEST_ERR]),
+ TEST_CASE_NAMED_WITH_DATA("fill",
+ test_dmadev_fill_setup, NULL,
+ runtest, ¶m[TEST_FILL]),
+ TEST_CASE_NAMED_WITH_DATA("m2d_autofree",
+ test_dmadev_autofree_setup, NULL,
+ runtest, ¶m[TEST_M2D]),
+ TEST_CASES_END()
+ }
+ };
+
int ret;
- /* attempt to create skeleton instance - ignore errors due to one being already present */
- rte_vdev_init(pmd, NULL);
- id = rte_dma_get_dev_id_by_name(pmd);
- if (id < 0)
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
return TEST_SKIPPED;
- printf("\n### Test dmadev infrastructure using skeleton driver\n");
- ret = test_dma_api(id);
+
+ test_dev_id = dev_id;
+ printf("\n### Test dmadev instance %u [%s]\n",
+ test_dev_id, dev_info.dev_name);
+
+ ret = unit_test_suite_runner(&ts);
+ test_dev_id = -EINVAL;
return ret;
}
@@ -1083,20 +1170,24 @@ parse_dma_env_var(void)
static int
test_dma(void)
{
+ const char *pmd = "dma_skeleton";
int i;
parse_dma_env_var();
- /* basic sanity on dmadev infrastructure */
- if (test_apis() < 0)
- ERR_RETURN("Error performing API tests\n");
+ /* attempt to create skeleton instance - ignore errors due to one being already present*/
+ rte_vdev_init(pmd, NULL);
if (rte_dma_count_avail() == 0)
return TEST_SKIPPED;
- RTE_DMA_FOREACH_DEV(i)
+ RTE_DMA_FOREACH_DEV(i) {
+ if (test_dma_api(i) < 0)
+ ERR_RETURN("Error performing API tests\n");
+
if (test_dmadev_instance(i) < 0)
ERR_RETURN("Error, test failure for device %d\n", i);
+ }
return 0;
}
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 4a181af90a..73d4db825a 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -9,31 +9,22 @@
#include <rte_test.h>
#include <rte_dmadev.h>
-extern int test_dma_api(uint16_t dev_id);
+#include "test.h"
-#define DMA_TEST_API_RUN(test) \
- testsuite_run_test(test, #test)
+extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
-#define TEST_SUCCESS 0
-#define TEST_FAILED -1
-
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
-static int total;
-static int passed;
-static int failed;
-
static int
-testsuite_setup(int16_t dev_id)
+testsuite_setup(void)
{
- test_dev_id = dev_id;
invalid_dev_id = -1;
src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
@@ -46,10 +37,6 @@ testsuite_setup(int16_t dev_id)
return -ENOMEM;
}
- total = 0;
- passed = 0;
- failed = 0;
-
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
@@ -71,25 +58,6 @@ testsuite_teardown(void)
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_INFO);
}
-static void
-testsuite_run_test(int (*test)(void), const char *name)
-{
- int ret = 0;
-
- if (test) {
- ret = test();
- if (ret < 0) {
- failed++;
- printf("%s Failed\n", name);
- } else {
- passed++;
- printf("%s Passed\n", name);
- }
- }
-
- total++;
-}
-
static int
test_dma_get_dev_id_by_name(void)
{
@@ -301,7 +269,7 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = dev_info.max_vchans;
+ dev_conf.nb_vchans = 1;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
@@ -537,38 +505,35 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static struct unit_test_suite dma_api_testsuite = {
+ .suite_name = "DMA API Test Suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE(test_dma_get_dev_id_by_name),
+ TEST_CASE(test_dma_is_valid_dev),
+ TEST_CASE(test_dma_count),
+ TEST_CASE(test_dma_info_get),
+ TEST_CASE(test_dma_configure),
+ TEST_CASE(test_dma_vchan_setup),
+ TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_stats),
+ TEST_CASE(test_dma_dump),
+ TEST_CASE(test_dma_completed),
+ TEST_CASE(test_dma_completed_status),
+ TEST_CASES_END()
+ }
+};
+
int
test_dma_api(uint16_t dev_id)
{
- int ret = testsuite_setup(dev_id);
- if (ret) {
- printf("testsuite setup fail!\n");
- return -1;
- }
+ struct rte_dma_info dev_info;
- /* If the testcase exit successfully, ensure that the test dmadev exist
- * and the dmadev is in the stopped state.
- */
- DMA_TEST_API_RUN(test_dma_get_dev_id_by_name);
- DMA_TEST_API_RUN(test_dma_is_valid_dev);
- DMA_TEST_API_RUN(test_dma_count);
- DMA_TEST_API_RUN(test_dma_info_get);
- DMA_TEST_API_RUN(test_dma_configure);
- DMA_TEST_API_RUN(test_dma_vchan_setup);
- DMA_TEST_API_RUN(test_dma_start_stop);
- DMA_TEST_API_RUN(test_dma_stats);
- DMA_TEST_API_RUN(test_dma_dump);
- DMA_TEST_API_RUN(test_dma_completed);
- DMA_TEST_API_RUN(test_dma_completed_status);
-
- testsuite_teardown();
-
- printf("Total tests : %d\n", total);
- printf("Passed : %d\n", passed);
- printf("Failed : %d\n", failed);
-
- if (failed)
- return -1;
+ if (rte_dma_info_get(dev_id, &dev_info) < 0)
+ return TEST_SKIPPED;
- return 0;
+ printf("\n### Test dmadev infrastructure using %u [%s]\n", dev_id, dev_info.dev_name);
+ test_dev_id = dev_id;
+ return unit_test_suite_runner(&dma_api_testsuite);
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v8 2/3] test/dma: test multiple vchan
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
@ 2023-11-16 17:45 ` Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
` (2 subsequent siblings)
4 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 17:45 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Support API with multiple vchan test.
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev_api.c | 63 +++++++++++++++++++++++++++++++++-----
1 file changed, 55 insertions(+), 8 deletions(-)
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 73d4db825a..2b8a4eda62 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -260,7 +260,7 @@ test_dma_vchan_setup(void)
}
static int
-setup_one_vchan(void)
+setup_vchan(int nb_vchans)
{
struct rte_dma_vchan_conf vchan_conf = { 0 };
struct rte_dma_info dev_info = { 0 };
@@ -269,13 +269,15 @@ setup_one_vchan(void)
ret = rte_dma_info_get(test_dev_id, &dev_info);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
- dev_conf.nb_vchans = 1;
+ dev_conf.nb_vchans = nb_vchans;
ret = rte_dma_configure(test_dev_id, &dev_conf);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to configure, %d", ret);
vchan_conf.direction = RTE_DMA_DIR_MEM_TO_MEM;
vchan_conf.nb_desc = dev_info.min_desc;
- ret = rte_dma_vchan_setup(test_dev_id, 0, &vchan_conf);
- RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan, %d", ret);
+ for (int i = 0; i < nb_vchans; i++) {
+ ret = rte_dma_vchan_setup(test_dev_id, i, &vchan_conf);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup vchan %d, %d", i, ret);
+ }
return TEST_SUCCESS;
}
@@ -294,7 +296,7 @@ test_dma_start_stop(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -312,6 +314,50 @@ test_dma_start_stop(void)
return TEST_SUCCESS;
}
+static int
+test_dma_reconfigure(void)
+{
+ struct rte_dma_conf dev_conf = { 0 };
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t cfg_vchans;
+ int ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ /* At least two vchans required for the test */
+ if (dev_info.max_vchans < 2)
+ return TEST_SKIPPED;
+
+ /* Setup one vchan for later test */
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ /* Check reconfigure and vchan setup after device stopped */
+ cfg_vchans = dev_conf.nb_vchans = (dev_info.max_vchans - 1);
+
+ ret = setup_vchan(cfg_vchans);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+ RTE_TEST_ASSERT_EQUAL(dev_info.nb_vchans, cfg_vchans, "incorrect reconfiguration");
+
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static int
test_dma_stats(void)
{
@@ -328,7 +374,7 @@ test_dma_stats(void)
RTE_TEST_ASSERT(ret == -EINVAL, "Expected -EINVAL, %d", ret);
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
/* Check for invalid vchan */
@@ -400,7 +446,7 @@ test_dma_completed(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -459,7 +505,7 @@ test_dma_completed_status(void)
int ret;
/* Setup one vchan for later test */
- ret = setup_one_vchan();
+ ret = setup_vchan(1);
RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
ret = rte_dma_start(test_dev_id);
@@ -517,6 +563,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_configure),
TEST_CASE(test_dma_vchan_setup),
TEST_CASE(test_dma_start_stop),
+ TEST_CASE(test_dma_reconfigure),
TEST_CASE(test_dma_stats),
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH v8 3/3] test/dma: add SG copy tests
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 1/3] test/dma: use unit test framework Gowrishankar Muthukrishnan
2023-11-16 17:45 ` [PATCH v8 2/3] test/dma: test multiple vchan Gowrishankar Muthukrishnan
@ 2023-11-16 17:45 ` Gowrishankar Muthukrishnan
2023-12-07 10:10 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
2024-03-06 19:45 ` Thomas Monjalon
4 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-11-16 17:45 UTC (permalink / raw)
To: dev
Cc: anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson,
Gowrishankar Muthukrishnan
Add scatter-gather copy tests.
Signed-off-by: Vidya Sagar Velumuri <vvelumuri@marvell.com>
Signed-off-by: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
app/test/test_dmadev.c | 139 ++++++++++++++++++++++++++++++-
app/test/test_dmadev_api.c | 164 ++++++++++++++++++++++++++++++++++---
2 files changed, 289 insertions(+), 14 deletions(-)
diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
index 94673720c4..143e1bcd68 100644
--- a/app/test/test_dmadev.c
+++ b/app/test/test_dmadev.c
@@ -20,7 +20,7 @@
#define TEST_NAME_MAX_LEN 80
#define TEST_RINGSIZE 512
-#define COPY_LEN 1024
+#define COPY_LEN 2048
static struct rte_dma_info info;
static struct rte_mempool *pool;
@@ -392,6 +392,125 @@ test_stop_start(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_enqueue_sg_copies(int16_t dev_id, uint16_t vchan)
+{
+ unsigned int src_len, dst_len, n_sge, len, i, j, k;
+ char orig_src[COPY_LEN], orig_dst[COPY_LEN];
+ struct rte_dma_info info = { 0 };
+ enum rte_dma_status_code status;
+ uint16_t id, n_src, n_dst;
+
+ if (rte_dma_info_get(dev_id, &info) < 0)
+ ERR_RETURN("Failed to get dev info");
+
+ if (info.max_sges < 2)
+ ERR_RETURN("Test needs minimum 2 SG pointers");
+
+ n_sge = info.max_sges;
+
+ for (n_src = 1; n_src <= n_sge; n_src++) {
+ for (n_dst = 1; n_dst <= n_sge; n_dst++) {
+ /* Normalize SG buffer lengths */
+ len = COPY_LEN;
+ len -= (len % (n_src * n_dst));
+ dst_len = len / n_dst;
+ src_len = len / n_src;
+
+ struct rte_dma_sge sg_src[n_sge], sg_dst[n_sge];
+ struct rte_mbuf *src[n_sge], *dst[n_sge];
+ char *src_data[n_sge], *dst_data[n_sge];
+
+ for (i = 0 ; i < len; i++)
+ orig_src[i] = rte_rand() & 0xFF;
+
+ memset(orig_dst, 0, len);
+
+ for (i = 0; i < n_src; i++) {
+ src[i] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(src[i] != NULL);
+ sg_src[i].addr = rte_pktmbuf_iova(src[i]);
+ sg_src[i].length = src_len;
+ src_data[i] = rte_pktmbuf_mtod(src[i], char *);
+ }
+
+ for (k = 0; k < n_dst; k++) {
+ dst[k] = rte_pktmbuf_alloc(pool);
+ RTE_ASSERT(dst[k] != NULL);
+ sg_dst[k].addr = rte_pktmbuf_iova(dst[k]);
+ sg_dst[k].length = dst_len;
+ dst_data[k] = rte_pktmbuf_mtod(dst[k], char *);
+ }
+
+ for (i = 0; i < n_src; i++) {
+ for (j = 0; j < src_len; j++)
+ src_data[i][j] = orig_src[i * src_len + j];
+ }
+
+ for (k = 0; k < n_dst; k++)
+ memset(dst_data[k], 0, dst_len);
+
+ printf("\tsrc segs: %2d [seg len: %4d] - dst segs: %2d [seg len : %4d]\n",
+ n_src, src_len, n_dst, dst_len);
+
+ id = rte_dma_copy_sg(dev_id, vchan, sg_src, sg_dst, n_src, n_dst,
+ RTE_DMA_OP_FLAG_SUBMIT);
+
+ if (id != id_count)
+ ERR_RETURN("Error with rte_dma_copy_sg, got %u, expected %u\n",
+ id, id_count);
+
+ /* Give time for copy to finish, then check it was done */
+ await_hw(dev_id, vchan);
+
+ for (k = 0; k < n_dst; k++)
+ memcpy((&orig_dst[0] + k * dst_len), dst_data[k], dst_len);
+
+ if (memcmp(orig_src, orig_dst, COPY_LEN))
+ ERR_RETURN("Data mismatch");
+
+ /* Verify completion */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 1)
+ ERR_RETURN("Error with rte_dma_completed\n");
+
+ /* Verify expected index(id_count) */
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed and id when no job done */
+ id = ~id;
+ if (rte_dma_completed(dev_id, vchan, 1, &id, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed when no job done\n");
+
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, id_count);
+
+ /* Check for completed_status and id when no job done */
+ id = ~id;
+ if (rte_dma_completed_status(dev_id, vchan, 1, &id, &status) != 0)
+ ERR_RETURN("Error with rte_dma_completed_status when no job done\n");
+ if (id != id_count)
+ ERR_RETURN("Error:incorrect job id received when no job done, %u [expected %u]\n",
+ id, 0);
+
+ for (i = 0; i < n_src; i++)
+ rte_pktmbuf_free(src[i]);
+ for (i = 0; i < n_dst; i++)
+ rte_pktmbuf_free(dst[i]);
+
+ /* Verify that completion returns nothing more */
+ if (rte_dma_completed(dev_id, 0, 1, NULL, NULL) != 0)
+ ERR_RETURN("Error with rte_dma_completed in empty check\n");
+
+ id_count++;
+ }
+ }
+ return 0;
+}
+
/* Failure handling test cases - global macros and variables for those tests*/
#define COMP_BURST_SZ 16
#define OPT_FENCE(idx) ((fence && idx == 8) ? RTE_DMA_OP_FLAG_FENCE : 0)
@@ -930,6 +1049,17 @@ prepare_m2d_auto_free(int16_t dev_id, uint16_t vchan)
return 0;
}
+static int
+test_dmadev_sg_copy_setup(void)
+{
+ int ret = TEST_SUCCESS;
+
+ if ((info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ return ret;
+}
+
static int
test_dmadev_burst_setup(void)
{
@@ -1045,7 +1175,7 @@ test_dmadev_setup(void)
TEST_RINGSIZE * 2, /* n == num elements */
32, /* cache size */
0, /* priv size */
- 2048, /* data room size */
+ COPY_LEN + RTE_PKTMBUF_HEADROOM, /* data room size */
info.numa_node);
if (pool == NULL)
ERR_RETURN("Error with mempool creation\n");
@@ -1071,6 +1201,7 @@ test_dmadev_instance(int16_t dev_id)
struct rte_dma_info dev_info;
enum {
TEST_COPY = 0,
+ TEST_COPY_SG,
TEST_START,
TEST_BURST,
TEST_ERR,
@@ -1081,6 +1212,7 @@ test_dmadev_instance(int16_t dev_id)
static struct runtest_param param[] = {
{"copy", test_enqueue_copies, 640},
+ {"sg_copy", test_enqueue_sg_copies, 1},
{"stop_start", test_stop_start, 1},
{"burst_capacity", test_burst_capacity, 1},
{"error_handling", test_completion_handling, 1},
@@ -1096,6 +1228,9 @@ test_dmadev_instance(int16_t dev_id)
TEST_CASE_NAMED_WITH_DATA("copy",
NULL, NULL,
runtest, ¶m[TEST_COPY]),
+ TEST_CASE_NAMED_WITH_DATA("sg_copy",
+ test_dmadev_sg_copy_setup, NULL,
+ runtest, ¶m[TEST_COPY_SG]),
TEST_CASE_NAMED_WITH_DATA("stop_start",
NULL, NULL,
runtest, ¶m[TEST_START]),
diff --git a/app/test/test_dmadev_api.c b/app/test/test_dmadev_api.c
index 2b8a4eda62..a130e74b51 100644
--- a/app/test/test_dmadev_api.c
+++ b/app/test/test_dmadev_api.c
@@ -10,47 +10,75 @@
#include <rte_dmadev.h>
#include "test.h"
+#include "test_dmadev_api.h"
extern int test_dma_api(uint16_t dev_id);
#define TEST_MEMCPY_SIZE 1024
#define TEST_WAIT_US_VAL 50000
+#define TEST_SG_MAX 64
static int16_t test_dev_id;
static int16_t invalid_dev_id;
static char *src;
static char *dst;
+static char *src_sg[TEST_SG_MAX];
+static char *dst_sg[TEST_SG_MAX];
static int
testsuite_setup(void)
{
invalid_dev_id = -1;
-
- src = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
- if (src == NULL)
- return -ENOMEM;
- dst = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
- if (dst == NULL) {
- rte_free(src);
- src = NULL;
- return -ENOMEM;
+ int i, rc = 0;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ src_sg[i] = rte_malloc("dmadev_test_src", TEST_MEMCPY_SIZE, 0);
+ if (src_sg[i] == NULL) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ dst_sg[i] = rte_malloc("dmadev_test_dst", TEST_MEMCPY_SIZE, 0);
+ if (dst_sg[i] == NULL) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rc = -ENOMEM;
+ goto exit;
+ }
}
+ src = src_sg[0];
+ dst = dst_sg[0];
+
/* Set dmadev log level to critical to suppress unnecessary output
* during API tests.
*/
rte_log_set_level_pattern("lib.dmadev", RTE_LOG_CRIT);
- return 0;
+ return rc;
+exit:
+ while (--i >= 0) {
+ rte_free(src_sg[i]);
+ rte_free(dst_sg[i]);
+ }
+
+ return rc;
}
static void
testsuite_teardown(void)
{
- rte_free(src);
+ int i;
+
+ for (i = 0; i < TEST_SG_MAX; i++) {
+ rte_free(src_sg[i]);
+ src_sg[i] = NULL;
+ rte_free(dst_sg[i]);
+ dst_sg[i] = NULL;
+ }
+
src = NULL;
- rte_free(dst);
dst = NULL;
/* Ensure the dmadev is stopped. */
rte_dma_stop(test_dev_id);
@@ -437,6 +465,37 @@ verify_memory(void)
return 0;
}
+static void
+sg_memory_setup(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++)
+ src_sg[i][j] = (char)j;
+
+ memset(dst_sg[i], 0, TEST_MEMCPY_SIZE);
+ }
+}
+
+static int
+sg_memory_verify(int n)
+{
+ int i, j;
+
+ for (i = 0; i < n; i++) {
+ for (j = 0; j < TEST_MEMCPY_SIZE; j++) {
+ if (src_sg[i][j] == dst_sg[i][j])
+ continue;
+
+ RTE_TEST_ASSERT_EQUAL(src_sg[i][j], dst_sg[i][j], "Failed to copy memory, %d %d",
+ src_sg[i][j], dst_sg[i][j]);
+ }
+ }
+
+ return 0;
+}
+
static int
test_dma_completed(void)
{
@@ -551,6 +610,86 @@ test_dma_completed_status(void)
return TEST_SUCCESS;
}
+static int
+test_dma_sg(void)
+{
+ struct rte_dma_sge src_sge[TEST_SG_MAX], dst_sge[TEST_SG_MAX];
+ struct rte_dma_info dev_info = { 0 };
+ uint16_t last_idx = -1;
+ bool has_error = true;
+ int n_sge, i, ret;
+ uint16_t cpl_ret;
+
+ ret = rte_dma_info_get(test_dev_id, &dev_info);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to obtain device info, %d", ret);
+
+ if ((dev_info.dev_capa & RTE_DMA_CAPA_OPS_COPY_SG) == 0)
+ return TEST_SKIPPED;
+
+ n_sge = RTE_MIN(dev_info.max_sges, TEST_SG_MAX);
+
+ ret = setup_vchan(1);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to setup one vchan, %d", ret);
+
+ ret = rte_dma_start(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to start, %d", ret);
+
+ for (i = 0; i < n_sge; i++) {
+ src_sge[i].addr = rte_malloc_virt2iova(src_sg[i]);
+ src_sge[i].length = TEST_MEMCPY_SIZE;
+ dst_sge[i].addr = rte_malloc_virt2iova(dst_sg[i]);
+ dst_sge[i].length = TEST_MEMCPY_SIZE;
+ }
+
+ sg_memory_setup(n_sge);
+
+ /* Check enqueue without submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge, 0);
+ RTE_TEST_ASSERT_EQUAL(ret, 0, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 0, "Failed to get completed");
+
+ /* Check DMA submit */
+ ret = rte_dma_submit(test_dev_id, 0);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to submit, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 0, "Last idx should be zero, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ sg_memory_setup(n_sge);
+
+ /* Check for enqueue with submit */
+ ret = rte_dma_copy_sg(test_dev_id, 0, src_sge, dst_sge, n_sge, n_sge,
+ RTE_DMA_OP_FLAG_SUBMIT);
+ RTE_TEST_ASSERT_EQUAL(ret, 1, "Failed to enqueue copy, %d", ret);
+
+ rte_delay_us_sleep(TEST_WAIT_US_VAL);
+
+ cpl_ret = rte_dma_completed(test_dev_id, 0, 1, &last_idx, &has_error);
+ RTE_TEST_ASSERT_EQUAL(cpl_ret, 1, "Failed to get completed");
+ RTE_TEST_ASSERT_EQUAL(last_idx, 1, "Last idx should be 1, %u", last_idx);
+ RTE_TEST_ASSERT_EQUAL(has_error, false, "Should have no error");
+
+ ret = sg_memory_verify(n_sge);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to verify memory");
+
+ /* Stop dmadev to make sure dmadev to a known state */
+ ret = rte_dma_stop(test_dev_id);
+ RTE_TEST_ASSERT_SUCCESS(ret, "Failed to stop, %d", ret);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite dma_api_testsuite = {
.suite_name = "DMA API Test Suite",
.setup = testsuite_setup,
@@ -568,6 +707,7 @@ static struct unit_test_suite dma_api_testsuite = {
TEST_CASE(test_dma_dump),
TEST_CASE(test_dma_completed),
TEST_CASE(test_dma_completed_status),
+ TEST_CASE(test_dma_sg),
TEST_CASES_END()
}
};
--
2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* RE: [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
` (2 preceding siblings ...)
2023-11-16 17:45 ` [PATCH v8 3/3] test/dma: add SG copy tests Gowrishankar Muthukrishnan
@ 2023-12-07 10:10 ` Gowrishankar Muthukrishnan
2024-02-05 10:34 ` Gowrishankar Muthukrishnan
2024-03-06 19:45 ` Thomas Monjalon
4 siblings, 1 reply; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2023-12-07 10:10 UTC (permalink / raw)
To: dev
Cc: Anoob Joseph, Chengwen Feng, Vamsi Krishna Attunuru,
Amit Prakash Shukla, Vidya Sagar Velumuri, Kevin Laatz,
Bruce Richardson
Hi,
Could this patch series be reviewed ? As of now, patches are rebased without any conflicts.
Thanks,
Gowrishankar
> -----Original Message-----
> From: Gowrishankar Muthukrishnan <gmuthukrishn@marvell.com>
> Sent: Thursday, November 16, 2023 11:15 PM
> To: dev@dpdk.org
> Cc: Anoob Joseph <anoobj@marvell.com>; Chengwen Feng
> <fengchengwen@huawei.com>; Vamsi Krishna Attunuru
> <vattunuru@marvell.com>; Amit Prakash Shukla
> <amitprakashs@marvell.com>; Vidya Sagar Velumuri
> <vvelumuri@marvell.com>; Kevin Laatz <kevin.laatz@intel.com>; Bruce
> Richardson <bruce.richardson@intel.com>; Gowrishankar Muthukrishnan
> <gmuthukrishn@marvell.com>
> Subject: [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests
>
> This patch series reworks DMA tests to follow unit test framework followed
> by new vchan reconfig and SG tests.
>
> v8:
> - Addressed compilation issue in Windows platform.
>
> Gowrishankar Muthukrishnan (3):
> test/dma: use unit test framework
> test/dma: test multiple vchan
> test/dma: add SG copy tests
>
> app/test/test_dmadev.c | 374 +++++++++++++++++++++++++++++-------
> -
> app/test/test_dmadev_api.c | 316 +++++++++++++++++++++++--------
> 2 files changed, 534 insertions(+), 156 deletions(-)
>
> --
> 2.25.1
^ permalink raw reply [flat|nested] 39+ messages in thread
* RE: [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests
2023-12-07 10:10 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
@ 2024-02-05 10:34 ` Gowrishankar Muthukrishnan
0 siblings, 0 replies; 39+ messages in thread
From: Gowrishankar Muthukrishnan @ 2024-02-05 10:34 UTC (permalink / raw)
To: dev
Cc: Anoob Joseph, Chengwen Feng, Vamsi Krishna Attunuru,
Amit Prakash Shukla, Vidya Sagar Velumuri, Kevin Laatz,
Bruce Richardson, Jerin Jacob, Thomas Monjalon
Hi,
Could this series be merged as the patches are acked.
Thanks,
Gowrishankar
^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests
2023-11-16 17:45 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
` (3 preceding siblings ...)
2023-12-07 10:10 ` [PATCH v8 0/3] test/dma: add vchan reconfig and SG tests Gowrishankar Muthukrishnan
@ 2024-03-06 19:45 ` Thomas Monjalon
4 siblings, 0 replies; 39+ messages in thread
From: Thomas Monjalon @ 2024-03-06 19:45 UTC (permalink / raw)
To: Gowrishankar Muthukrishnan
Cc: dev, anoobj, Chengwen Feng, Vamsi Attunuru, Amit Prakash Shukla,
Vidya Sagar Velumuri, Kevin Laatz, Bruce Richardson
16/11/2023 18:45, Gowrishankar Muthukrishnan:
> Gowrishankar Muthukrishnan (3):
> test/dma: use unit test framework
> test/dma: test multiple vchan
> test/dma: add SG copy tests
Applied, thanks.
^ permalink raw reply [flat|nested] 39+ messages in thread