diff --git a/.github/workflows/ubuntu_build_with_gtest.yml b/.github/workflows/ubuntu_build_with_gtest.yml index 11de631c2..cd21874f2 100644 --- a/.github/workflows/ubuntu_build_with_gtest.yml +++ b/.github/workflows/ubuntu_build_with_gtest.yml @@ -139,3 +139,7 @@ jobs: - name: Run st2110 st20p test case in simulation ENA environment run: | sudo ./build/tests/KahawaiTest --auto_start_stop --p_port ${{ env.TEST_PORT_P }} --r_port ${{ env.TEST_PORT_R }} --rss_mode l3_l4 --pacing_way tsc --iova_mode pa --multi_src_port --gtest_filter=Main.*:St20p*:-*ext* + + - name: Run st2110 st20p test case with kernel loopback + run: | + ./build/tests/KahawaiTest --p_port kernel:lo --r_port kernel:lo --auto_start_stop --gtest_filter=St20p* \ No newline at end of file diff --git a/include/mtl_api.h b/include/mtl_api.h index 956032931..a5cd1659d 100644 --- a/include/mtl_api.h +++ b/include/mtl_api.h @@ -1284,6 +1284,8 @@ enum mtl_iova_mode mtl_iova_mode_get(mtl_handle mt); * * @param handle * The handle to the st user dma dev. + * @param port + * The port. * @param ip * The buffer for IP address. * @param netmask @@ -1297,6 +1299,19 @@ enum mtl_iova_mode mtl_iova_mode_get(mtl_handle mt); int mtl_port_ip_info(mtl_handle mt, enum mtl_port port, uint8_t ip[MTL_IP_ADDR_LEN], uint8_t netmask[MTL_IP_ADDR_LEN], uint8_t gateway[MTL_IP_ADDR_LEN]); +/** + * Check if the pmd of one mtl port is dpdk based or not. + * + * @param handle + * The handle to the st user dma dev. + * @param port + * The port. + * @return + * - true: a DPDK based PMD. + * - false: not a DPDK based PMD, MTL_PMD_KERNEL_SOCKET or MTL_PMD_NATIVE_AF_XDP. + */ +bool mtl_pmd_is_dpdk_based(mtl_handle mt, enum mtl_port port); + /** * Get SIMD level current cpu supported. * diff --git a/lib/src/mt_main.c b/lib/src/mt_main.c index c1826ae9b..9467ebd37 100644 --- a/lib/src/mt_main.c +++ b/lib/src/mt_main.c @@ -326,8 +326,13 @@ static int mt_user_params_check(struct mtl_init_params* p) { for (int j = 0; j < i; j++) { /* check if duplicate port name */ if (0 == strncmp(p->port[i], p->port[j], MTL_PORT_MAX_LEN)) { - err("%s, same name %s for port %d and %d\n", __func__, p->port[i], i, j); - return -EINVAL; + if (!strncmp(p->port[i], "kernel:lo", MTL_PORT_MAX_LEN)) { + /* duplicated kernel:lo for test purpose */ + warn("%s, same name %s for port %d and %d\n", __func__, p->port[i], i, j); + } else { + err("%s, same name %s for port %d and %d\n", __func__, p->port[i], i, j); + return -EINVAL; + } } /* check if duplicate ip */ if ((p->net_proto[i] == MTL_PROTO_STATIC) && (p->pmd[i] == MTL_PMD_DPDK_USER) && @@ -833,6 +838,10 @@ mtl_iova_t mtl_dma_map(mtl_handle mt, const void* vaddr, size_t size) { if (ret < 0) return MTL_BAD_IOVA; iova = item.iova; + if (!mt_drv_dpdk_based(impl, MTL_PORT_P)) { + return iova; + } + ret = rte_extmem_register((void*)vaddr, size, NULL, 0, page_size); if (ret < 0) { err("%s, fail(%d,%s) to register extmem %p\n", __func__, ret, rte_strerror(rte_errno), @@ -889,6 +898,10 @@ int mtl_dma_unmap(mtl_handle mt, const void* vaddr, mtl_iova_t iova, size_t size ret = mt_map_remove(impl, &item); if (ret < 0) return ret; + if (!mt_drv_dpdk_based(impl, MTL_PORT_P)) { + return 0; + } + /* only unmap for MTL_PORT_P now */ ret = rte_dev_dma_unmap(mt_port_device(impl, MTL_PORT_P), (void*)vaddr, iova, size); if (ret < 0) { @@ -1264,3 +1277,17 @@ const char* mtl_get_simd_level_name(enum mtl_simd_level level) { } int mtl_openlog_stream(FILE* f) { return rte_openlog_stream(f); } + +bool mtl_pmd_is_dpdk_based(mtl_handle mt, enum mtl_port port) { + struct mtl_main_impl* impl = mt; + + if (impl->type != MT_HANDLE_MAIN) { + err("%s, invalid type %d\n", __func__, impl->type); + return -EINVAL; + } + if (port >= mt_num_ports(impl)) { + err("%s, invalid port %d\n", __func__, port); + return -EINVAL; + } + return mt_drv_dpdk_based(impl, port); +} diff --git a/lib/src/mt_main.h b/lib/src/mt_main.h index 0978d2ef5..698d1d275 100644 --- a/lib/src/mt_main.h +++ b/lib/src/mt_main.h @@ -1176,6 +1176,13 @@ static inline bool mt_drv_use_kernel_ctl(struct mtl_main_impl* impl, enum mtl_po return false; } +static inline bool mt_drv_dpdk_based(struct mtl_main_impl* impl, enum mtl_port port) { + if (mt_if(impl, port)->drv_info.flags & MT_DRV_F_NOT_DPDK_PMD) + return false; + else + return true; +} + static inline bool mt_drv_mcast_in_dp(struct mtl_main_impl* impl, enum mtl_port port) { if (mt_if(impl, port)->drv_info.flags & MT_DRV_F_MCAST_IN_DP) return true; diff --git a/lib/src/st2110/st_rx_video_session.c b/lib/src/st2110/st_rx_video_session.c index d057f3f45..9bae440fb 100644 --- a/lib/src/st2110/st_rx_video_session.c +++ b/lib/src/st2110/st_rx_video_session.c @@ -1527,6 +1527,11 @@ static int rv_start_pcapng(struct mtl_main_impl* impl, struct st_rx_video_sessio int idx = s->idx; int pkt_len = ST_PKT_MAX_ETHER_BYTES; + if (!mt_drv_dpdk_based(impl, port)) { + err("%s, port %d is not dpdk based, unsupported\n", __func__, port); + return -ENOTSUP; + } + if (s->st22_info) { snprintf(s->pcapng_file_name, MTL_PCAP_FILE_MAX_LEN, "st22_rx_%d_%u_XXXXXX.pcapng", idx, max_dump_packets); diff --git a/tests/src/st20_test.cpp b/tests/src/st20_test.cpp index 5dbc6289d..b123dbd54 100644 --- a/tests/src/st20_test.cpp +++ b/tests/src/st20_test.cpp @@ -520,6 +520,7 @@ static void st20_tx_ops_init(tests_context* st20, struct st20_tx_ops* ops) { ops->name = "st20_test"; ops->priv = st20; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->dip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", @@ -553,6 +554,7 @@ static void st20_rx_ops_init(tests_context* st20, struct st20_rx_ops* ops) { ops->name = "st20_test"; ops->priv = st20; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->sip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", @@ -3694,6 +3696,11 @@ static void st20_rx_dump_test(enum st20_type type[], enum st_fps fps[], int widt return; } + if (!mtl_pmd_is_dpdk_based(m_handle, MTL_PORT_R)) { + info("%s, MTL_PORT_R is not a DPDK based PMD, skip this case\n", __func__); + return; + } + std::vector test_ctx_tx; std::vector test_ctx_rx; std::vector tx_handle; diff --git a/tests/src/st20p_test.cpp b/tests/src/st20p_test.cpp index 8712d1461..0fd2d14a2 100644 --- a/tests/src/st20p_test.cpp +++ b/tests/src/st20p_test.cpp @@ -662,6 +662,14 @@ static void st20p_rx_digest_test(enum st_fps fps[], int width[], int height[], } } + if (para->pkt_convert) { + enum mtl_pmd_type pmd = ctx->para.pmd[MTL_PORT_R]; + if (MTL_PMD_DPDK_USER != pmd) { + info("%s, skip as pmd %d is not dpdk user\n", __func__, pmd); + return; + } + } + std::vector test_ctx_tx; std::vector test_ctx_rx; std::vector tx_handle; diff --git a/tests/src/st22_test.cpp b/tests/src/st22_test.cpp index 99e587708..2b660937d 100644 --- a/tests/src/st22_test.cpp +++ b/tests/src/st22_test.cpp @@ -95,6 +95,7 @@ static void st22_tx_ops_init(tests_context* st22, struct st22_tx_ops* ops) { ops->name = "st22_test"; ops->priv = st22; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->dip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", @@ -129,6 +130,7 @@ static void st22_rx_ops_init(tests_context* st22, struct st22_rx_ops* ops) { ops->name = "st22_test"; ops->priv = st22; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->sip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", diff --git a/tests/src/st30_test.cpp b/tests/src/st30_test.cpp index 4a42b65d2..865db13f3 100644 --- a/tests/src/st30_test.cpp +++ b/tests/src/st30_test.cpp @@ -188,6 +188,7 @@ static void st30_rx_ops_init(tests_context* st30, struct st30_rx_ops* ops) { ops->name = "st30_test"; ops->priv = st30; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->sip_addr[MTL_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_PORT_P], MTL_PORT_MAX_LEN, "%s", ctx->para.port[MTL_PORT_P]); ops->udp_port[MTL_PORT_P] = 20000 + st30->idx; @@ -217,6 +218,7 @@ static void st30_tx_ops_init(tests_context* st30, struct st30_tx_ops* ops) { ops->name = "st30_test"; ops->priv = st30; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->dip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", diff --git a/tests/src/st40_test.cpp b/tests/src/st40_test.cpp index e70463fba..789af5e1d 100644 --- a/tests/src/st40_test.cpp +++ b/tests/src/st40_test.cpp @@ -214,6 +214,7 @@ static void st40_rx_ops_init(tests_context* st40, struct st40_rx_ops* ops) { ops->name = "st40_test"; ops->priv = st40; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->sip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", @@ -238,6 +239,7 @@ static void st40_tx_ops_init(tests_context* st40, struct st40_tx_ops* ops) { ops->name = "st40_test"; ops->priv = st40; ops->num_port = ctx->para.num_ports; + if (ctx->same_dual_port) ops->num_port = 1; memcpy(ops->dip_addr[MTL_SESSION_PORT_P], ctx->mcast_ip_addr[MTL_PORT_P], MTL_IP_ADDR_LEN); snprintf(ops->port[MTL_SESSION_PORT_P], MTL_PORT_MAX_LEN, "%s", diff --git a/tests/src/tests.cpp b/tests/src/tests.cpp index 2ce442d4e..fb0db1a49 100644 --- a/tests/src/tests.cpp +++ b/tests/src/tests.cpp @@ -570,7 +570,6 @@ GTEST_API_ int main(int argc, char** argv) { for (int i = 0; i < ctx->para.num_ports; i++) { ctx->para.pmd[i] = mtl_pmd_by_port_name(ctx->para.port[i]); if (ctx->para.pmd[i] != MTL_PMD_DPDK_USER) { - mtl_get_if_ip(ctx->para.port[i], ctx->para.sip_addr[i], ctx->para.netmask[i]); ctx->para.flags |= MTL_FLAG_RX_SEPARATE_VIDEO_LCORE; } else { link_flap_wa = true; @@ -586,11 +585,18 @@ GTEST_API_ int main(int argc, char** argv) { return -EIO; } - if (ctx->dhcp) { - for (int i = 0; i < ctx->para.num_ports; i++) { - /* get the assigned dhcp ip */ - mtl_port_ip_info(ctx->handle, (enum mtl_port)i, ctx->para.sip_addr[i], - ctx->para.netmask[i], ctx->para.gateway[i]); + for (int i = 0; i < ctx->para.num_ports; i++) { + mtl_port_ip_info(ctx->handle, (enum mtl_port)i, ctx->para.sip_addr[i], + ctx->para.netmask[i], ctx->para.gateway[i]); + uint8_t* ip = ctx->para.sip_addr[i]; + info("%s, if ip %u.%u.%u.%u for port %s\n", __func__, ip[0], ip[1], ip[2], ip[3], + ctx->para.port[i]); + } + + if (ctx->para.num_ports > 1) { + if (0 == strcmp(ctx->para.port[MTL_PORT_P], ctx->para.port[MTL_PORT_R])) { + /* for test with --p_port kernel:lo --r_port kernel:lo */ + ctx->same_dual_port = true; } } diff --git a/tests/src/tests.h b/tests/src/tests.h index bc3bbf96c..f6fb59f56 100644 --- a/tests/src/tests.h +++ b/tests/src/tests.h @@ -95,6 +95,7 @@ struct st_tests_context { bool dhcp; enum mtl_iova_mode iova; enum mtl_rss_mode rss_mode; + bool same_dual_port; st22_encoder_dev_handle encoder_dev_handle; st22_decoder_dev_handle decoder_dev_handle;