Version in base suite: 20.11.6-1~deb11u1 Version in overlay suite: 20.11.7-1~deb11u1 Base version: dpdk_20.11.7-1~deb11u1 Target version: dpdk_20.11.8-1~deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/d/dpdk/dpdk_20.11.7-1~deb11u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/d/dpdk/dpdk_20.11.8-1~deb11u1.dsc .github/workflows/build.yml | 14 VERSION | 2 app/test-bbdev/test_bbdev_perf.c | 38 app/test-compress-perf/comp_perf_options.h | 6 app/test-compress-perf/comp_perf_options_parse.c | 8 app/test-compress-perf/comp_perf_test_common.c | 127 +- app/test-compress-perf/comp_perf_test_cyclecount.c | 75 - app/test-compress-perf/comp_perf_test_throughput.c | 64 - app/test-compress-perf/comp_perf_test_verify.c | 62 - app/test-compress-perf/main.c | 8 app/test-crypto-perf/cperf_options_parsing.c | 1 app/test-crypto-perf/cperf_test_common.c | 8 app/test-crypto-perf/cperf_test_vector_parsing.c | 1 app/test-flow-perf/main.c | 8 app/test-pmd/cmdline.c | 32 app/test-pmd/cmdline_flow.c | 48 app/test-pmd/csumonly.c | 17 app/test-pmd/ieee1588fwd.c | 2 app/test-pmd/noisy_vnf.c | 5 app/test-pmd/testpmd.c | 112 + app/test-pmd/testpmd.h | 1 app/test/packet_burst_generator.c | 26 app/test/test_cryptodev.c | 12 app/test/test_cryptodev_security_pdcp_test_vectors.h | 8 app/test/test_mbuf.c | 2 app/test/test_reorder.c | 2 config/meson.build | 6 debian/changelog | 7 devtools/check-git-log.sh | 2 doc/guides/linux_gsg/enable_func.rst | 4 doc/guides/prog_guide/cryptodev_lib.rst | 123 -- doc/guides/prog_guide/event_timer_adapter.rst | 2 doc/guides/rel_notes/release_20_11.rst | 269 ++++ doc/guides/sample_app_ug/l2_forward_cat.rst | 9 doc/guides/sample_app_ug/pipeline.rst | 2 drivers/baseband/acc100/rte_acc100_pmd.c | 9 drivers/baseband/turbo_sw/meson.build | 26 drivers/bus/ifpga/ifpga_bus.c | 3 drivers/common/mlx5/mlx5_common.h | 7 drivers/compress/qat/qat_comp_pmd.c | 2 drivers/crypto/ccp/ccp_dev.c | 4 drivers/crypto/ccp/ccp_pci.c | 3 drivers/crypto/ccp/rte_ccp_pmd.c | 2 drivers/crypto/qat/qat_sym_session.c | 5 drivers/crypto/snow3g/rte_snow3g_pmd.c | 13 drivers/net/bnxt/bnxt_ethdev.c | 2 drivers/net/bnxt/bnxt_rxq.c | 6 drivers/net/bnxt/bnxt_rxr.c | 1 drivers/net/bnxt/bnxt_txr.c | 6 drivers/net/e1000/em_rxtx.c | 3 drivers/net/hns3/hns3_cmd.h | 1 drivers/net/hns3/hns3_ethdev.c | 36 drivers/net/hns3/hns3_ethdev.h | 9 drivers/net/hns3/hns3_ethdev_vf.c | 25 drivers/net/hns3/hns3_fdir.h | 10 drivers/net/hns3/hns3_flow.c | 1082 ++++++++++++------- drivers/net/hns3/hns3_mp.c | 4 drivers/net/hns3/hns3_rss.c | 689 ++++++++---- drivers/net/hns3/hns3_rss.h | 135 +- drivers/net/hns3/hns3_rxtx.c | 78 + drivers/net/hns3/hns3_rxtx.h | 2 drivers/net/i40e/i40e_ethdev.c | 67 - drivers/net/i40e/i40e_ethdev.h | 5 drivers/net/i40e/i40e_flow.c | 8 drivers/net/iavf/iavf.h | 1 drivers/net/iavf/iavf_ethdev.c | 3 drivers/net/iavf/iavf_generic_flow.c | 3 drivers/net/iavf/iavf_vchnl.c | 72 - drivers/net/ice/ice_generic_flow.c | 8 drivers/net/ipn3ke/ipn3ke_ethdev.c | 2 drivers/net/ipn3ke/ipn3ke_representor.c | 2 drivers/net/ixgbe/ixgbe_ethdev.c | 31 drivers/net/ixgbe/ixgbe_flow.c | 12 drivers/net/mlx5/linux/mlx5_ethdev_os.c | 19 drivers/net/mlx5/mlx5_flow.c | 5 drivers/net/mlx5/mlx5_rxtx.c | 135 +- drivers/net/mlx5/mlx5_rxtx.h | 4 drivers/net/mlx5/mlx5_rxtx_vec.c | 13 drivers/net/mlx5/mlx5_rxtx_vec_altivec.h | 16 drivers/net/mlx5/mlx5_rxtx_vec_neon.h | 10 drivers/net/mlx5/mlx5_rxtx_vec_sse.h | 9 drivers/net/mlx5/mlx5_stats.c | 3 drivers/net/mlx5/mlx5_trigger.c | 2 drivers/net/mlx5/mlx5_txpp.c | 4 drivers/net/nfp/nfp_net.c | 9 drivers/net/sfc/sfc_mae.c | 16 drivers/net/txgbe/base/txgbe_phy.c | 7 drivers/net/txgbe/txgbe_ethdev.c | 5 drivers/net/txgbe/txgbe_rxtx.c | 26 drivers/net/vhost/rte_eth_vhost.c | 316 ++--- drivers/net/virtio/virtio_ethdev.c | 6 drivers/net/virtio/virtio_pci.c | 28 drivers/net/virtio/virtio_rxtx.c | 25 drivers/net/virtio/virtio_user_ethdev.c | 11 drivers/raw/ifpga/base/opae_hw_api.c | 4 drivers/raw/skeleton/skeleton_rawdev.c | 6 drivers/raw/skeleton/skeleton_rawdev_test.c | 48 drivers/vdpa/ifc/ifcvf_vdpa.c | 7 examples/cmdline/parse_obj_list.h | 3 examples/qos_sched/init.c | 12 examples/qos_sched/profile.cfg | 4 examples/qos_sched/profile_ov.cfg | 6 examples/vm_power_manager/channel_manager.c | 19 kernel/linux/kni/compat.h | 4 lib/librte_acl/acl_run_altivec.h | 2 lib/librte_cmdline/cmdline.c | 12 lib/librte_cmdline/cmdline_os_unix.c | 6 lib/librte_cmdline/cmdline_os_windows.c | 14 lib/librte_cmdline/cmdline_private.h | 3 lib/librte_compressdev/rte_compressdev.h | 2 lib/librte_compressdev/rte_compressdev_pmd.c | 6 lib/librte_cryptodev/rte_crypto_sym.h | 4 lib/librte_cryptodev/rte_cryptodev.h | 6 lib/librte_cryptodev/rte_cryptodev_pmd.c | 7 lib/librte_cryptodev/rte_cryptodev_pmd.h | 3 lib/librte_eal/common/eal_common_fbarray.c | 3 lib/librte_eal/freebsd/eal_alarm.c | 6 lib/librte_eal/freebsd/eal_hugepage_info.c | 2 lib/librte_eal/include/generic/rte_atomic.h | 12 lib/librte_eal/include/rte_bitmap.h | 2 lib/librte_eal/include/rte_hexdump.h | 4 lib/librte_eal/include/rte_service_component.h | 2 lib/librte_eal/linux/eal_hugepage_info.c | 2 lib/librte_eal/windows/eal.c | 3 lib/librte_eal/windows/include/pthread.h | 3 lib/librte_eventdev/rte_event_eth_tx_adapter.c | 2 lib/librte_eventdev/rte_event_timer_adapter.c | 97 + lib/librte_fib/rte_fib.h | 2 lib/librte_fib/rte_fib6.h | 2 lib/librte_graph/node.c | 8 lib/librte_ipsec/rte_ipsec_sad.h | 2 lib/librte_kni/rte_kni.c | 4 lib/librte_kvargs/rte_kvargs.h | 14 lib/librte_lpm/rte_lpm.h | 2 lib/librte_lpm/rte_lpm6.h | 2 lib/librte_mempool/rte_mempool.h | 89 - lib/librte_pdump/rte_pdump.c | 2 lib/librte_rcu/rte_rcu_qsbr.h | 3 lib/librte_reorder/rte_reorder.c | 96 + lib/librte_reorder/rte_reorder.h | 3 lib/librte_rib/rte_rib.h | 2 lib/librte_rib/rte_rib6.h | 2 lib/librte_ring/rte_ring_elem.h | 10 lib/librte_telemetry/telemetry.c | 2 lib/librte_vhost/rte_vhost_async.h | 18 lib/librte_vhost/socket.c | 8 lib/librte_vhost/vhost.h | 5 lib/librte_vhost/vhost_user.c | 28 lib/librte_vhost/virtio_net.c | 6 149 files changed, 3107 insertions(+), 1678 deletions(-) diff -Nru dpdk-20.11.7/.github/workflows/build.yml dpdk-20.11.8/.github/workflows/build.yml --- dpdk-20.11.7/.github/workflows/build.yml 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/.github/workflows/build.yml 2023-04-27 17:57:22.000000000 +0000 @@ -28,29 +28,29 @@ fail-fast: false matrix: config: - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: gcc library: static - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: gcc library: shared checks: abi+doc+tests - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: clang library: static - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: clang library: shared checks: doc+tests - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: gcc library: static cross: i386 - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: gcc library: static cross: aarch64 - - os: ubuntu-18.04 + - os: ubuntu-20.04 compiler: gcc library: shared cross: aarch64 diff -Nru dpdk-20.11.7/VERSION dpdk-20.11.8/VERSION --- dpdk-20.11.7/VERSION 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/VERSION 2023-04-27 17:57:22.000000000 +0000 @@ -1 +1 @@ -20.11.7 +20.11.8 diff -Nru dpdk-20.11.7/app/test/packet_burst_generator.c dpdk-20.11.8/app/test/packet_burst_generator.c --- dpdk-20.11.7/app/test/packet_burst_generator.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test/packet_burst_generator.c 2023-04-27 17:57:22.000000000 +0000 @@ -262,11 +262,11 @@ void *ip_hdr, uint8_t ipv4, struct rte_udp_hdr *udp_hdr, int nb_pkt_per_burst, uint8_t pkt_len, uint8_t nb_pkt_segs) { - int i, nb_pkt = 0; - size_t eth_hdr_size; - + const uint8_t pkt_seg_data_len = pkt_len / nb_pkt_segs; struct rte_mbuf *pkt_seg; struct rte_mbuf *pkt; + size_t eth_hdr_size; + int i, nb_pkt = 0; for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { pkt = rte_pktmbuf_alloc(mp); @@ -277,7 +277,7 @@ break; } - pkt->data_len = pkt_len; + pkt->data_len = pkt_seg_data_len; pkt_seg = pkt; for (i = 1; i < nb_pkt_segs; i++) { pkt_seg->next = rte_pktmbuf_alloc(mp); @@ -287,7 +287,10 @@ goto nomore_mbuf; } pkt_seg = pkt_seg->next; - pkt_seg->data_len = pkt_len; + if (i != nb_pkt_segs - 1) + pkt_seg->data_len = pkt_seg_data_len; + else + pkt_seg->data_len = pkt_seg_data_len + pkt_len % nb_pkt_segs; } pkt_seg->next = NULL; /* Last segment of packet. */ @@ -343,11 +346,11 @@ uint8_t ipv4, uint8_t proto, void *proto_hdr, int nb_pkt_per_burst, uint8_t pkt_len, uint8_t nb_pkt_segs) { - int i, nb_pkt = 0; - size_t eth_hdr_size; - + const uint8_t pkt_seg_data_len = pkt_len / nb_pkt_segs; struct rte_mbuf *pkt_seg; struct rte_mbuf *pkt; + size_t eth_hdr_size; + int i, nb_pkt = 0; for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) { pkt = rte_pktmbuf_alloc(mp); @@ -358,7 +361,7 @@ break; } - pkt->data_len = pkt_len; + pkt->data_len = pkt_seg_data_len; pkt_seg = pkt; for (i = 1; i < nb_pkt_segs; i++) { pkt_seg->next = rte_pktmbuf_alloc(mp); @@ -368,7 +371,10 @@ goto nomore_mbuf; } pkt_seg = pkt_seg->next; - pkt_seg->data_len = pkt_len; + if (i != nb_pkt_segs - 1) + pkt_seg->data_len = pkt_seg_data_len; + else + pkt_seg->data_len = pkt_seg_data_len + pkt_len % nb_pkt_segs; } pkt_seg->next = NULL; /* Last segment of packet. */ diff -Nru dpdk-20.11.7/app/test/test_cryptodev.c dpdk-20.11.8/app/test/test_cryptodev.c --- dpdk-20.11.7/app/test/test_cryptodev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test/test_cryptodev.c 2023-04-27 17:57:22.000000000 +0000 @@ -10172,11 +10172,11 @@ TEST_ASSERT((stats.enqueued_count == 1), "rte_cryptodev_stats_get returned unexpected enqueued stat"); TEST_ASSERT((stats.dequeued_count == 1), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); + "rte_cryptodev_stats_get returned unexpected dequeued stat"); TEST_ASSERT((stats.enqueue_err_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); + "rte_cryptodev_stats_get returned unexpected enqueued error count stat"); TEST_ASSERT((stats.dequeue_err_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); + "rte_cryptodev_stats_get returned unexpected dequeued error count stat"); /* invalid device but should ignore and not reset device stats*/ rte_cryptodev_stats_reset(ts_params->valid_devs[0] + 300); @@ -10184,7 +10184,7 @@ &stats), "rte_cryptodev_stats_get failed"); TEST_ASSERT((stats.enqueued_count == 1), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); + "rte_cryptodev_stats_get returned unexpected enqueued stat after invalid reset"); /* check that a valid reset clears stats */ rte_cryptodev_stats_reset(ts_params->valid_devs[0]); @@ -10192,9 +10192,9 @@ &stats), "rte_cryptodev_stats_get failed"); TEST_ASSERT((stats.enqueued_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); + "rte_cryptodev_stats_get returned unexpected enqueued stat after valid reset"); TEST_ASSERT((stats.dequeued_count == 0), - "rte_cryptodev_stats_get returned unexpected enqueued stat"); + "rte_cryptodev_stats_get returned unexpected dequeued stat after valid reset"); return TEST_SUCCESS; } diff -Nru dpdk-20.11.7/app/test/test_cryptodev_security_pdcp_test_vectors.h dpdk-20.11.8/app/test/test_cryptodev_security_pdcp_test_vectors.h --- dpdk-20.11.7/app/test/test_cryptodev_security_pdcp_test_vectors.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test/test_cryptodev_security_pdcp_test_vectors.h 2023-04-27 17:57:22.000000000 +0000 @@ -5441,7 +5441,7 @@ 0xC2, 0xE2, 0x91, 0x91, 0xA3, 0x9C, 0xE6, 0x30, 0x69, 0x70, 0x33, 0x8A, 0x15, 0xD0, 0x36, 0x47, 0x0E, 0x8F, 0xEE, 0x2C, 0x96, 0x0C, 0xD7, 0x7D, 0x70, 0x1B, 0x01, 0x7F, 0x96, 0x46, - 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD}, + 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD, 0x00, 0x00, 0x00, 0x00}, /* Control Plane w/NULL enc. + NULL int. DL LONG SN */ (uint8_t[]){0xA0, 0x00, 0x86, 0xB8, 0xF8, 0xDB, 0x2D, 0x3F, 0x23, 0x82, 0x53, 0xFD, 0x37, 0xDE, 0x88, 0x63, 0x08, 0x4F, 0xD3, 0x71, @@ -5449,7 +5449,7 @@ 0xC2, 0xE2, 0x91, 0x91, 0xA3, 0x9C, 0xE6, 0x30, 0x69, 0x70, 0x33, 0x8A, 0x15, 0xD0, 0x36, 0x47, 0x0E, 0x8F, 0xEE, 0x2C, 0x96, 0x0C, 0xD7, 0x7D, 0x70, 0x1B, 0x01, 0x7F, 0x96, 0x46, - 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD}, + 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD, 0x00, 0x00, 0x00, 0x00}, /* Control Plane w/NULL enc. + SNOW f9 int. UL LONG SN */ (uint8_t[]){0x00, 0x01, 0x86, 0xB8, 0xF8, 0xDB, 0x2D, 0x3F, 0x23, 0x82, 0x53, 0xFD, 0x37, 0xDE, 0x88, 0x63, 0x08, 0x4F, 0xD3, 0x71, @@ -5835,7 +5835,7 @@ 0xC2, 0xE2, 0x91, 0x91, 0xA3, 0x9C, 0xE6, 0x30, 0x69, 0x70, 0x33, 0x8A, 0x15, 0xD0, 0x36, 0x47, 0x0E, 0x8F, 0xEE, 0x2C, 0x96, 0x0C, 0xD7, 0x7D, 0x70, 0x1B, 0x01, 0x7F, 0x96, 0x46, - 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD}, + 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD, 0x00, 0x00, 0x00, 0x00}, /* User Plane w/NULL enc. + NULL int. DL for 12-bit SN */ (uint8_t[]){0xA0, 0x00, 0x86, 0xB8, 0xF8, 0xDB, 0x2D, 0x3F, 0x23, 0x82, 0x53, 0xFD, 0x37, 0xDE, 0x88, 0x63, 0x08, 0x4F, 0xD3, 0x71, @@ -5843,7 +5843,7 @@ 0xC2, 0xE2, 0x91, 0x91, 0xA3, 0x9C, 0xE6, 0x30, 0x69, 0x70, 0x33, 0x8A, 0x15, 0xD0, 0x36, 0x47, 0x0E, 0x8F, 0xEE, 0x2C, 0x96, 0x0C, 0xD7, 0x7D, 0x70, 0x1B, 0x01, 0x7F, 0x96, 0x46, - 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD}, + 0x53, 0xB0, 0xA4, 0x7A, 0xF9, 0xDD, 0x00, 0x00, 0x00, 0x00}, /* User Plane w/NULL enc. + SNOW f9 int. UL for 12-bit SN */ (uint8_t[]){0x80, 0x01, 0x86, 0xB8, 0xF8, 0xDB, 0x2D, 0x3F, 0x23, 0x82, 0x53, 0xFD, 0x37, 0xDE, 0x88, 0x63, 0x08, 0x4F, 0xD3, 0x71, diff -Nru dpdk-20.11.7/app/test/test_mbuf.c dpdk-20.11.8/app/test/test_mbuf.c --- dpdk-20.11.7/app/test/test_mbuf.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test/test_mbuf.c 2023-04-27 17:57:22.000000000 +0000 @@ -2744,6 +2744,7 @@ /* split m0 chain in two, between m1 and m2 */ m0->nb_segs = 2; + m0->pkt_len -= m2->data_len; m1->next = NULL; m2->nb_segs = 1; @@ -2764,6 +2765,7 @@ m2->nb_segs != 1 || m2->next != NULL) GOTO_FAIL("nb_segs or next was not reset properly"); + rte_mempool_free(pool); return 0; fail: diff -Nru dpdk-20.11.7/app/test/test_reorder.c dpdk-20.11.8/app/test/test_reorder.c --- dpdk-20.11.7/app/test/test_reorder.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test/test_reorder.c 2023-04-27 17:57:22.000000000 +0000 @@ -270,6 +270,7 @@ } if (robufs[0] != NULL) rte_pktmbuf_free(robufs[0]); + memset(robufs, 0, sizeof(robufs)); /* Insert more packets * RB[] = {NULL, NULL, NULL, NULL} @@ -306,6 +307,7 @@ if (robufs[i] != NULL) rte_pktmbuf_free(robufs[i]); } + memset(robufs, 0, sizeof(robufs)); /* * RB[] = {NULL, NULL, NULL, NULL} diff -Nru dpdk-20.11.7/app/test-bbdev/test_bbdev_perf.c dpdk-20.11.8/app/test-bbdev/test_bbdev_perf.c --- dpdk-20.11.7/app/test-bbdev/test_bbdev_perf.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-bbdev/test_bbdev_perf.c 2023-04-27 17:57:22.000000000 +0000 @@ -70,13 +70,12 @@ #define SYNC_WAIT 0 #define SYNC_START 1 -#define INVALID_OPAQUE -1 #define INVALID_QUEUE_ID -1 /* Increment for next code block in external HARQ memory */ #define HARQ_INCR 32768 /* Headroom for filler LLRs insertion in HARQ buffer */ -#define FILLER_HEADROOM 1024 +#define FILLER_HEADROOM 2048 /* Constants from K0 computation from 3GPP 38.212 Table 5.4.2.1-2 */ #define N_ZC_1 66 /* N = 66 Zc for BG 1 */ #define N_ZC_2 50 /* N = 50 Zc for BG 2 */ @@ -87,6 +86,7 @@ #define K0_3_1 56 /* K0 fraction numerator for rv 3 and BG 1 */ #define K0_3_2 43 /* K0 fraction numerator for rv 3 and BG 2 */ +#define HARQ_MEM_TOLERANCE 256 static struct test_bbdev_vector test_vector; /* Switch between PMD and Interrupt for throughput TC */ @@ -1779,10 +1779,9 @@ "op_status (%d) != expected_status (%d)", op->status, expected_status); - if (op->opaque_data != (void *)(uintptr_t)INVALID_OPAQUE) - TEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data, - "Ordering error, expected %p, got %p", - (void *)(uintptr_t)order_idx, op->opaque_data); + TEST_ASSERT((void *)(uintptr_t)order_idx == op->opaque_data, + "Ordering error, expected %p, got %p", + (void *)(uintptr_t)order_idx, op->opaque_data); return TEST_SUCCESS; } @@ -1904,13 +1903,17 @@ uint16_t data_len = rte_pktmbuf_data_len(m) - offset; total_data_size += orig_op->segments[i].length; - TEST_ASSERT(orig_op->segments[i].length < - (uint32_t)(data_len + 64), + TEST_ASSERT(orig_op->segments[i].length < (uint32_t)(data_len + HARQ_MEM_TOLERANCE), "Length of segment differ in original (%u) and filled (%u) op", orig_op->segments[i].length, data_len); harq_orig = (int8_t *) orig_op->segments[i].addr; harq_out = rte_pktmbuf_mtod_offset(m, int8_t *, offset); + /* Cannot compare HARQ output data for such cases */ + if ((ldpc_llr_decimals > 1) && ((ops_ld->op_flags & RTE_BBDEV_LDPC_LLR_COMPRESSION) + || (ops_ld->op_flags & RTE_BBDEV_LDPC_HARQ_6BIT_COMPRESSION))) + break; + if (!(ldpc_cap_flags & RTE_BBDEV_LDPC_INTERNAL_HARQ_MEMORY_FILLERS ) || (ops_ld->op_flags & @@ -1925,9 +1928,9 @@ ops_ld->n_filler; if (data_len > deRmOutSize) data_len = deRmOutSize; - if (data_len > orig_op->segments[i].length) - data_len = orig_op->segments[i].length; } + if (data_len > orig_op->segments[i].length) + data_len = orig_op->segments[i].length; /* * HARQ output can have minor differences * due to integer representation and related scaling @@ -1986,7 +1989,7 @@ /* Validate total mbuf pkt length */ uint32_t pkt_len = rte_pktmbuf_pkt_len(op->data) - op->offset; - TEST_ASSERT(total_data_size < pkt_len + 64, + TEST_ASSERT(total_data_size < pkt_len + HARQ_MEM_TOLERANCE, "Length of data differ in original (%u) and filled (%u) op", total_data_size, pkt_len); @@ -4361,7 +4364,8 @@ if (unlikely(num_to_process - dequeued < burst_sz)) burst_sz = num_to_process - dequeued; - rte_bbdev_dec_op_alloc_bulk(mempool, ops_enq, burst_sz); + ret = rte_bbdev_dec_op_alloc_bulk(mempool, ops_enq, burst_sz); + TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", burst_sz); if (test_vector.op_type != RTE_BBDEV_OP_NONE) copy_reference_dec_op(ops_enq, burst_sz, dequeued, bufs->inputs, @@ -4446,7 +4450,8 @@ if (unlikely(num_to_process - dequeued < burst_sz)) burst_sz = num_to_process - dequeued; - rte_bbdev_dec_op_alloc_bulk(mempool, ops_enq, burst_sz); + ret = rte_bbdev_dec_op_alloc_bulk(mempool, ops_enq, burst_sz); + TEST_ASSERT_SUCCESS(ret, "Allocation failed for %d ops", burst_sz); if (test_vector.op_type != RTE_BBDEV_OP_NONE) copy_reference_ldpc_dec_op(ops_enq, burst_sz, dequeued, bufs->inputs, @@ -4698,7 +4703,7 @@ printf("Set RTE_BBDEV_OFFLOAD_COST to 'y' to turn the test on.\n"); return TEST_SKIPPED; #else - int iter; + int iter, ret; uint16_t burst_sz = op_params->burst_sz; const uint16_t num_to_process = op_params->num_to_process; const enum rte_bbdev_op_type op_type = test_vector.op_type; @@ -4789,7 +4794,10 @@ rte_get_tsc_hz()); struct rte_bbdev_stats stats = {0}; - get_bbdev_queue_stats(ad->dev_id, queue_id, &stats); + ret = get_bbdev_queue_stats(ad->dev_id, queue_id, &stats); + TEST_ASSERT_SUCCESS(ret, + "Failed to get stats for queue (%u) of device (%u)", + queue_id, ad->dev_id); if (op_type != RTE_BBDEV_OP_LDPC_DEC) { TEST_ASSERT_SUCCESS(stats.enqueued_count != num_to_process, "Mismatch in enqueue count %10"PRIu64" %d", diff -Nru dpdk-20.11.7/app/test-compress-perf/comp_perf_options.h dpdk-20.11.8/app/test-compress-perf/comp_perf_options.h --- dpdk-20.11.7/app/test-compress-perf/comp_perf_options.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/comp_perf_options.h 2023-04-27 17:57:22.000000000 +0000 @@ -30,9 +30,9 @@ }; enum comp_operation { - COMPRESS_ONLY, - DECOMPRESS_ONLY, - COMPRESS_DECOMPRESS + COMPRESS = (1 << 0), + DECOMPRESS = (1 << 1), + COMPRESS_DECOMPRESS = (COMPRESS | DECOMPRESS), }; struct range_list { diff -Nru dpdk-20.11.7/app/test-compress-perf/comp_perf_options_parse.c dpdk-20.11.8/app/test-compress-perf/comp_perf_options_parse.c --- dpdk-20.11.7/app/test-compress-perf/comp_perf_options_parse.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/comp_perf_options_parse.c 2023-04-27 17:57:22.000000000 +0000 @@ -446,11 +446,11 @@ struct name_id_map optype_namemap[] = { { "comp", - COMPRESS_ONLY + COMPRESS }, { "decomp", - DECOMPRESS_ONLY + DECOMPRESS }, { "comp_and_decomp", @@ -491,7 +491,7 @@ int id = get_str_key_id_mapping(huffman_namemap, RTE_DIM(huffman_namemap), arg); if (id < 0) { - RTE_LOG(ERR, USER1, "Invalid Huffmane encoding specified\n"); + RTE_LOG(ERR, USER1, "Invalid Huffman encoding specified\n"); return -1; } @@ -507,7 +507,7 @@ /* * Try parsing the argument as a range, if it fails, - * arse it as a list + * parse it as a list */ if (parse_range(arg, &test_data->level_lst.min, &test_data->level_lst.max, diff -Nru dpdk-20.11.7/app/test-compress-perf/comp_perf_test_common.c dpdk-20.11.8/app/test-compress-perf/comp_perf_test_common.c --- dpdk-20.11.7/app/test-compress-perf/comp_perf_test_common.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/comp_perf_test_common.c 2023-04-27 17:57:22.000000000 +0000 @@ -227,23 +227,43 @@ { uint16_t comp_mbuf_size; uint16_t decomp_mbuf_size; + size_t comp_data_size; + size_t decomp_data_size; + size_t output_data_sz; test_data->out_seg_sz = find_buf_size(test_data->seg_sz); - /* Number of segments for input and output - * (compression and decompression) - */ - test_data->total_segs = DIV_CEIL(test_data->input_data_sz, - test_data->seg_sz); + if (test_data->test_op & COMPRESS) { + /* + * Number of segments for input and output + * (compression and decompression) + */ + test_data->total_segs = DIV_CEIL(test_data->input_data_sz, + test_data->seg_sz); + } else { + /* + * When application does decompression only, input data is + * compressed and smaller than the output. The expected size of + * uncompressed data given by the user in segment size argument. + */ + test_data->total_segs = test_data->max_sgl_segs; + } + + output_data_sz = (size_t) test_data->out_seg_sz * test_data->total_segs; + output_data_sz = + RTE_MAX(output_data_sz, (size_t) MIN_COMPRESSED_BUF_SIZE); if (test_data->use_external_mbufs != 0) { if (comp_perf_allocate_external_mbufs(test_data, mem) < 0) return -1; comp_mbuf_size = 0; decomp_mbuf_size = 0; - } else { + } else if (test_data->test_op & COMPRESS) { comp_mbuf_size = test_data->out_seg_sz + RTE_PKTMBUF_HEADROOM; decomp_mbuf_size = test_data->seg_sz + RTE_PKTMBUF_HEADROOM; + } else { + comp_mbuf_size = test_data->seg_sz + RTE_PKTMBUF_HEADROOM; + decomp_mbuf_size = test_data->out_seg_sz + RTE_PKTMBUF_HEADROOM; } char pool_name[32] = ""; @@ -287,26 +307,28 @@ return -1; } - /* - * Compressed data might be a bit larger than input data, - * if data cannot be compressed - */ - mem->compressed_data = rte_zmalloc_socket(NULL, - RTE_MAX( - (size_t) test_data->out_seg_sz * - test_data->total_segs, - (size_t) MIN_COMPRESSED_BUF_SIZE), - 0, - rte_socket_id()); + if (test_data->test_op & COMPRESS) { + /* + * Compressed data might be a bit larger than input data, + * if data cannot be compressed + */ + comp_data_size = output_data_sz; + decomp_data_size = test_data->input_data_sz; + } else { + comp_data_size = test_data->input_data_sz; + decomp_data_size = output_data_sz; + } + + mem->compressed_data = rte_zmalloc_socket(NULL, comp_data_size, 0, + rte_socket_id()); if (mem->compressed_data == NULL) { RTE_LOG(ERR, USER1, "Memory to hold the data from the input " "file could not be allocated\n"); return -1; } - mem->decompressed_data = rte_zmalloc_socket(NULL, - test_data->input_data_sz, 0, - rte_socket_id()); + mem->decompressed_data = rte_zmalloc_socket(NULL, decomp_data_size, 0, + rte_socket_id()); if (mem->decompressed_data == NULL) { RTE_LOG(ERR, USER1, "Memory to hold the data from the input " "file could not be allocated\n"); @@ -344,6 +366,7 @@ prepare_bufs(struct comp_test_data *test_data, struct cperf_mem_resources *mem) { uint32_t remaining_data = test_data->input_data_sz; + uint32_t remaining_data_decomp = test_data->input_data_sz; uint8_t *input_data_ptr = test_data->input_data; size_t data_sz = 0; uint8_t *data_addr; @@ -351,6 +374,7 @@ uint16_t segs_per_mbuf = 0; uint32_t cmz = 0; uint32_t dmz = 0; + bool decompress_only = !!(test_data->test_op == DECOMPRESS); for (i = 0; i < mem->total_bufs; i++) { /* Allocate data in input mbuf and copy data from input file */ @@ -361,8 +385,6 @@ return -1; } - data_sz = RTE_MIN(remaining_data, test_data->seg_sz); - if (test_data->use_external_mbufs != 0) { rte_pktmbuf_attach_extbuf(mem->decomp_bufs[i], mem->decomp_memzones[dmz]->addr, @@ -372,16 +394,23 @@ dmz++; } + if (!decompress_only) + data_sz = RTE_MIN(remaining_data, test_data->seg_sz); + else + data_sz = test_data->out_seg_sz; + data_addr = (uint8_t *) rte_pktmbuf_append( mem->decomp_bufs[i], data_sz); if (data_addr == NULL) { RTE_LOG(ERR, USER1, "Could not append data\n"); return -1; } - rte_memcpy(data_addr, input_data_ptr, data_sz); - input_data_ptr += data_sz; - remaining_data -= data_sz; + if (!decompress_only) { + rte_memcpy(data_addr, input_data_ptr, data_sz); + input_data_ptr += data_sz; + remaining_data -= data_sz; + } /* Already one segment in the mbuf */ segs_per_mbuf = 1; @@ -398,8 +427,6 @@ return -1; } - data_sz = RTE_MIN(remaining_data, test_data->seg_sz); - if (test_data->use_external_mbufs != 0) { rte_pktmbuf_attach_extbuf( next_seg, @@ -410,6 +437,12 @@ dmz++; } + if (!decompress_only) + data_sz = RTE_MIN(remaining_data, + test_data->seg_sz); + else + data_sz = test_data->out_seg_sz; + data_addr = (uint8_t *)rte_pktmbuf_append(next_seg, data_sz); @@ -418,9 +451,11 @@ return -1; } - rte_memcpy(data_addr, input_data_ptr, data_sz); - input_data_ptr += data_sz; - remaining_data -= data_sz; + if (!decompress_only) { + rte_memcpy(data_addr, input_data_ptr, data_sz); + input_data_ptr += data_sz; + remaining_data -= data_sz; + } if (rte_pktmbuf_chain(mem->decomp_bufs[i], next_seg) < 0) { @@ -447,16 +482,26 @@ cmz++; } - data_addr = (uint8_t *) rte_pktmbuf_append( - mem->comp_bufs[i], - test_data->out_seg_sz); + if (decompress_only) + data_sz = RTE_MIN(remaining_data_decomp, test_data->seg_sz); + else + data_sz = test_data->out_seg_sz; + + data_addr = (uint8_t *) rte_pktmbuf_append(mem->comp_bufs[i], + data_sz); if (data_addr == NULL) { RTE_LOG(ERR, USER1, "Could not append data\n"); return -1; } + if (decompress_only) { + rte_memcpy(data_addr, input_data_ptr, data_sz); + input_data_ptr += data_sz; + remaining_data_decomp -= data_sz; + } + /* Chain mbufs if needed for output mbufs */ - for (j = 1; j < segs_per_mbuf; j++) { + for (j = 1; j < segs_per_mbuf && remaining_data_decomp > 0; j++) { struct rte_mbuf *next_seg = rte_pktmbuf_alloc(mem->comp_buf_pool); @@ -476,13 +521,25 @@ cmz++; } + if (decompress_only) + data_sz = RTE_MIN(remaining_data_decomp, + test_data->seg_sz); + else + data_sz = test_data->out_seg_sz; + data_addr = (uint8_t *)rte_pktmbuf_append(next_seg, - test_data->out_seg_sz); + data_sz); if (data_addr == NULL) { RTE_LOG(ERR, USER1, "Could not append data\n"); return -1; } + if (decompress_only) { + rte_memcpy(data_addr, input_data_ptr, data_sz); + input_data_ptr += data_sz; + remaining_data_decomp -= data_sz; + } + if (rte_pktmbuf_chain(mem->comp_bufs[i], next_seg) < 0) { RTE_LOG(ERR, USER1, "Could not chain mbufs\n"); diff -Nru dpdk-20.11.7/app/test-compress-perf/comp_perf_test_cyclecount.c dpdk-20.11.8/app/test-compress-perf/comp_perf_test_cyclecount.c --- dpdk-20.11.7/app/test-compress-perf/comp_perf_test_cyclecount.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/comp_perf_test_cyclecount.c 2023-04-27 17:57:22.000000000 +0000 @@ -510,38 +510,55 @@ if (cperf_verify_test_runner(&ctx->ver)) return EXIT_FAILURE; - /* - * Run the tests twice, discarding the first performance - * results, before the cache is warmed up - */ - - /* C O M P R E S S */ - for (i = 0; i < 2; i++) { - if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) - return EXIT_FAILURE; - } - - ops_enq_retries_comp = ctx->ops_enq_retries; - ops_deq_retries_comp = ctx->ops_deq_retries; - - duration_enq_per_op_comp = ctx->duration_enq / - (ctx->ver.mem.total_bufs * test_data->num_iter); - duration_deq_per_op_comp = ctx->duration_deq / - (ctx->ver.mem.total_bufs * test_data->num_iter); + if (test_data->test_op & COMPRESS) { + /* + * Run the test twice, discarding the first performance + * results, before the cache is warmed up + */ + for (i = 0; i < 2; i++) { + if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) + return EXIT_FAILURE; + } + + ops_enq_retries_comp = ctx->ops_enq_retries; + ops_deq_retries_comp = ctx->ops_deq_retries; + + duration_enq_per_op_comp = ctx->duration_enq / + (ctx->ver.mem.total_bufs * test_data->num_iter); + duration_deq_per_op_comp = ctx->duration_deq / + (ctx->ver.mem.total_bufs * test_data->num_iter); + } else { + ops_enq_retries_comp = 0; + ops_deq_retries_comp = 0; - /* D E C O M P R E S S */ - for (i = 0; i < 2; i++) { - if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) - return EXIT_FAILURE; + duration_enq_per_op_comp = 0; + duration_deq_per_op_comp = 0; } - ops_enq_retries_decomp = ctx->ops_enq_retries; - ops_deq_retries_decomp = ctx->ops_deq_retries; + if (test_data->test_op & DECOMPRESS) { + /* + * Run the test twice, discarding the first performance + * results, before the cache is warmed up + */ + for (i = 0; i < 2; i++) { + if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) + return EXIT_FAILURE; + } + + ops_enq_retries_decomp = ctx->ops_enq_retries; + ops_deq_retries_decomp = ctx->ops_deq_retries; + + duration_enq_per_op_decomp = ctx->duration_enq / + (ctx->ver.mem.total_bufs * test_data->num_iter); + duration_deq_per_op_decomp = ctx->duration_deq / + (ctx->ver.mem.total_bufs * test_data->num_iter); + } else { + ops_enq_retries_decomp = 0; + ops_deq_retries_decomp = 0; - duration_enq_per_op_decomp = ctx->duration_enq / - (ctx->ver.mem.total_bufs * test_data->num_iter); - duration_deq_per_op_decomp = ctx->duration_deq / - (ctx->ver.mem.total_bufs * test_data->num_iter); + duration_enq_per_op_decomp = 0; + duration_deq_per_op_decomp = 0; + } duration_setup_per_op = ctx->duration_op / (ctx->ver.mem.total_bufs * test_data->num_iter); @@ -558,7 +575,7 @@ " [D-e] - decompression enqueue\n" " [D-d] - decompression dequeue\n" " - Cycles section: number of cycles per 'op' for the following operations:\n" - " setup/op - memory allocation, op configuration and memory dealocation\n" + " setup/op - memory allocation, op configuration and memory deallocation\n" " [C-e] - compression enqueue\n" " [C-d] - compression dequeue\n" " [D-e] - decompression enqueue\n" diff -Nru dpdk-20.11.7/app/test-compress-perf/comp_perf_test_throughput.c dpdk-20.11.8/app/test-compress-perf/comp_perf_test_throughput.c --- dpdk-20.11.7/app/test-compress-perf/comp_perf_test_throughput.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/comp_perf_test_throughput.c 2023-04-27 17:57:22.000000000 +0000 @@ -355,41 +355,53 @@ * First the verification part is needed */ if (cperf_verify_test_runner(&ctx->ver)) { - ret = EXIT_FAILURE; + ret = EXIT_FAILURE; goto end; } - /* - * Run the tests twice, discarding the first performance - * results, before the cache is warmed up - */ - for (i = 0; i < 2; i++) { - if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) { - ret = EXIT_FAILURE; - goto end; + if (test_data->test_op & COMPRESS) { + /* + * Run the test twice, discarding the first performance + * results, before the cache is warmed up + */ + for (i = 0; i < 2; i++) { + if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) { + ret = EXIT_FAILURE; + goto end; + } } - } - for (i = 0; i < 2; i++) { - if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) { - ret = EXIT_FAILURE; - goto end; - } + ctx->comp_tsc_byte = + (double)(ctx->comp_tsc_duration[test_data->level]) / + test_data->input_data_sz; + ctx->comp_gbps = rte_get_tsc_hz() / ctx->comp_tsc_byte * 8 / + 1000000000; + } else { + ctx->comp_tsc_byte = 0; + ctx->comp_gbps = 0; } - ctx->comp_tsc_byte = - (double)(ctx->comp_tsc_duration[test_data->level]) / - test_data->input_data_sz; + if (test_data->test_op & DECOMPRESS) { + /* + * Run the test twice, discarding the first performance + * results, before the cache is warmed up + */ + for (i = 0; i < 2; i++) { + if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) { + ret = EXIT_FAILURE; + goto end; + } + } - ctx->decomp_tsc_byte = + ctx->decomp_tsc_byte = (double)(ctx->decomp_tsc_duration[test_data->level]) / - test_data->input_data_sz; - - ctx->comp_gbps = rte_get_tsc_hz() / ctx->comp_tsc_byte * 8 / - 1000000000; - - ctx->decomp_gbps = rte_get_tsc_hz() / ctx->decomp_tsc_byte * 8 / - 1000000000; + test_data->input_data_sz; + ctx->decomp_gbps = rte_get_tsc_hz() / ctx->decomp_tsc_byte * 8 / + 1000000000; + } else { + ctx->decomp_tsc_byte = 0; + ctx->decomp_gbps = 0; + } if (rte_atomic16_test_and_set(&display_once)) { printf("\n%12s%6s%12s%17s%15s%16s\n", diff -Nru dpdk-20.11.7/app/test-compress-perf/comp_perf_test_verify.c dpdk-20.11.8/app/test-compress-perf/comp_perf_test_verify.c --- dpdk-20.11.7/app/test-compress-perf/comp_perf_test_verify.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/comp_perf_test_verify.c 2023-04-27 17:57:22.000000000 +0000 @@ -112,7 +112,8 @@ output_data_sz = &ctx->decomp_data_sz; input_bufs = mem->comp_bufs; output_bufs = mem->decomp_bufs; - out_seg_sz = test_data->seg_sz; + out_seg_sz = (test_data->test_op & COMPRESS) ? + test_data->seg_sz : test_data->out_seg_sz; } /* Create private xform */ @@ -224,7 +225,7 @@ op->status == RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE) { RTE_LOG(ERR, USER1, -"Out of space error occurred due to uncompressible input data expanding to larger than destination buffer. Increase the EXPANSE_RATIO constant to use this data.\n"); +"Out of space error occurred due to incompressible input data expanding to larger than destination buffer. Increase the EXPANSE_RATIO constant to use this data.\n"); res = -1; goto end; } else if (op->status != @@ -309,7 +310,7 @@ op->status == RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE) { RTE_LOG(ERR, USER1, -"Out of space error occurred due to uncompressible input data expanding to larger than destination buffer. Increase the EXPANSE_RATIO constant to use this data.\n"); +"Out of space error occurred due to incompressible input data expanding to larger than destination buffer. Increase the EXPANSE_RATIO constant to use this data.\n"); res = -1; goto end; } else if (op->status != @@ -395,32 +396,47 @@ test_data->ratio = 0; - if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) { - ret = EXIT_FAILURE; - goto end; + if (test_data->test_op & COMPRESS) { + if (main_loop(ctx, RTE_COMP_COMPRESS) < 0) { + ret = EXIT_FAILURE; + goto end; + } } - if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) { - ret = EXIT_FAILURE; - goto end; - } + if (test_data->test_op & DECOMPRESS) { + if (main_loop(ctx, RTE_COMP_DECOMPRESS) < 0) { + ret = EXIT_FAILURE; + goto end; + } - if (ctx->decomp_data_sz != test_data->input_data_sz) { - RTE_LOG(ERR, USER1, - "Decompressed data length not equal to input data length\n"); - RTE_LOG(ERR, USER1, - "Decompressed size = %zu, expected = %zu\n", - ctx->decomp_data_sz, test_data->input_data_sz); - ret = EXIT_FAILURE; - goto end; - } else { - if (memcmp(ctx->mem.decompressed_data, - test_data->input_data, - test_data->input_data_sz) != 0) { + if (!(test_data->test_op & COMPRESS)) { + /* + * For DECOMPRESS_ONLY mode there is no more + * verifications, reset the 'ratio' and 'comp_data_sz' + * fields for other tests report. + */ + ctx->comp_data_sz = 0; + ctx->ratio = 0; + goto end; + } + + if (ctx->decomp_data_sz != test_data->input_data_sz) { + RTE_LOG(ERR, USER1, + "Decompressed data length not equal to input data length\n"); RTE_LOG(ERR, USER1, - "Decompressed data is not the same as file data\n"); + "Decompressed size = %zu, expected = %zu\n", + ctx->decomp_data_sz, test_data->input_data_sz); ret = EXIT_FAILURE; goto end; + } else { + if (memcmp(ctx->mem.decompressed_data, + test_data->input_data, + test_data->input_data_sz) != 0) { + RTE_LOG(ERR, USER1, + "Decompressed data is not the same as file data\n"); + ret = EXIT_FAILURE; + goto end; + } } } diff -Nru dpdk-20.11.7/app/test-compress-perf/main.c dpdk-20.11.8/app/test-compress-perf/main.c --- dpdk-20.11.7/app/test-compress-perf/main.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-compress-perf/main.c 2023-04-27 17:57:22.000000000 +0000 @@ -253,6 +253,14 @@ goto end; } + if (!(test_data->test_op & COMPRESS) && + test_data->input_data_sz > + (size_t) test_data->seg_sz * (size_t) test_data->max_sgl_segs) { + RTE_LOG(ERR, USER1, + "Size of input must be less than total segments\n"); + goto end; + } + test_data->input_data = rte_zmalloc_socket(NULL, test_data->input_data_sz, 0, rte_socket_id()); diff -Nru dpdk-20.11.7/app/test-crypto-perf/cperf_options_parsing.c dpdk-20.11.8/app/test-crypto-perf/cperf_options_parsing.c --- dpdk-20.11.7/app/test-crypto-perf/cperf_options_parsing.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-crypto-perf/cperf_options_parsing.c 2023-04-27 17:57:22.000000000 +0000 @@ -496,6 +496,7 @@ if (access(opts->test_file, F_OK) != -1) return 0; RTE_LOG(ERR, USER1, "Test vector file doesn't exist\n"); + free(opts->test_file); return -1; } diff -Nru dpdk-20.11.7/app/test-crypto-perf/cperf_test_common.c dpdk-20.11.8/app/test-crypto-perf/cperf_test_common.c --- dpdk-20.11.7/app/test-crypto-perf/cperf_test_common.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-crypto-perf/cperf_test_common.c 2023-04-27 17:57:22.000000000 +0000 @@ -166,9 +166,11 @@ RTE_CACHE_LINE_ROUNDUP(crypto_op_total_size); uint32_t mbuf_size = sizeof(struct rte_mbuf) + options->segment_sz; uint32_t max_size = options->max_buffer_size + options->digest_sz; - uint16_t segments_nb = (max_size % options->segment_sz) ? - (max_size / options->segment_sz) + 1 : - max_size / options->segment_sz; + uint32_t segment_data_len = options->segment_sz - options->headroom_sz - + options->tailroom_sz; + uint16_t segments_nb = (max_size % segment_data_len) ? + (max_size / segment_data_len) + 1 : + (max_size / segment_data_len); uint32_t obj_size = crypto_op_total_size_padded + (mbuf_size * segments_nb); diff -Nru dpdk-20.11.7/app/test-crypto-perf/cperf_test_vector_parsing.c dpdk-20.11.8/app/test-crypto-perf/cperf_test_vector_parsing.c --- dpdk-20.11.7/app/test-crypto-perf/cperf_test_vector_parsing.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-crypto-perf/cperf_test_vector_parsing.c 2023-04-27 17:57:22.000000000 +0000 @@ -28,6 +28,7 @@ rte_free(vector->cipher_key.data); rte_free(vector->auth_key.data); rte_free(vector->ciphertext.data); + free(opts->test_file); } rte_free(vector); diff -Nru dpdk-20.11.7/app/test-flow-perf/main.c dpdk-20.11.8/app/test-flow-perf/main.c --- dpdk-20.11.7/app/test-flow-perf/main.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-flow-perf/main.c 2023-04-27 17:57:22.000000000 +0000 @@ -709,13 +709,11 @@ if (strcmp(lgopts[opt_idx].name, "rules-batch") == 0) { n = atoi(optarg); - if (n >= DEFAULT_RULES_BATCH) + if (n > 0) rules_batch = n; - else { + else rte_exit(EXIT_FAILURE, - "rules_batch should be >= %d\n", - DEFAULT_RULES_BATCH); - } + "flow rules-batch should be > 0\n"); } if (strcmp(lgopts[opt_idx].name, "rules-count") == 0) { diff -Nru dpdk-20.11.7/app/test-pmd/cmdline.c dpdk-20.11.8/app/test-pmd/cmdline.c --- dpdk-20.11.7/app/test-pmd/cmdline.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/cmdline.c 2023-04-27 17:57:22.000000000 +0000 @@ -71,9 +71,8 @@ #include "cmdline_tm.h" #include "bpf_cmd.h" -static struct cmdline *testpmd_cl; - static void cmd_reconfig_device_queue(portid_t id, uint8_t dev, uint8_t queue); +static struct cmdline *testpmd_cl; /* *** Help command with introduction. *** */ struct cmd_help_brief_result { @@ -17195,35 +17194,28 @@ printf("Read CLI commands from %s\n", filename); } +void +prompt_exit(void) +{ + cmdline_quit(testpmd_cl); +} + /* prompt function, called from main on MAIN lcore */ void prompt(void) { - int ret; - /* initialize non-constant commands */ cmd_set_fwd_mode_init(); cmd_set_fwd_retry_mode_init(); testpmd_cl = cmdline_stdin_new(main_ctx, "testpmd> "); - if (testpmd_cl == NULL) + if (testpmd_cl == NULL) { + fprintf(stderr, + "Failed to create stdin based cmdline context\n"); return; - - ret = atexit(prompt_exit); - if (ret != 0) - printf("Cannot set exit function for cmdline\n"); + } cmdline_interact(testpmd_cl); - if (ret != 0) - cmdline_stdin_exit(testpmd_cl); -} - -void -prompt_exit(void) -{ - if (testpmd_cl != NULL) { - cmdline_quit(testpmd_cl); - cmdline_stdin_exit(testpmd_cl); - } + cmdline_stdin_exit(testpmd_cl); } static void diff -Nru dpdk-20.11.7/app/test-pmd/cmdline_flow.c dpdk-20.11.8/app/test-pmd/cmdline_flow.c --- dpdk-20.11.7/app/test-pmd/cmdline_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/cmdline_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -5281,15 +5281,15 @@ l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); memcpy(eth.src.addr_bytes, l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð, sizeof(eth)); - header += sizeof(eth); + memcpy(header, ð, sizeof(struct rte_ether_hdr)); + header += sizeof(struct rte_ether_hdr); if (l2_encap_conf.select_vlan) { if (l2_encap_conf.select_ipv4) vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); else vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan, sizeof(vlan)); - header += sizeof(vlan); + memcpy(header, &vlan, sizeof(struct rte_vlan_hdr)); + header += sizeof(struct rte_vlan_hdr); } action_encap_data->conf.size = header - action_encap_data->data; @@ -5337,11 +5337,11 @@ header = action_decap_data->data; if (l2_decap_conf.select_vlan) eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); - memcpy(header, ð, sizeof(eth)); - header += sizeof(eth); + memcpy(header, ð, sizeof(struct rte_ether_hdr)); + header += sizeof(struct rte_ether_hdr); if (l2_decap_conf.select_vlan) { - memcpy(header, &vlan, sizeof(vlan)); - header += sizeof(vlan); + memcpy(header, &vlan, sizeof(struct rte_vlan_hdr)); + header += sizeof(struct rte_vlan_hdr); } action_decap_data->conf.size = header - action_decap_data->data; @@ -5421,15 +5421,15 @@ mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); memcpy(eth.src.addr_bytes, mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð, sizeof(eth)); - header += sizeof(eth); + memcpy(header, ð, sizeof(struct rte_ether_hdr)); + header += sizeof(struct rte_ether_hdr); if (mplsogre_encap_conf.select_vlan) { if (mplsogre_encap_conf.select_ipv4) vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); else vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan, sizeof(vlan)); - header += sizeof(vlan); + memcpy(header, &vlan, sizeof(struct rte_vlan_hdr)); + header += sizeof(struct rte_vlan_hdr); } if (mplsogre_encap_conf.select_ipv4) { memcpy(header, &ipv4, sizeof(ipv4)); @@ -5516,15 +5516,15 @@ mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); memcpy(eth.src.addr_bytes, mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð, sizeof(eth)); - header += sizeof(eth); + memcpy(header, ð, sizeof(struct rte_ether_hdr)); + header += sizeof(struct rte_ether_hdr); if (mplsogre_encap_conf.select_vlan) { if (mplsogre_encap_conf.select_ipv4) vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); else vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan, sizeof(vlan)); - header += sizeof(vlan); + memcpy(header, &vlan, sizeof(struct rte_vlan_hdr)); + header += sizeof(struct rte_vlan_hdr); } if (mplsogre_encap_conf.select_ipv4) { memcpy(header, &ipv4, sizeof(ipv4)); @@ -5615,15 +5615,15 @@ mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); memcpy(eth.src.addr_bytes, mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð, sizeof(eth)); - header += sizeof(eth); + memcpy(header, ð, sizeof(struct rte_ether_hdr)); + header += sizeof(struct rte_ether_hdr); if (mplsoudp_encap_conf.select_vlan) { if (mplsoudp_encap_conf.select_ipv4) vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); else vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan, sizeof(vlan)); - header += sizeof(vlan); + memcpy(header, &vlan, sizeof(struct rte_vlan_hdr)); + header += sizeof(struct rte_vlan_hdr); } if (mplsoudp_encap_conf.select_ipv4) { memcpy(header, &ipv4, sizeof(ipv4)); @@ -5712,15 +5712,15 @@ mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); memcpy(eth.src.addr_bytes, mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); - memcpy(header, ð, sizeof(eth)); - header += sizeof(eth); + memcpy(header, ð, sizeof(struct rte_ether_hdr)); + header += sizeof(struct rte_ether_hdr); if (mplsoudp_encap_conf.select_vlan) { if (mplsoudp_encap_conf.select_ipv4) vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); else vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); - memcpy(header, &vlan, sizeof(vlan)); - header += sizeof(vlan); + memcpy(header, &vlan, sizeof(struct rte_vlan_hdr)); + header += sizeof(struct rte_vlan_hdr); } if (mplsoudp_encap_conf.select_ipv4) { memcpy(header, &ipv4, sizeof(ipv4)); diff -Nru dpdk-20.11.7/app/test-pmd/csumonly.c dpdk-20.11.8/app/test-pmd/csumonly.c --- dpdk-20.11.7/app/test-pmd/csumonly.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/csumonly.c 2023-04-27 17:57:22.000000000 +0000 @@ -1133,9 +1133,12 @@ nb_prep = rte_eth_tx_prepare(fs->tx_port, fs->tx_queue, tx_pkts_burst, nb_rx); - if (nb_prep != nb_rx) + if (nb_prep != nb_rx) { printf("Preparing packet burst to transmit failed: %s\n", rte_strerror(rte_errno)); + fs->fwd_dropped += (nb_rx - nb_prep); + rte_pktmbuf_free_bulk(&tx_pkts_burst[nb_prep], nb_rx - nb_prep); + } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, tx_pkts_burst, nb_prep); @@ -1143,12 +1146,12 @@ /* * Retry if necessary */ - if (unlikely(nb_tx < nb_rx) && fs->retry_enabled) { + if (unlikely(nb_tx < nb_prep) && fs->retry_enabled) { retry = 0; - while (nb_tx < nb_rx && retry++ < burst_tx_retry_num) { + while (nb_tx < nb_prep && retry++ < burst_tx_retry_num) { rte_delay_us(burst_tx_delay_time); nb_tx += rte_eth_tx_burst(fs->tx_port, fs->tx_queue, - &tx_pkts_burst[nb_tx], nb_rx - nb_tx); + &tx_pkts_burst[nb_tx], nb_prep - nb_tx); } } fs->tx_packets += nb_tx; @@ -1157,11 +1160,11 @@ fs->rx_bad_outer_l4_csum += rx_bad_outer_l4_csum; inc_tx_burst_stats(fs, nb_tx); - if (unlikely(nb_tx < nb_rx)) { - fs->fwd_dropped += (nb_rx - nb_tx); + if (unlikely(nb_tx < nb_prep)) { + fs->fwd_dropped += (nb_prep - nb_tx); do { rte_pktmbuf_free(tx_pkts_burst[nb_tx]); - } while (++nb_tx < nb_rx); + } while (++nb_tx < nb_prep); } get_end_cycles(fs, start_tsc); diff -Nru dpdk-20.11.7/app/test-pmd/ieee1588fwd.c dpdk-20.11.8/app/test-pmd/ieee1588fwd.c --- dpdk-20.11.7/app/test-pmd/ieee1588fwd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/ieee1588fwd.c 2023-04-27 17:57:22.000000000 +0000 @@ -184,13 +184,13 @@ /* Forward PTP packet with hardware TX timestamp */ mb->ol_flags |= PKT_TX_IEEE1588_TMST; - fs->tx_packets += 1; if (rte_eth_tx_burst(fs->rx_port, fs->tx_queue, &mb, 1) == 0) { printf("Port %u sent PTP packet dropped\n", fs->rx_port); fs->fwd_dropped += 1; rte_pktmbuf_free(mb); return; } + fs->tx_packets += 1; /* * Check the TX timestamp. diff -Nru dpdk-20.11.7/app/test-pmd/noisy_vnf.c dpdk-20.11.8/app/test-pmd/noisy_vnf.c --- dpdk-20.11.7/app/test-pmd/noisy_vnf.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/noisy_vnf.c 2023-04-27 17:57:22.000000000 +0000 @@ -213,9 +213,10 @@ sent = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, tmp_pkts, nb_deqd); if (unlikely(sent < nb_deqd) && fs->retry_enabled) - nb_tx += do_retry(nb_rx, nb_tx, tmp_pkts, fs); - inc_tx_burst_stats(fs, nb_tx); + sent += do_retry(nb_deqd, sent, tmp_pkts, fs); + inc_tx_burst_stats(fs, sent); fs->fwd_dropped += drop_pkts(tmp_pkts, nb_deqd, sent); + nb_tx += sent; ncf->prev_time = rte_get_timer_cycles(); } } diff -Nru dpdk-20.11.7/app/test-pmd/testpmd.c dpdk-20.11.8/app/test-pmd/testpmd.c --- dpdk-20.11.7/app/test-pmd/testpmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/testpmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -216,7 +217,7 @@ * In container, it cannot terminate the process which running with 'stats-period' * option. Set flag to exit stats period loop after received SIGINT/SIGTERM. */ -static volatile uint8_t f_quit; +volatile uint8_t f_quit; uint8_t cl_quit; /* Quit testpmd from cmdline. */ /* @@ -1845,6 +1846,8 @@ fwd_cycles += fs->core_cycles; } for (i = 0; i < cur_fwd_config.nb_fwd_ports; i++) { + uint64_t tx_dropped = 0; + pt_id = fwd_ports_ids[i]; port = &ports[pt_id]; @@ -1866,8 +1869,9 @@ total_recv += stats.ipackets; total_xmit += stats.opackets; total_rx_dropped += stats.imissed; - total_tx_dropped += ports_stats[pt_id].tx_dropped; - total_tx_dropped += stats.oerrors; + tx_dropped += ports_stats[pt_id].tx_dropped; + tx_dropped += stats.oerrors; + total_tx_dropped += tx_dropped; total_rx_nombuf += stats.rx_nombuf; printf("\n %s Forward statistics for port %-2d %s\n", @@ -1891,8 +1895,8 @@ printf(" TX-packets: %-14"PRIu64" TX-dropped: %-14"PRIu64 "TX-total: %-"PRIu64"\n", - stats.opackets, ports_stats[pt_id].tx_dropped, - stats.opackets + ports_stats[pt_id].tx_dropped); + stats.opackets, tx_dropped, + stats.opackets + tx_dropped); if (record_burst_stats) { if (ports_stats[pt_id].rx_stream) @@ -3824,13 +3828,6 @@ } static void -force_quit(void) -{ - pmd_test_exit(); - prompt_exit(); -} - -static void print_stats(void) { uint8_t i; @@ -3848,26 +3845,10 @@ } static void -signal_handler(int signum) +signal_handler(int signum __rte_unused) { - if (signum == SIGINT || signum == SIGTERM) { - printf("\nSignal %d received, preparing to exit...\n", - signum); -#ifdef RTE_LIB_PDUMP - /* uninitialize packet capture framework */ - rte_pdump_uninit(); -#endif -#ifdef RTE_LIB_LATENCYSTATS - if (latencystats_enabled != 0) - rte_latencystats_uninit(); -#endif - force_quit(); - /* Set flag to indicate the force termination. */ - f_quit = 1; - /* exit with the expected status */ - signal(signum, SIG_DFL); - kill(getpid(), signum); - } + f_quit = 1; + prompt_exit(); } int @@ -3878,8 +3859,18 @@ uint16_t count; int ret; +#ifdef RTE_EXEC_ENV_WINDOWS signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); +#else + /* Want read() not to be restarted on signal */ + struct sigaction action = { + .sa_handler = signal_handler, + }; + + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +#endif testpmd_logtype = rte_log_register("testpmd"); if (testpmd_logtype < 0) @@ -3895,6 +3886,9 @@ rte_exit(EXIT_FAILURE, "Secondary process type not supported.\n"); + /* allocate port structures, and init them */ + init_port(); + ret = register_eth_event_callback(); if (ret != 0) rte_exit(EXIT_FAILURE, "Cannot register for ethdev events"); @@ -3913,9 +3907,6 @@ if (nb_ports == 0) TESTPMD_LOG(WARNING, "No probed ethernet devices\n"); - /* allocate port structures, and init them */ - init_port(); - set_def_fwd_config(); if (nb_lcores == 0) rte_exit(EXIT_FAILURE, "No cores defined for forwarding\n" @@ -3990,8 +3981,13 @@ } } - if (!no_device_start && start_port(RTE_PORT_ALL) != 0) - rte_exit(EXIT_FAILURE, "Start ports failed\n"); + if (!no_device_start && start_port(RTE_PORT_ALL) != 0) { + if (!interactive) { + rte_eal_cleanup(); + rte_exit(EXIT_FAILURE, "Start ports failed\n"); + } + fprintf(stderr, "Start ports failed\n"); + } /* set all ports to promiscuous mode by default */ RTE_ETH_FOREACH_DEV(port_id) { @@ -4036,15 +4032,9 @@ start_packet_forwarding(0); } prompt(); - pmd_test_exit(); } else #endif { - char c; - int rc; - - f_quit = 0; - printf("No commandline core given, start packet forwarding\n"); start_packet_forwarding(tx_first); if (stats_period != 0) { @@ -4067,15 +4057,41 @@ prev_time = cur_time; sleep(1); } - } + } else { + char c; + fd_set fds; + + printf("Press enter to exit\n"); - printf("Press enter to exit\n"); - rc = read(0, &c, 1); - pmd_test_exit(); - if (rc < 0) - return 1; + FD_ZERO(&fds); + FD_SET(0, &fds); + + /* wait for signal or enter */ + ret = select(1, &fds, NULL, NULL, NULL); + if (ret < 0 && errno != EINTR) + rte_exit(EXIT_FAILURE, + "Select failed: %s\n", + strerror(errno)); + + /* if got enter then consume it */ + if (ret == 1 && read(0, &c, 1) < 0) + rte_exit(EXIT_FAILURE, + "Read failed: %s\n", + strerror(errno)); + } } + pmd_test_exit(); + +#ifdef RTE_LIB_PDUMP + /* uninitialize packet capture framework */ + rte_pdump_uninit(); +#endif +#ifdef RTE_LIB_LATENCYSTATS + if (latencystats_enabled != 0) + rte_latencystats_uninit(); +#endif + ret = rte_eal_cleanup(); if (ret != 0) rte_exit(EXIT_FAILURE, diff -Nru dpdk-20.11.7/app/test-pmd/testpmd.h dpdk-20.11.8/app/test-pmd/testpmd.h --- dpdk-20.11.7/app/test-pmd/testpmd.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/app/test-pmd/testpmd.h 2023-04-27 17:57:22.000000000 +0000 @@ -25,6 +25,7 @@ #define RTE_PORT_HANDLING (uint16_t)3 extern uint8_t cl_quit; +extern volatile uint8_t f_quit; /* * It is used to allocate the memory for hash key. diff -Nru dpdk-20.11.7/config/meson.build dpdk-20.11.8/config/meson.build --- dpdk-20.11.7/config/meson.build 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/config/meson.build 2023-04-27 17:57:22.000000000 +0000 @@ -107,7 +107,7 @@ toolchain = cc.get_id() dpdk_conf.set_quoted('RTE_TOOLCHAIN', toolchain) -dpdk_conf.set('RTE_TOOLCHAIN_' + toolchain.to_upper(), 1) +dpdk_conf.set('RTE_TOOLCHAIN_' + toolchain.to_upper().underscorify(), 1) dpdk_conf.set('RTE_ARCH_64', cc.sizeof('void *') == 8) dpdk_conf.set('RTE_ARCH_32', cc.sizeof('void *') == 4) @@ -152,7 +152,7 @@ endif has_libfdt = 0 -fdt_dep = cc.find_library('libfdt', required: false) +fdt_dep = cc.find_library('fdt', required: false) if fdt_dep.found() and cc.has_header('fdt.h') dpdk_conf.set10('RTE_HAS_LIBFDT', true) has_libfdt = 1 @@ -160,7 +160,7 @@ dpdk_extra_ldflags += '-lfdt' endif -libexecinfo = cc.find_library('libexecinfo', required: false) +libexecinfo = cc.find_library('execinfo', required: false) if libexecinfo.found() and cc.has_header('execinfo.h') add_project_link_arguments('-lexecinfo', language: 'c') dpdk_extra_ldflags += '-lexecinfo' diff -Nru dpdk-20.11.7/debian/changelog dpdk-20.11.8/debian/changelog --- dpdk-20.11.7/debian/changelog 2022-12-14 00:32:18.000000000 +0000 +++ dpdk-20.11.8/debian/changelog 2023-04-28 11:27:52.000000000 +0000 @@ -1,3 +1,10 @@ +dpdk (20.11.8-1~deb11u1) bullseye; urgency=medium + + * New upstream release 20.11.8; for a full list of changes see: + http://doc.dpdk.org/guides-20.11/rel_notes/release_20_11.html + + -- Luca Boccassi Fri, 28 Apr 2023 12:27:52 +0100 + dpdk (20.11.7-1~deb11u1) bullseye; urgency=medium * New upstream release 20.11.7; for a full list of changes see: diff -Nru dpdk-20.11.7/devtools/check-git-log.sh dpdk-20.11.8/devtools/check-git-log.sh --- dpdk-20.11.7/devtools/check-git-log.sh 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/devtools/check-git-log.sh 2023-04-27 17:57:22.000000000 +0000 @@ -113,7 +113,7 @@ for word in $(cat $words); do bad=$(echo "$headlines" | grep -iw $word | grep -vw $word) if [ "$word" = "Tx" ]; then - bad=$(echo $bad | grep -v 'OCTEON\ TX') + bad=$(echo $bad | grep -v 'OCTEON TX') fi for bad_line in $bad; do bad_word=$(echo $bad_line | cut -d":" -f2 | grep -iwo $word) diff -Nru dpdk-20.11.7/doc/guides/linux_gsg/enable_func.rst dpdk-20.11.8/doc/guides/linux_gsg/enable_func.rst --- dpdk-20.11.7/doc/guides/linux_gsg/enable_func.rst 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/doc/guides/linux_gsg/enable_func.rst 2023-04-27 17:57:22.000000000 +0000 @@ -106,12 +106,12 @@ If the driver requires using physical addresses (PA), the executable file must be granted additional capabilities: -* ``SYS_ADMIN`` to read ``/proc/self/pagemaps`` +* ``DAC_READ_SEARCH`` and ``SYS_ADMIN`` to read ``/proc/self/pagemaps`` * ``IPC_LOCK`` to lock hugepages in memory .. code-block:: console - setcap cap_ipc_lock,cap_sys_admin+ep + setcap cap_dac_read_search,cap_ipc_lock,cap_sys_admin+ep If physical addresses are not accessible, the following message will appear during EAL initialization:: diff -Nru dpdk-20.11.7/doc/guides/prog_guide/cryptodev_lib.rst dpdk-20.11.8/doc/guides/prog_guide/cryptodev_lib.rst --- dpdk-20.11.7/doc/guides/prog_guide/cryptodev_lib.rst 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/doc/guides/prog_guide/cryptodev_lib.rst 2023-04-27 17:57:22.000000000 +0000 @@ -98,14 +98,10 @@ The ``rte_cryptodev_config`` structure is used to pass the configuration parameters for socket selection and number of queue pairs. -.. code-block:: c - - struct rte_cryptodev_config { - int socket_id; - /**< Socket to allocate resources on */ - uint16_t nb_queue_pairs; - /**< Number of queue pairs to configure on device */ - }; +.. literalinclude:: ../../../lib/librte_cryptodev/rte_cryptodev.h + :language: c + :start-after: Structure rte_cryptodev_config 8< + :end-before: >8 End of structure rte_cryptodev_config. Configuration of Queue Pairs @@ -121,13 +117,11 @@ const struct rte_cryptodev_qp_conf *qp_conf, int socket_id) - struct rte_cryptodev_qp_conf { - uint32_t nb_descriptors; /**< Number of descriptors per queue pair */ - struct rte_mempool *mp_session; - /**< The mempool for creating session in sessionless mode */ - struct rte_mempool *mp_session_private; - /**< The mempool for creating sess private data in sessionless mode */ - }; + +.. literalinclude:: ../../../lib/librte_cryptodev/rte_cryptodev.h + :language: c + :start-after: Structure rte_cryptodev_qp_conf 8< + :end-before: >8 End of structure rte_cryptodev_qp_conf. The fields ``mp_session`` and ``mp_session_private`` are used for creating @@ -273,23 +267,10 @@ features and capabilities. The ``rte_cryptodev_info`` structure contains all the relevant information for the device. -.. code-block:: c - - struct rte_cryptodev_info { - const char *driver_name; - uint8_t driver_id; - struct rte_device *device; - - uint64_t feature_flags; - - const struct rte_cryptodev_capabilities *capabilities; - - unsigned max_nb_queue_pairs; - - struct { - unsigned max_nb_sessions; - } sym; - }; +.. literalinclude:: ../../../lib/librte_cryptodev/rte_cryptodev.h + :language: c + :start-after: Structure rte_cryptodev_info 8< + :end-before: >8 End of structure rte_cryptodev_info. Operation Processing @@ -506,22 +487,10 @@ Also it is important to note that the order in which the transforms are passed indicates the order of the chaining. -.. code-block:: c - - struct rte_crypto_sym_xform { - struct rte_crypto_sym_xform *next; - /**< next xform in chain */ - enum rte_crypto_sym_xform_type type; - /**< xform type */ - union { - struct rte_crypto_auth_xform auth; - /**< Authentication / hash xform */ - struct rte_crypto_cipher_xform cipher; - /**< Cipher xform */ - struct rte_crypto_aead_xform aead; - /**< AEAD xform */ - }; - }; +.. literalinclude:: ../../../lib/librte_cryptodev/rte_crypto_sym.h + :language: c + :start-after: Structure rte_crypto_sym_xform 8< + :end-before: >8 End of structure rte_crypto_sym_xform. The API does not place a limit on the number of transforms that can be chained together but this will be limited by the underlying Crypto device poll mode @@ -544,61 +513,11 @@ specified in the session or the transform chain. -.. code-block:: c +.. literalinclude:: ../../../lib/librte_cryptodev/rte_crypto_sym.h + :language: c + :start-after: Structure rte_crypto_sym_op 8< + :end-before: >8 End of structure rte_crypto_sym_op. - struct rte_crypto_sym_op { - struct rte_mbuf *m_src; - struct rte_mbuf *m_dst; - - union { - struct rte_cryptodev_sym_session *session; - /**< Handle for the initialised session context */ - struct rte_crypto_sym_xform *xform; - /**< Session-less API Crypto operation parameters */ - }; - - union { - struct { - struct { - uint32_t offset; - uint32_t length; - } data; /**< Data offsets and length for AEAD */ - - struct { - uint8_t *data; - rte_iova_t phys_addr; - } digest; /**< Digest parameters */ - - struct { - uint8_t *data; - rte_iova_t phys_addr; - } aad; - /**< Additional authentication parameters */ - } aead; - - struct { - struct { - struct { - uint32_t offset; - uint32_t length; - } data; /**< Data offsets and length for ciphering */ - } cipher; - - struct { - struct { - uint32_t offset; - uint32_t length; - } data; - /**< Data offsets and length for authentication */ - - struct { - uint8_t *data; - rte_iova_t phys_addr; - } digest; /**< Digest parameters */ - } auth; - }; - }; - }; Synchronous mode ---------------- diff -Nru dpdk-20.11.7/doc/guides/prog_guide/event_timer_adapter.rst dpdk-20.11.8/doc/guides/prog_guide/event_timer_adapter.rst --- dpdk-20.11.7/doc/guides/prog_guide/event_timer_adapter.rst 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/doc/guides/prog_guide/event_timer_adapter.rst 2023-04-27 17:57:22.000000000 +0000 @@ -35,7 +35,7 @@ The Event Timer Adapter API represents each event timer with a generic struct, which contains an event and user metadata. The ``rte_event_timer`` struct is -defined in ``lib/librte_event/librte_event_timer_adapter.h``. +defined in ``rte_event_timer_adapter.h``. .. _timer_expiry_event: diff -Nru dpdk-20.11.7/doc/guides/rel_notes/release_20_11.rst dpdk-20.11.8/doc/guides/rel_notes/release_20_11.rst --- dpdk-20.11.7/doc/guides/rel_notes/release_20_11.rst 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/doc/guides/rel_notes/release_20_11.rst 2023-04-27 17:57:22.000000000 +0000 @@ -3886,3 +3886,272 @@ * net/iavf * vf_interrupt_pmd/nic_interrupt_VF_vfio_pci: l3fwd-power Wake up failed on X722 37d0 + +20.11.8 Release Notes +--------------------- + + +20.11.8 Fixes +~~~~~~~~~~~~~ + +* acl: fix crash on PPC64 with GCC 11 +* app/bbdev: add allocation checks +* app/bbdev: check statistics failure +* app/compress-perf: fix remaining data for ops +* app/compress-perf: fix some typos +* app/compress-perf: fix testing single operation +* app/crypto-perf: fix number of segments +* app/crypto-perf: fix test file memory leak +* app/flow-perf: fix division or module by zero +* app/testpmd: cleanup cleanly from signal +* app/testpmd: fix crash on cleanup +* app/testpmd: fix encap/decap size calculation +* app/testpmd: fix forwarding stats for Tx dropped +* app/testpmd: fix interactive mode on Windows +* app/testpmd: fix interactive mode with no ports +* app/testpmd: fix packet count in IEEE 1588 engine +* app/testpmd: fix packet transmission in noisy VNF engine +* app/testpmd: fix Tx preparation in checksum engine +* baseband/acc: fix acc100 iteration counter in TB +* baseband/acc: fix memory leak on acc100 close +* build: fix dependencies lookup +* build: fix toolchain definition +* bus/ifpga: fix devargs handling +* ci: switch to Ubuntu 20.04 +* cmdline: handle EOF as quit +* common/mlx5: use just sufficient barrier for Arm +* compressdev: fix empty devargs parsing +* compressdev: fix end of driver list +* crypto/ccp: remove some printf +* cryptodev: fix empty devargs parsing +* crypto/qat: fix stream cipher direction +* crypto/snow3g: fix snow3g enqueue stat increment +* devtools: fix escaped space in grep pattern +* doc: add Linux capability to access physical addresses +* doc: fix code blocks in cryptodev guide +* doc: fix dependency setup in l2fwd-cat example guide +* doc: fix pipeline example path in user guide +* doc: fix reference to event timer header +* eal/freebsd: fix lock in alarm callback +* eal: use same atomic intrinsics for GCC and clang +* eal/windows: fix pedantic build +* eal/windows: mark memory config as complete +* eventdev/eth_tx: fix devices loop +* eventdev/timer: fix overflow +* examples/cmdline: fix build with GCC 12 +* examples/qos_sched: fix config entries in wrong sections +* examples/qos_sched: fix debug mode +* examples/qos_sched: fix Tx port config when link down +* examples/vm_power_manager: revert backported commit +* fbarray: fix metadata dump +* graph: fix node shrink +* kni: fix build on RHEL 9.1 +* kni: fix possible starvation when mbufs are exhausted +* kvargs: add API documentation for process callback +* lib: remove empty return types from doxygen comments +* mem: fix hugepage info mapping +* mempool: fix get objects from mempool with cache +* net/bnxt: fix link state change interrupt config +* net/bnxt: fix RSS hash in mbuf +* net/bnxt: fix Rx queue stats after queue stop and start +* net/bnxt: fix Tx queue stats after queue stop and start +* net/e1000: fix saving of stripped VLAN TCI +* net/hns3: add verification of RSS types +* net/hns3: allow adding queue buffer size hash rule +* net/hns3: extract common functions to set Rx/Tx +* net/hns3: fix burst mode query with dummy function +* net/hns3: fix clearing RSS configuration +* net/hns3: fix config struct used for conversion +* net/hns3: fix duplicate RSS rule check +* net/hns3: fix log about indirection table size +* net/hns3: fix possible truncation of hash key when config +* net/hns3: fix possible truncation of redirection table +* net/hns3: fix RSS key size compatibility +* net/hns3: fix warning on flush or destroy rule +* net/hns3: refactor set RSS hash algorithm and key interface +* net/hns3: reimplement hash flow function +* net/hns3: remove useless code when destroy valid RSS rule +* net/hns3: save hash algo to RSS filter list node +* net/hns3: separate flow RSS config from RSS conf +* net/hns3: separate setting and clearing RSS rule +* net/hns3: separate setting hash algorithm +* net/hns3: separate setting hash key +* net/hns3: separate setting redirection table +* net/hns3: separate setting RSS types +* net/hns3: use hardware config to report hash key +* net/hns3: use hardware config to report hash types +* net/hns3: use hardware config to report redirection table +* net/hns3: use new RSS rule to configure hardware +* net/hns3: use RSS filter list to check duplicated rule +* net/i40e: fix MAC loopback on X722 +* net/i40e: fix validation of flow transfer attribute +* net/i40e: reduce interrupt interval in multi-driver mode +* net/i40e: revert link status check on device start +* net/iavf: add lock for VF commands +* net/iavf: fix device stop during reset +* net/iavf: protect insertion in flow list +* net/ice: fix validation of flow transfer attribute +* net/ipn3ke: fix representor name +* net/ipn3ke: fix thread exit +* net/ixgbe: enable IPv6 mask in flow rules +* net/ixgbe: fix firmware version consistency +* net/ixgbe: fix IPv6 mask in flow director +* net/mlx5: check compressed CQE opcode in vectorized Rx +* net/mlx5: fix build with GCC 12 and ASan +* net/mlx5: fix CQE dump for Tx +* net/mlx5: fix error CQE dumping for vectorized Rx +* net/mlx5: fix flow sample with ConnectX-5 +* net/mlx5: fix hairpin Tx queue reference count +* net/mlx5: fix sysfs port name translation +* net/mlx5: ignore non-critical syndromes for Rx queue +* net/nfp: fix firmware name derived from PCI name +* net/nfp: fix getting RSS configuration +* net/nfp: fix MTU configuration order +* net/sfc: enforce fate action in transfer flow rules +* net/txgbe: fix default signal quality value for KX/KX4 +* net/txgbe: fix interrupt loss +* net/txgbe: fix packet type to parse from offload flags +* net/txgbe: fix Rx buffer size in config register +* net/vhost: add missing newline in logs +* net/vhost: fix Rx interrupt +* net/virtio: deduce IP length for TSO checksum +* net/virtio: fix empty devargs parsing +* net/virtio: remove address width limit for modern devices +* net/virtio-user: fix device starting failure handling +* pdump: fix build with GCC 12 +* raw/ifpga/base: fix init with multi-process +* raw/skeleton: fix empty devargs parsing +* raw/skeleton: fix selftest +* reorder: fix sequence number mbuf field register +* reorder: invalidate buffer from ready queue in drain +* ring: silence GCC 12 warnings +* telemetry: fix repeat display when callback don't init dict +* test/bbdev: extend HARQ tolerance +* test/bbdev: fix crash for non supported HARQ length +* test/bbdev: remove check for invalid opaque data +* test/crypto: add missing MAC-I to PDCP vectors +* test/crypto: fix statistics error messages +* test: fix segment length in packet generator +* test/mbuf: fix mbuf reset test +* test/mbuf: fix test with mbuf debug enabled +* test/reorder: fix double free of drained buffers +* vdpa/ifc: fix argument compatibility check +* vdpa/ifc: fix reconnection in SW-assisted live migration +* version: 20.11.8-rc1 +* vhost: decrease log level for unimplemented requests +* vhost: fix doxygen warnings +* vhost: fix net header settings in datapath +* vhost: fix OOB access for invalid vhost ID +* vhost: fix possible FD leaks +* vhost: fix possible FD leaks on truncation + +20.11.8 Validation +~~~~~~~~~~~~~~~~~~ + +* Intel(R) Testing + + * Basic Intel(R) NIC testing + * Build & CFLAG compile: cover the build test combination with latest GCC/Clang version and the popular OS revision such as Ubuntu20.04, Fedora36, RHEL8.4, etc. + * PF(i40e, ixgbe): test scenarios including RTE_FLOW/TSO/Jumboframe/checksum offload/VLAN/VXLAN, etc. + * VF(i40e, ixgbe): test scenarios including VF-RTE_FLOW/TSO/Jumboframe/checksum offload/VLAN/VXLAN, etc. + * PF/VF(ice): test scenarios including Switch features/Package Management/Flow Director/Advanced Tx/Advanced RSS/ACL/DCF/Flexible Descriptor, etc. + * Intel NIC single core/NIC performance: test scenarios including PF/VF single core performance test, etc. + * IPsec: test scenarios including ipsec/ipsec-gw/ipsec library basic test - QAT&SW/FIB library, etc. + + * Basic cryptodev and virtio testing + * Virtio: both function and performance test are covered. Such as PVP/Virtio_loopback/virtio-user loopback/virtio-net VM2VM perf testing/VMAWARE ESXI 8.0, etc. + * Cryptodev: + * Function test: test scenarios including Cryptodev API testing/CompressDev ISA-L/QAT/ZLIB PMD Testing/FIPS, etc. + * Performance test: test scenarios including Thoughput Performance/Cryptodev Latency, etc. + + +* Nvidia(R) Testing + + * Basic functionality via testpmd/example applications + + * Tx/Rx + * xstats + * Timestamps + * Link status + * RTE flow and flow_director + * RSS + * VLAN filtering, stripping and insertion + * Checksum/TSO + * ptype + * link_status_interrupt example application + * l3fwd-power example application + * Multi-process example applications + * Hardware LRO tests + + * Build tests + + * Ubuntu 20.04.5 with MLNX_OFED_LINUX-5.9-0.5.6.0. + * Ubuntu 20.04.5 with rdma-core master (f0a079f). + * Ubuntu 20.04.5 with rdma-core v28.0. + * Ubuntu 18.04.6 with rdma-core v17.1. + * Ubuntu 18.04.6 with rdma-core master (f0a079f) (i386). + * Fedora 37 with rdma-core v41.0. + * Fedora 39 (Rawhide) with rdma-core v44.0. + * CentOS 7 7.9.2009 with rdma-core master (f0a079f). + * CentOS 7 7.9.2009 with MLNX_OFED_LINUX-5.9-0.5.6.0. + * CentOS 8 8.4.2105 with rdma-core master (f0a079f). + * OpenSUSE Leap 15.4 with rdma-core v38.1. + * Windows Server 2019 with Clang 11.0.0. + + * BlueField-2 + + * DOCA 1.5.1 + * fw 24.35.2000 + + * ConnectX-7 + + * Ubuntu 20.04 + * Driver MLNX_OFED_LINUX-5.9-0.5.6.0 + * fw 22.36.1010 + + * ConnectX-6 Dx + + * Ubuntu 20.04 + * Driver MLNX_OFED_LINUX-5.9-0.5.6.0 + * fw 22.36.1010 + + +* Red Hat(R) Testing + + * Platform + + * RHEL 8 + * Kernel 5.14 + * Qemu 6.2.0 + * X540-AT2 NIC(ixgbe, 10G) + + * Functionality + + * Guest with device assignment(PF) throughput testing(1G hugepage size) + * Guest with device assignment(PF) throughput testing(2M hugepage size) + * Guest with device assignment(VF) throughput testing + * PVP (host dpdk testpmd as vswitch) 1Q: throughput testing + * PVP vhost-user 2Q throughput testing + * PVP vhost-user 1Q cross numa node throughput testing + * Guest with vhost-user 2 queues throughput testing + * vhost-user reconnect with dpdk-client, qemu-server: qemu reconnect + * vhost-user reconnect with dpdk-client, qemu-server: ovs reconnect + * PVP reconnect with dpdk-client, qemu-server: PASS + * PVP 1Q live migration testing + * PVP 1Q cross numa node live migration testing + * Guest with ovs+dpdk+vhost-user 1Q live migration testing + * Guest with ovs+dpdk+vhost-user 1Q live migration testing (2M) + * Guest with ovs+dpdk+vhost-user 2Q live migration testing + * Guest with ovs+dpdk+vhost-user 4Q live migration testing + * Host PF + DPDK testing + * Host VF + DPDK testing + +20.11.8 Known Issues +~~~~~~~~~~~~~~~~~~~~ + +* softnic + + * metering/policing: creating a rule can sometimes fail + +* testpmd + * a "OP_DEL_RSS_INPUT_CFG" error can sometimes appear when exiting diff -Nru dpdk-20.11.7/doc/guides/sample_app_ug/l2_forward_cat.rst dpdk-20.11.8/doc/guides/sample_app_ug/l2_forward_cat.rst --- dpdk-20.11.7/doc/guides/sample_app_ug/l2_forward_cat.rst 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/doc/guides/sample_app_ug/l2_forward_cat.rst 2023-04-27 17:57:22.000000000 +0000 @@ -50,13 +50,12 @@ * https://github.com/01org/intel-cmt-cat -#. To compile the application export the path to PQoS lib - and the DPDK source tree and go to the example directory: +To compile the application, export the path to PQoS lib: - .. code-block:: console - - export PQOS_INSTALL_PATH=/path/to/libpqos +.. code-block:: console + export CFLAGS=-I/path/to/intel-cmt-cat/include + export LDFLAGS=-L/path/to/intel-cmt-cat/lib To compile the sample application see :doc:`compiling`. diff -Nru dpdk-20.11.7/doc/guides/sample_app_ug/pipeline.rst dpdk-20.11.8/doc/guides/sample_app_ug/pipeline.rst --- dpdk-20.11.7/doc/guides/sample_app_ug/pipeline.rst 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/doc/guides/sample_app_ug/pipeline.rst 2023-04-27 17:57:22.000000000 +0000 @@ -58,7 +58,7 @@ .. code-block:: console - $ .//examples/dpdk-pipeline -c 0x3 -- -s examples/vxlan.cli + $ .//examples/dpdk-pipeline -c 0x3 -- -s examples/pipeline/examples/vxlan.cli The application should start successfully and display as follows: diff -Nru dpdk-20.11.7/drivers/baseband/acc100/rte_acc100_pmd.c dpdk-20.11.8/drivers/baseband/acc100/rte_acc100_pmd.c --- dpdk-20.11.7/drivers/baseband/acc100/rte_acc100_pmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/baseband/acc100/rte_acc100_pmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -778,6 +778,7 @@ rte_free(d->tail_ptrs); rte_free(d->info_ring); rte_free(d->sw_rings_base); + rte_free(d->harq_layout); d->sw_rings_base = NULL; d->tail_ptrs = NULL; d->info_ring = NULL; @@ -3967,8 +3968,12 @@ /* CRC invalid if error exists */ if (!op->status) op->status |= rsp.crc_status << RTE_BBDEV_CRC_ERROR; - op->turbo_dec.iter_count = RTE_MAX((uint8_t) rsp.iter_cnt, - op->turbo_dec.iter_count); + if (q->op_type == RTE_BBDEV_OP_LDPC_DEC) + op->ldpc_dec.iter_count = RTE_MAX((uint8_t) rsp.iter_cnt, + op->ldpc_dec.iter_count); + else + op->turbo_dec.iter_count = RTE_MAX((uint8_t) rsp.iter_cnt, + op->turbo_dec.iter_count); /* Check if this is the last desc in batch (Atomic Queue) */ if (desc->req.last_desc_in_batch) { diff -Nru dpdk-20.11.7/drivers/baseband/turbo_sw/meson.build dpdk-20.11.8/drivers/baseband/turbo_sw/meson.build --- dpdk-20.11.7/drivers/baseband/turbo_sw/meson.build 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/baseband/turbo_sw/meson.build 2023-04-27 17:57:22.000000000 +0000 @@ -6,15 +6,15 @@ # check for FlexRAN SDK libraries for AVX2 lib4g = cc.find_library('libturbo', dirs: [path + '/lib_turbo'], required: false) if lib4g.found() - ext_deps += cc.find_library('libturbo', dirs: [path + '/lib_turbo'], required: true) - ext_deps += cc.find_library('libcrc', dirs: [path + '/lib_crc'], required: true) - ext_deps += cc.find_library('librate_matching', dirs: [path + '/lib_rate_matching'], required: true) - ext_deps += cc.find_library('libcommon', dirs: [path + '/lib_common'], required: true) - ext_deps += cc.find_library('libstdc++', required: true) - ext_deps += cc.find_library('libirc', required: true) - ext_deps += cc.find_library('libimf', required: true) - ext_deps += cc.find_library('libipps', required: true) - ext_deps += cc.find_library('libsvml', required: true) + ext_deps += cc.find_library('turbo', dirs: [path + '/lib_turbo'], required: true) + ext_deps += cc.find_library('crc', dirs: [path + '/lib_crc'], required: true) + ext_deps += cc.find_library('rate_matching', dirs: [path + '/lib_rate_matching'], required: true) + ext_deps += cc.find_library('common', dirs: [path + '/lib_common'], required: true) + ext_deps += cc.find_library('stdc++', required: true) + ext_deps += cc.find_library('irc', required: true) + ext_deps += cc.find_library('imf', required: true) + ext_deps += cc.find_library('ipps', required: true) + ext_deps += cc.find_library('svml', required: true) includes += include_directories(path + '/lib_turbo') includes += include_directories(path + '/lib_crc') includes += include_directories(path + '/lib_rate_matching') @@ -25,10 +25,10 @@ # check for FlexRAN SDK libraries for AVX512 lib5g = cc.find_library('libldpc_decoder_5gnr', dirs: [path + '/lib_ldpc_decoder_5gnr'], required: false) if lib5g.found() - ext_deps += cc.find_library('libldpc_encoder_5gnr', dirs: [path + '/lib_ldpc_encoder_5gnr'], required: true) - ext_deps += cc.find_library('libldpc_decoder_5gnr', dirs: [path + '/lib_ldpc_decoder_5gnr'], required: true) - ext_deps += cc.find_library('libLDPC_ratematch_5gnr', dirs: [path + '/lib_LDPC_ratematch_5gnr'], required: true) - ext_deps += cc.find_library('librate_dematching_5gnr', dirs: [path + '/lib_rate_dematching_5gnr'], required: true) + ext_deps += cc.find_library('ldpc_encoder_5gnr', dirs: [path + '/lib_ldpc_encoder_5gnr'], required: true) + ext_deps += cc.find_library('ldpc_decoder_5gnr', dirs: [path + '/lib_ldpc_decoder_5gnr'], required: true) + ext_deps += cc.find_library('LDPC_ratematch_5gnr', dirs: [path + '/lib_LDPC_ratematch_5gnr'], required: true) + ext_deps += cc.find_library('rate_dematching_5gnr', dirs: [path + '/lib_rate_dematching_5gnr'], required: true) includes += include_directories(path + '/lib_ldpc_encoder_5gnr') includes += include_directories(path + '/lib_ldpc_decoder_5gnr') includes += include_directories(path + '/lib_LDPC_ratematch_5gnr') diff -Nru dpdk-20.11.7/drivers/bus/ifpga/ifpga_bus.c dpdk-20.11.8/drivers/bus/ifpga/ifpga_bus.c --- dpdk-20.11.7/drivers/bus/ifpga/ifpga_bus.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/bus/ifpga/ifpga_bus.c 2023-04-27 17:57:22.000000000 +0000 @@ -136,6 +136,8 @@ goto end; } afu_pr_conf.pr_enable = 1; + strlcpy(afu_pr_conf.bs_path, path, + sizeof(afu_pr_conf.bs_path)); } else { afu_pr_conf.pr_enable = 0; } @@ -167,7 +169,6 @@ rawdev->dev_ops->dev_start(rawdev)) goto end; - strlcpy(afu_pr_conf.bs_path, path, sizeof(afu_pr_conf.bs_path)); if (rawdev->dev_ops && rawdev->dev_ops->firmware_load && rawdev->dev_ops->firmware_load(rawdev, diff -Nru dpdk-20.11.7/drivers/common/mlx5/mlx5_common.h dpdk-20.11.8/drivers/common/mlx5/mlx5_common.h --- dpdk-20.11.7/drivers/common/mlx5/mlx5_common.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/common/mlx5/mlx5_common.h 2023-04-27 17:57:22.000000000 +0000 @@ -199,7 +199,12 @@ if (unlikely((op_owner != (!!(idx))) || (op_code == MLX5_CQE_INVALID))) return MLX5_CQE_STATUS_HW_OWN; - rte_io_rmb(); + + /* Prevent speculative reading of other fields in CQE until + * CQE is valid. + */ + rte_atomic_thread_fence(__ATOMIC_ACQUIRE); + if (unlikely(op_code == MLX5_CQE_RESP_ERR || op_code == MLX5_CQE_REQ_ERR)) return MLX5_CQE_STATUS_ERR; diff -Nru dpdk-20.11.7/drivers/compress/qat/qat_comp_pmd.c dpdk-20.11.8/drivers/compress/qat/qat_comp_pmd.c --- dpdk-20.11.7/drivers/compress/qat/qat_comp_pmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/compress/qat/qat_comp_pmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -30,7 +30,7 @@ RTE_COMP_FF_OOP_LB_IN_SGL_OUT | RTE_COMP_FF_STATEFUL_DECOMPRESSION, .window_size = {.min = 15, .max = 15, .increment = 0} }, - {RTE_COMP_ALGO_LIST_END, 0, {0, 0, 0} } }; + RTE_COMP_END_OF_CAPABILITIES_LIST() }; static void qat_comp_stats_get(struct rte_compressdev *dev, diff -Nru dpdk-20.11.7/drivers/crypto/ccp/ccp_dev.c dpdk-20.11.8/drivers/crypto/ccp/ccp_dev.c --- dpdk-20.11.7/drivers/crypto/ccp/ccp_dev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/crypto/ccp/ccp_dev.c 2023-04-27 17:57:22.000000000 +0000 @@ -361,7 +361,7 @@ if (ccp_get_bit(&cmd_q->lsbmask, j)) weight++; - printf("Queue %d can access %d LSB regions of mask %lu\n", + CCP_LOG_DBG("Queue %d can access %d LSB regions of mask %lu\n", (int)cmd_q->id, weight, cmd_q->lsbmask); return weight ? 0 : -EINVAL; @@ -797,7 +797,7 @@ snprintf(dirname, sizeof(dirname), "%s/%s", SYSFS_PCI_DEVICES, d->d_name); if (is_ccp_device(dirname, ccp_id, &ccp_type)) { - printf("CCP : Detected CCP device with ID = 0x%x\n", + CCP_LOG_DBG("CCP : Detected CCP device with ID = 0x%x\n", ccp_id[ccp_type].device_id); ret = ccp_probe_device(dirname, domain, bus, devid, function, ccp_type); diff -Nru dpdk-20.11.7/drivers/crypto/ccp/ccp_pci.c dpdk-20.11.8/drivers/crypto/ccp/ccp_pci.c --- dpdk-20.11.7/drivers/crypto/ccp/ccp_pci.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/crypto/ccp/ccp_pci.c 2023-04-27 17:57:22.000000000 +0000 @@ -11,6 +11,7 @@ #include #include "ccp_pci.h" +#include "ccp_pmd_private.h" static const char * const uio_module_names[] = { "igb_uio", @@ -40,7 +41,7 @@ rewind(fp); } fclose(fp); - printf("Insert igb_uio or uio_pci_generic kernel module(s)"); + CCP_LOG_DBG("Insert igb_uio or uio_pci_generic kernel module(s)"); return -1;/* uio not inserted */ } diff -Nru dpdk-20.11.7/drivers/crypto/ccp/rte_ccp_pmd.c dpdk-20.11.8/drivers/crypto/ccp/rte_ccp_pmd.c --- dpdk-20.11.7/drivers/crypto/ccp/rte_ccp_pmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/crypto/ccp/rte_ccp_pmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -342,7 +342,7 @@ goto init_error; } - printf("CCP : Crypto device count = %d\n", cryptodev_cnt); + CCP_LOG_DBG("CCP : Crypto device count = %d\n", cryptodev_cnt); dev->driver_id = ccp_cryptodev_driver_id; /* register rx/tx burst functions for data path */ diff -Nru dpdk-20.11.7/drivers/crypto/qat/qat_sym_session.c dpdk-20.11.8/drivers/crypto/qat/qat_sym_session.c --- dpdk-20.11.7/drivers/crypto/qat/qat_sym_session.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/crypto/qat/qat_sym_session.c 2023-04-27 17:57:22.000000000 +0000 @@ -1572,9 +1572,10 @@ key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT; } else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2 || cdesc->qat_cipher_alg == - ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) + ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3) { key_convert = ICP_QAT_HW_CIPHER_KEY_CONVERT; - else if (cdesc->qat_dir == ICP_QAT_HW_CIPHER_ENCRYPT) + cdesc->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT; + } else if (cdesc->qat_dir == ICP_QAT_HW_CIPHER_ENCRYPT) key_convert = ICP_QAT_HW_CIPHER_NO_CONVERT; else key_convert = ICP_QAT_HW_CIPHER_KEY_CONVERT; diff -Nru dpdk-20.11.7/drivers/crypto/snow3g/rte_snow3g_pmd.c dpdk-20.11.8/drivers/crypto/snow3g/rte_snow3g_pmd.c --- dpdk-20.11.7/drivers/crypto/snow3g/rte_snow3g_pmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/crypto/snow3g/rte_snow3g_pmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -371,7 +371,8 @@ process_op_bit(struct rte_crypto_op *op, struct snow3g_session *session, struct snow3g_qp *qp, uint16_t *accumulated_enqueued_ops) { - unsigned enqueued_op, processed_op; + unsigned int processed_op; + int ret; switch (session->op) { case SNOW3G_OP_ONLY_CIPHER: @@ -412,9 +413,13 @@ if (unlikely(processed_op != 1)) return 0; - enqueued_op = rte_ring_enqueue(qp->processed_ops, op); - qp->qp_stats.enqueued_count += enqueued_op; - *accumulated_enqueued_ops += enqueued_op; + + ret = rte_ring_enqueue(qp->processed_ops, op); + if (ret != 0) + return ret; + + qp->qp_stats.enqueued_count += 1; + *accumulated_enqueued_ops += 1; return 1; } diff -Nru dpdk-20.11.7/drivers/net/bnxt/bnxt_ethdev.c dpdk-20.11.8/drivers/net/bnxt/bnxt_ethdev.c --- dpdk-20.11.7/drivers/net/bnxt/bnxt_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/bnxt/bnxt_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -1030,7 +1030,6 @@ .tx_free_thresh = 32, .tx_rs_thresh = 32, }; - eth_dev->data->dev_conf.intr_conf.lsc = 1; dev_info->rx_desc_lim.nb_min = BNXT_MIN_RING_DESC; dev_info->rx_desc_lim.nb_max = BNXT_MAX_RX_RING_DESC; @@ -5772,6 +5771,7 @@ rte_eth_copy_pci_info(eth_dev, pci_dev); eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; + eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC; bp = eth_dev->data->dev_private; diff -Nru dpdk-20.11.7/drivers/net/bnxt/bnxt_rxq.c dpdk-20.11.8/drivers/net/bnxt/bnxt_rxq.c --- dpdk-20.11.7/drivers/net/bnxt/bnxt_rxq.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/bnxt/bnxt_rxq.c 2023-04-27 17:57:22.000000000 +0000 @@ -446,6 +446,12 @@ return -EINVAL; } + /* reset the previous stats for the rx_queue since the counters + * will be cleared when the queue is started. + */ + memset(&bp->prev_rx_ring_stats[rx_queue_id], 0, + sizeof(struct bnxt_ring_stats)); + /* Set the queue state to started here. * We check the status of the queue while posting buffer. * If queue is it started, we do not post buffers for Rx. diff -Nru dpdk-20.11.7/drivers/net/bnxt/bnxt_rxr.c dpdk-20.11.8/drivers/net/bnxt/bnxt_rxr.c --- dpdk-20.11.7/drivers/net/bnxt/bnxt_rxr.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/bnxt/bnxt_rxr.c 2023-04-27 17:57:22.000000000 +0000 @@ -749,7 +749,6 @@ skip_mark: mbuf->hash.fdir.hi = 0; - mbuf->hash.fdir.id = 0; return 0; } diff -Nru dpdk-20.11.7/drivers/net/bnxt/bnxt_txr.c dpdk-20.11.8/drivers/net/bnxt/bnxt_txr.c --- dpdk-20.11.7/drivers/net/bnxt/bnxt_txr.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/bnxt/bnxt_txr.c 2023-04-27 17:57:22.000000000 +0000 @@ -535,6 +535,12 @@ if (rc) return rc; + /* reset the previous stats for the tx_queue since the counters + * will be cleared when the queue is started. + */ + memset(&bp->prev_tx_ring_stats[tx_queue_id], 0, + sizeof(struct bnxt_ring_stats)); + dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; txq->tx_started = true; PMD_DRV_LOG(DEBUG, "Tx queue started\n"); diff -Nru dpdk-20.11.7/drivers/net/e1000/em_rxtx.c dpdk-20.11.8/drivers/net/e1000/em_rxtx.c --- dpdk-20.11.7/drivers/net/e1000/em_rxtx.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/e1000/em_rxtx.c 2023-04-27 17:57:22.000000000 +0000 @@ -1031,6 +1031,7 @@ * - RX port identifier, * - hardware offload data, if any: * - IP checksum flag, + * - VLAN TCI, if any, * - error flags. */ first_seg->port = rxq->port_id; @@ -1040,7 +1041,7 @@ rx_desc_error_to_pkt_flags(rxd.errors); /* Only valid if PKT_RX_VLAN set in pkt_flags */ - rxm->vlan_tci = rte_le_to_cpu_16(rxd.special); + first_seg->vlan_tci = rte_le_to_cpu_16(rxd.special); /* Prefetch data of first segment, if configured to do so. */ rte_packet_prefetch((char *)first_seg->buf_addr + diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_cmd.h dpdk-20.11.8/drivers/net/hns3/hns3_cmd.h --- dpdk-20.11.7/drivers/net/hns3/hns3_cmd.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_cmd.h 2023-04-27 17:57:22.000000000 +0000 @@ -579,6 +579,7 @@ #define HNS3_RSS_CFG_TBL_SIZE_H 4 #define HNS3_RSS_CFG_TBL_BW_H 2 #define HNS3_RSS_CFG_TBL_BW_L 8 +#define HNS3_RSS_CFG_TBL_BW_H_M 0x3 /* Configure the indirection table, opcode:0x0D07 */ struct hns3_rss_indirection_table_cmd { diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_ethdev.c dpdk-20.11.8/drivers/net/hns3/hns3_ethdev.c --- dpdk-20.11.7/drivers/net/hns3/hns3_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -2606,7 +2606,7 @@ }; info->reta_size = hw->rss_ind_tbl_size; - info->hash_key_size = HNS3_RSS_KEY_SIZE; + info->hash_key_size = hw->rss_key_size; info->flow_type_rss_offloads = HNS3_ETH_RSS_SUPPORT; info->default_rxportconf.burst_size = HNS3_DEFAULT_PORT_CONF_BURST_SIZE; @@ -3040,12 +3040,21 @@ { if (hw->rss_ind_tbl_size == 0 || hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { - hns3_err(hw, "the size of hash lookup table configured (%u)" - " exceeds the maximum(%u)", hw->rss_ind_tbl_size, - HNS3_RSS_IND_TBL_SIZE_MAX); + hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", + hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); return -EINVAL; } + if (hw->rss_key_size == 0 || hw->rss_key_size > HNS3_RSS_KEY_SIZE_MAX) { + hns3_err(hw, "the RSS key size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", + hw->rss_key_size, HNS3_RSS_KEY_SIZE_MAX); + return -EINVAL; + } + + if (hw->rss_key_size > HNS3_RSS_KEY_SIZE) + hns3_warn(hw, "the RSS key size obtained (%u) is greater than the default key size (%u)", + hw->rss_key_size, HNS3_RSS_KEY_SIZE); + return 0; } @@ -5068,8 +5077,7 @@ rte_spinlock_unlock(&hw->lock); hns3_rx_scattered_calc(dev); - hns3_set_rxtx_function(dev); - hns3_mp_req_start_rxtx(dev); + hns3_start_rxtx_datapath(dev); rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, dev); /* Enable interrupt of all rx queues before enabling queues */ @@ -5175,12 +5183,7 @@ dev->data->dev_started = 0; hw->adapter_state = HNS3_NIC_STOPPING; - hns3_set_rxtx_function(dev); - rte_wmb(); - /* Disable datapath on secondary process. */ - hns3_mp_req_stop_rxtx(dev); - /* Prevent crashes when queues are still in use. */ - rte_delay_ms(hw->cfg_max_queues); + hns3_stop_rxtx_datapath(dev); rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { @@ -5670,11 +5673,7 @@ rte_eal_alarm_cancel(hns3_service_handler, eth_dev); hw->mac.link_status = ETH_LINK_DOWN; - hns3_set_rxtx_function(eth_dev); - rte_wmb(); - /* Disable datapath on secondary process. */ - hns3_mp_req_stop_rxtx(eth_dev); - rte_delay_ms(hw->cfg_max_queues); + hns3_stop_rxtx_datapath(eth_dev); rte_spinlock_lock(&hw->lock); if (hns->hw.adapter_state == HNS3_NIC_STARTED || @@ -5707,8 +5706,7 @@ hw->reset.level == HNS3_GLOBAL_RESET) hns3_set_rst_done(hw); eth_dev = &rte_eth_devices[hw->data->port_id]; - hns3_set_rxtx_function(eth_dev); - hns3_mp_req_start_rxtx(eth_dev); + hns3_start_rxtx_datapath(eth_dev); if (hw->adapter_state == HNS3_NIC_STARTED) { hns3_service_handler(eth_dev); diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_ethdev.h dpdk-20.11.8/drivers/net/hns3/hns3_ethdev.h --- dpdk-20.11.7/drivers/net/hns3/hns3_ethdev.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_ethdev.h 2023-04-27 17:57:22.000000000 +0000 @@ -896,15 +896,6 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define NEXT_ITEM_OF_ACTION(act, actions, index) \ - do { \ - (act) = (actions) + (index); \ - while ((act)->type == RTE_FLOW_ACTION_TYPE_VOID) { \ - (index)++; \ - (act) = (actions) + (index); \ - } \ - } while (0) - #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_ethdev_vf.c dpdk-20.11.8/drivers/net/hns3/hns3_ethdev_vf.c --- dpdk-20.11.7/drivers/net/hns3/hns3_ethdev_vf.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_ethdev_vf.c 2023-04-27 17:57:22.000000000 +0000 @@ -1163,9 +1163,8 @@ { if (hw->rss_ind_tbl_size == 0 || hw->rss_ind_tbl_size > HNS3_RSS_IND_TBL_SIZE_MAX) { - hns3_warn(hw, "the size of hash lookup table configured (%u)" - " exceeds the maximum(%u)", hw->rss_ind_tbl_size, - HNS3_RSS_IND_TBL_SIZE_MAX); + hns3_err(hw, "the indirection table size obtained (%u) is invalid, and should not be zero or exceed the maximum(%u)", + hw->rss_ind_tbl_size, HNS3_RSS_IND_TBL_SIZE_MAX); return -EINVAL; } @@ -1963,12 +1962,7 @@ dev->data->dev_started = 0; hw->adapter_state = HNS3_NIC_STOPPING; - hns3_set_rxtx_function(dev); - rte_wmb(); - /* Disable datapath on secondary process. */ - hns3_mp_req_stop_rxtx(dev); - /* Prevent crashes when queues are still in use. */ - rte_delay_ms(hw->cfg_max_queues); + hns3_stop_rxtx_datapath(dev); rte_spinlock_lock(&hw->lock); if (rte_atomic16_read(&hw->reset.resetting) == 0) { @@ -2242,8 +2236,7 @@ rte_spinlock_unlock(&hw->lock); hns3_rx_scattered_calc(dev); - hns3_set_rxtx_function(dev); - hns3_mp_req_start_rxtx(dev); + hns3_start_rxtx_datapath(dev); hns3vf_service_handler(dev); /* Enable interrupt of all rx queues before enabling queues */ @@ -2407,11 +2400,7 @@ rte_eal_alarm_cancel(hns3vf_service_handler, eth_dev); hw->mac.link_status = ETH_LINK_DOWN; - hns3_set_rxtx_function(eth_dev); - rte_wmb(); - /* Disable datapath on secondary process. */ - hns3_mp_req_stop_rxtx(eth_dev); - rte_delay_ms(hw->cfg_max_queues); + hns3_stop_rxtx_datapath(eth_dev); rte_spinlock_lock(&hw->lock); if (hw->adapter_state == HNS3_NIC_STARTED || @@ -2441,8 +2430,8 @@ struct rte_eth_dev *eth_dev; eth_dev = &rte_eth_devices[hw->data->port_id]; - hns3_set_rxtx_function(eth_dev); - hns3_mp_req_start_rxtx(eth_dev); + hns3_start_rxtx_datapath(eth_dev); + if (hw->adapter_state == HNS3_NIC_STARTED) { hns3vf_service_handler(eth_dev); diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_fdir.h dpdk-20.11.8/drivers/net/hns3/hns3_fdir.h --- dpdk-20.11.7/drivers/net/hns3/hns3_fdir.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_fdir.h 2023-04-27 17:57:22.000000000 +0000 @@ -175,10 +175,18 @@ struct hns3_fdir_rule fdir_conf; }; +struct hns3_flow_rss_conf { + struct rte_flow_action_rss conf; + uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ + uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ + uint64_t pattern_type; + uint64_t hw_pctypes; /* packet types in driver */ +}; + /* rss filter list structure */ struct hns3_rss_conf_ele { TAILQ_ENTRY(hns3_rss_conf_ele) entries; - struct hns3_rss_conf filter_info; + struct hns3_flow_rss_conf filter_info; }; /* hns3_flow memory list structure */ diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_flow.c dpdk-20.11.8/drivers/net/hns3/hns3_flow.c --- dpdk-20.11.7/drivers/net/hns3/hns3_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -5,10 +5,140 @@ #include #include #include +#include #include "hns3_ethdev.h" #include "hns3_logs.h" +union hns3_filter_conf { + struct hns3_fdir_rule fdir_conf; + struct hns3_flow_rss_conf rss_conf; +}; + +struct hns3_filter_info { + enum rte_filter_type type; + union hns3_filter_conf conf; +}; + +#define NEXT_ITEM_OF_ACTION(act, actions, index) \ + do { \ + (act) = (actions) + (index); \ + while ((act)->type == RTE_FLOW_ACTION_TYPE_VOID) { \ + (index)++; \ + (act) = (actions) + (index); \ + } \ + } while (0) + +#define NEXT_ITEM_OF_PATTERN(item, pattern, index) \ + do { \ + (item) = (pattern) + (index); \ + while ((item)->type == RTE_FLOW_ITEM_TYPE_VOID) { \ + (index)++; \ + (item) = (pattern) + (index); \ + } \ + } while (0) + +#define HNS3_HASH_HDR_ETH RTE_BIT64(0) +#define HNS3_HASH_HDR_IPV4 RTE_BIT64(1) +#define HNS3_HASH_HDR_IPV6 RTE_BIT64(2) +#define HNS3_HASH_HDR_TCP RTE_BIT64(3) +#define HNS3_HASH_HDR_UDP RTE_BIT64(4) +#define HNS3_HASH_HDR_SCTP RTE_BIT64(5) + +#define HNS3_HASH_VOID_NEXT_ALLOW BIT_ULL(RTE_FLOW_ITEM_TYPE_ETH) + +#define HNS3_HASH_ETH_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV4) | \ + BIT_ULL(RTE_FLOW_ITEM_TYPE_IPV6)) + +#define HNS3_HASH_IP_NEXT_ALLOW (BIT_ULL(RTE_FLOW_ITEM_TYPE_TCP) | \ + BIT_ULL(RTE_FLOW_ITEM_TYPE_UDP) | \ + BIT_ULL(RTE_FLOW_ITEM_TYPE_SCTP)) + +static const uint64_t hash_pattern_next_allow_items[] = { + [RTE_FLOW_ITEM_TYPE_VOID] = HNS3_HASH_VOID_NEXT_ALLOW, + [RTE_FLOW_ITEM_TYPE_ETH] = HNS3_HASH_ETH_NEXT_ALLOW, + [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_IP_NEXT_ALLOW, + [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_IP_NEXT_ALLOW, +}; + +static const uint64_t hash_pattern_item_header[] = { + [RTE_FLOW_ITEM_TYPE_ETH] = HNS3_HASH_HDR_ETH, + [RTE_FLOW_ITEM_TYPE_IPV4] = HNS3_HASH_HDR_IPV4, + [RTE_FLOW_ITEM_TYPE_IPV6] = HNS3_HASH_HDR_IPV6, + [RTE_FLOW_ITEM_TYPE_TCP] = HNS3_HASH_HDR_TCP, + [RTE_FLOW_ITEM_TYPE_UDP] = HNS3_HASH_HDR_UDP, + [RTE_FLOW_ITEM_TYPE_SCTP] = HNS3_HASH_HDR_SCTP, +}; + +#define HNS3_HASH_IPV4 (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV4) +#define HNS3_HASH_IPV4_TCP (HNS3_HASH_HDR_ETH | \ + HNS3_HASH_HDR_IPV4 | \ + HNS3_HASH_HDR_TCP) +#define HNS3_HASH_IPV4_UDP (HNS3_HASH_HDR_ETH | \ + HNS3_HASH_HDR_IPV4 | \ + HNS3_HASH_HDR_UDP) +#define HNS3_HASH_IPV4_SCTP (HNS3_HASH_HDR_ETH | \ + HNS3_HASH_HDR_IPV4 | \ + HNS3_HASH_HDR_SCTP) +#define HNS3_HASH_IPV6 (HNS3_HASH_HDR_ETH | HNS3_HASH_HDR_IPV6) +#define HNS3_HASH_IPV6_TCP (HNS3_HASH_HDR_ETH | \ + HNS3_HASH_HDR_IPV6 | \ + HNS3_HASH_HDR_TCP) +#define HNS3_HASH_IPV6_UDP (HNS3_HASH_HDR_ETH | \ + HNS3_HASH_HDR_IPV6 | \ + HNS3_HASH_HDR_UDP) +#define HNS3_HASH_IPV6_SCTP (HNS3_HASH_HDR_ETH | \ + HNS3_HASH_HDR_IPV6 | \ + HNS3_HASH_HDR_SCTP) + +static const struct hns3_hash_map_info { + /* flow type specified, zero means action works for all flow types. */ + uint64_t pattern_type; + uint64_t rss_pctype; /* packet type with prefix RTE_ETH_RSS_xxx */ + uint64_t l3l4_types; /* Supported L3/L4 RSS types for this packet type */ + uint64_t hw_pctype; /* packet type in driver */ + uint64_t tuple_mask; /* full tuples of the hw_pctype */ +} hash_map_table[] = { + /* IPV4 */ + { HNS3_HASH_IPV4, + ETH_RSS_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST, + HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M }, + { HNS3_HASH_IPV4, + ETH_RSS_NONFRAG_IPV4_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST, + HNS3_RSS_PCTYPE_IPV4_NONF, HNS3_RSS_TUPLE_IPV4_NONF_M }, + { HNS3_HASH_IPV4, + ETH_RSS_FRAG_IPV4, HNS3_RSS_SUPPORT_L3_SRC_DST, + HNS3_RSS_PCTYPE_IPV4_FLAG, HNS3_RSS_TUPLE_IPV4_FLAG_M }, + { HNS3_HASH_IPV4_TCP, + ETH_RSS_NONFRAG_IPV4_TCP, HNS3_RSS_SUPPORT_L3L4, + HNS3_RSS_PCTYPE_IPV4_TCP, HNS3_RSS_TUPLE_IPV4_TCP_M }, + { HNS3_HASH_IPV4_UDP, + ETH_RSS_NONFRAG_IPV4_UDP, HNS3_RSS_SUPPORT_L3L4, + HNS3_RSS_PCTYPE_IPV4_UDP, HNS3_RSS_TUPLE_IPV4_UDP_M }, + { HNS3_HASH_IPV4_SCTP, + ETH_RSS_NONFRAG_IPV4_SCTP, HNS3_RSS_SUPPORT_L3L4, + HNS3_RSS_PCTYPE_IPV4_SCTP, HNS3_RSS_TUPLE_IPV4_SCTP_M }, + /* IPV6 */ + { HNS3_HASH_IPV6, + ETH_RSS_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST, + HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M }, + { HNS3_HASH_IPV6, + ETH_RSS_NONFRAG_IPV6_OTHER, HNS3_RSS_SUPPORT_L3_SRC_DST, + HNS3_RSS_PCTYPE_IPV6_NONF, HNS3_RSS_TUPLE_IPV6_NONF_M }, + { HNS3_HASH_IPV6, + ETH_RSS_FRAG_IPV6, HNS3_RSS_SUPPORT_L3_SRC_DST, + HNS3_RSS_PCTYPE_IPV6_FLAG, HNS3_RSS_TUPLE_IPV6_FLAG_M }, + { HNS3_HASH_IPV6_TCP, + ETH_RSS_NONFRAG_IPV6_TCP, HNS3_RSS_SUPPORT_L3L4, + HNS3_RSS_PCTYPE_IPV6_TCP, HNS3_RSS_TUPLE_IPV6_TCP_M }, + { HNS3_HASH_IPV6_UDP, + ETH_RSS_NONFRAG_IPV6_UDP, HNS3_RSS_SUPPORT_L3L4, + HNS3_RSS_PCTYPE_IPV6_UDP, HNS3_RSS_TUPLE_IPV6_UDP_M }, + { HNS3_HASH_IPV6_SCTP, + ETH_RSS_NONFRAG_IPV6_SCTP, HNS3_RSS_SUPPORT_L3L4, + HNS3_RSS_PCTYPE_IPV6_SCTP, HNS3_RSS_TUPLE_IPV6_SCTP_M }, +}; + static const uint8_t full_mask[VNI_OR_TNI_LEN] = { 0xFF, 0xFF, 0xFF }; static const uint8_t zero_mask[VNI_OR_TNI_LEN] = { 0x00, 0x00, 0x00 }; @@ -78,7 +208,7 @@ } /* - * This function is used to find rss general action. + * This function is used to parse filter type. * 1. As we know RSS is used to spread packets among several queues, the flow * API provide the struct rte_flow_action_rss, user could config its field * sush as: func/level/types/key/queue to control RSS function. @@ -86,16 +216,18 @@ * implemented by FDIR + RSS in hns3 hardware, user can create one FDIR rule * which action is RSS queues region. * 3. When action is RSS, we use the following rule to distinguish: - * Case 1: pattern have ETH and action's queue_num > 0, indicate it is queue - * region configuration. + * Case 1: pattern has ETH and all fields in RSS action except 'queues' are + * zero or default, indicate it is queue region configuration. * Case other: an rss general action. */ -static const struct rte_flow_action * -hns3_find_rss_general_action(const struct rte_flow_item pattern[], - const struct rte_flow_action actions[]) +static void +hns3_parse_filter_type(const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct hns3_filter_info *filter_info) { + const struct rte_flow_action_rss *rss_act; const struct rte_flow_action *act = NULL; - const struct hns3_rss_conf *rss; + bool only_has_queues = false; bool have_eth = false; for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) { @@ -104,8 +236,10 @@ break; } } - if (!act) - return NULL; + if (act == NULL) { + filter_info->type = RTE_ETH_FILTER_FDIR; + return; + } for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { if (pattern->type == RTE_FLOW_ITEM_TYPE_ETH) { @@ -114,19 +248,21 @@ } } - rss = act->conf; - if (have_eth && rss->conf.queue_num) { + rss_act = act->conf; + only_has_queues = (rss_act->queue_num > 0) && + (rss_act->func == RTE_ETH_HASH_FUNCTION_DEFAULT && + rss_act->types == 0 && rss_act->key_len == 0); + if (have_eth && only_has_queues) { /* - * Pattern have ETH and action's queue_num > 0, indicate this is - * queue region configuration. - * Because queue region is implemented by FDIR + RSS in hns3 - * hardware, it needs to enter FDIR process, so here return NULL - * to avoid enter RSS process. + * Pattern has ETH and all fields in RSS action except 'queues' + * are zero or default, which indicates this is queue region + * configuration. */ - return NULL; + filter_info->type = RTE_ETH_FILTER_FDIR; + return; } - return act; + filter_info->type = RTE_ETH_FILTER_HASH; } static inline struct hns3_flow_counter * @@ -1225,7 +1361,6 @@ { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct hns3_fdir_rule_ele *fdir_rule_ptr; - struct hns3_rss_conf_ele *rss_filter_ptr; struct hns3_flow_mem *flow_node; fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list); @@ -1235,13 +1370,6 @@ fdir_rule_ptr = TAILQ_FIRST(&hw->flow_fdir_list); } - rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); - while (rss_filter_ptr) { - TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); - rte_free(rss_filter_ptr); - rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); - } - flow_node = TAILQ_FIRST(&hw->flow_list); while (flow_node) { TAILQ_REMOVE(&hw->flow_list, flow_node, entries); @@ -1252,227 +1380,478 @@ } static bool +hns3_flow_rule_key_same(const struct rte_flow_action_rss *comp, + const struct rte_flow_action_rss *with) +{ + if (comp->key_len != with->key_len) + return false; + + if (with->key_len == 0) + return true; + + if (comp->key == NULL && with->key == NULL) + return true; + + if (!(comp->key != NULL && with->key != NULL)) + return false; + + return !memcmp(comp->key, with->key, with->key_len); +} + +static bool +hns3_flow_rule_queues_same(const struct rte_flow_action_rss *comp, + const struct rte_flow_action_rss *with) +{ + if (comp->queue_num != with->queue_num) + return false; + + if (with->queue_num == 0) + return true; + + if (comp->queue == NULL && with->queue == NULL) + return true; + + if (!(comp->queue != NULL && with->queue != NULL)) + return false; + + return !memcmp(comp->queue, with->queue, with->queue_num); +} + +static bool hns3_action_rss_same(const struct rte_flow_action_rss *comp, const struct rte_flow_action_rss *with) { - bool rss_key_is_same; - bool func_is_same; + bool same_level; + bool same_types; + bool same_func; + + same_level = (comp->level == with->level); + same_types = (comp->types == with->types); + same_func = (comp->func == with->func); + + return same_level && same_types && same_func && + hns3_flow_rule_key_same(comp, with) && + hns3_flow_rule_queues_same(comp, with); +} +static bool +hns3_valid_ipv6_sctp_rss_types(struct hns3_hw *hw, uint64_t types) +{ /* - * When user flush all RSS rule, RSS func is set invalid with - * RTE_ETH_HASH_FUNCTION_MAX. Then the user create a flow after - * flushed, any validate RSS func is different with it before - * flushed. Others, when user create an action RSS with RSS func - * specified RTE_ETH_HASH_FUNCTION_DEFAULT, the func is the same - * between continuous RSS flow. + * Some hardware don't support to use src/dst port fields to hash + * for IPV6 SCTP packet type. */ - if (comp->func == RTE_ETH_HASH_FUNCTION_MAX) - func_is_same = false; - else - func_is_same = (with->func != RTE_ETH_HASH_FUNCTION_DEFAULT) ? - (comp->func == with->func) : true; + if (types & ETH_RSS_NONFRAG_IPV6_SCTP && + types & HNS3_RSS_SUPPORT_L4_SRC_DST && + !hw->rss_info.ipv6_sctp_offload_supported) + return false; - if (with->key_len == 0 || with->key == NULL) - rss_key_is_same = 1; - else - rss_key_is_same = comp->key_len == with->key_len && - !memcmp(comp->key, with->key, with->key_len); + return true; +} - return (func_is_same && rss_key_is_same && - comp->types == (with->types & HNS3_ETH_RSS_SUPPORT) && - comp->level == with->level && - comp->queue_num == with->queue_num && - !memcmp(comp->queue, with->queue, - sizeof(*with->queue) * with->queue_num)); +static int +hns3_flow_parse_hash_func(const struct rte_flow_action_rss *rss_act, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) +{ + if (rss_act->func >= RTE_ETH_HASH_FUNCTION_MAX) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + NULL, "RSS hash func are not supported"); + + rss_conf->conf.func = rss_act->func; + return 0; } static int -hns3_rss_conf_copy(struct hns3_rss_conf *out, - const struct rte_flow_action_rss *in) +hns3_flow_parse_hash_key(struct hns3_hw *hw, + const struct rte_flow_action_rss *rss_act, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) { - if (in->key_len > RTE_DIM(out->key) || - in->queue_num > RTE_DIM(out->queue)) - return -EINVAL; - if (in->key == NULL && in->key_len) - return -EINVAL; - out->conf = (struct rte_flow_action_rss) { - .func = in->func, - .level = in->level, - .types = in->types, - .key_len = in->key_len, - .queue_num = in->queue_num, - }; - out->conf.queue = memcpy(out->queue, in->queue, - sizeof(*in->queue) * in->queue_num); - if (in->key) - out->conf.key = memcpy(out->key, in->key, in->key_len); + if (rss_act->key_len != hw->rss_key_size) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + NULL, "invalid RSS key length"); + + if (rss_act->key != NULL) + memcpy(rss_conf->key, rss_act->key, rss_act->key_len); + else + memcpy(rss_conf->key, hns3_hash_key, + RTE_MIN(sizeof(hns3_hash_key), rss_act->key_len)); + /* Need to record if user sets hash key. */ + rss_conf->conf.key = rss_act->key; + rss_conf->conf.key_len = rss_act->key_len; return 0; } -/* - * This function is used to parse rss action validation. - */ static int -hns3_parse_rss_filter(struct rte_eth_dev *dev, - const struct rte_flow_action *actions, - struct rte_flow_error *error) +hns3_flow_parse_queues(struct hns3_hw *hw, + const struct rte_flow_action_rss *rss_act, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) { - struct hns3_adapter *hns = dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - struct hns3_rss_conf *rss_conf = &hw->rss_info; - const struct rte_flow_action_rss *rss; - const struct rte_flow_action *act; - uint32_t act_index = 0; - uint16_t n; + uint16_t i; - NEXT_ITEM_OF_ACTION(act, actions, act_index); - rss = act->conf; + if (rss_act->queue_num > hw->rss_ind_tbl_size) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + NULL, + "queue number can not exceed RSS indirection table."); - if (rss == NULL) { - return rte_flow_error_set(error, EINVAL, + if (rss_act->queue_num > HNS3_RSS_QUEUES_BUFFER_NUM) + return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION_CONF, - act, "no valid queues"); + NULL, + "queue number configured exceeds queue buffer size driver supported"); + + for (i = 0; i < rss_act->queue_num; i++) { + if (rss_act->queue[i] >= hw->alloc_rss_size) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + NULL, + "queue id must be less than queue number allocated to a TC"); } - if (rss->queue_num > RTE_DIM(rss_conf->queue)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, - "queue number configured exceeds " - "queue buffer size driver supported"); + memcpy(rss_conf->queue, rss_act->queue, + rss_act->queue_num * sizeof(rss_conf->queue[0])); + rss_conf->conf.queue = rss_conf->queue; + rss_conf->conf.queue_num = rss_act->queue_num; - for (n = 0; n < rss->queue_num; n++) { - if (rss->queue[n] < hw->alloc_rss_size) - continue; - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, - "queue id must be less than queue number allocated to a TC"); + return 0; +} + +static int +hns3_flow_get_hw_pctype(struct hns3_hw *hw, + const struct rte_flow_action_rss *rss_act, + const struct hns3_hash_map_info *map, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) +{ + uint64_t l3l4_src_dst, l3l4_refine, left_types; + + if (rss_act->types == 0) { + /* Disable RSS hash of this packet type if types is zero. */ + rss_conf->hw_pctypes |= map->hw_pctype; + return 0; } - if (!(rss->types & HNS3_ETH_RSS_SUPPORT) && rss->types) + /* + * Can not have extra types except rss_pctype and l3l4_type in this map. + */ + left_types = ~map->rss_pctype & rss_act->types; + if (left_types & ~map->l3l4_types) return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, - act, - "Flow types is unsupported by " - "hns3's RSS"); - if (rss->func >= RTE_ETH_HASH_FUNCTION_MAX) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, - "RSS hash func are not supported"); - if (rss->level) + RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, + "cannot set extra types."); + + l3l4_src_dst = left_types; + /* L3/L4 SRC and DST shouldn't be specified at the same time. */ + l3l4_refine = rte_eth_rss_hf_refine(l3l4_src_dst); + if (l3l4_refine != l3l4_src_dst) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, - "a nonzero RSS encapsulation level is not supported"); - if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key)) + RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, + "cannot specify L3_SRC/DST_ONLY or L4_SRC/DST_ONLY at the same."); + + if (!hns3_valid_ipv6_sctp_rss_types(hw, rss_act->types)) return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, act, - "RSS hash key must be exactly 40 bytes"); + RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL, + "hardware doesn't support to use L4 src/dst to hash for IPV6-SCTP."); - /* - * For Kunpeng920 and Kunpeng930 NIC hardware, it is not supported to - * use dst port/src port fields to RSS hash for the following packet - * types. - * - IPV4 FRAG | IPV4 NONFRAG | IPV6 FRAG | IPV6 NONFRAG - * Besides, for Kunpeng920, The NIC hardware is not supported to use - * src/dst port fields to RSS hash for IPV6 SCTP packet type. - */ - if (rss->types & (ETH_RSS_L4_DST_ONLY | ETH_RSS_L4_SRC_ONLY) && - (rss->types & ETH_RSS_IP || - (!hw->rss_info.ipv6_sctp_offload_supported && - rss->types & ETH_RSS_NONFRAG_IPV6_SCTP))) - return rte_flow_error_set(error, EINVAL, + rss_conf->hw_pctypes |= map->hw_pctype; + + return 0; +} + +static int +hns3_flow_parse_rss_types_by_ptype(struct hns3_hw *hw, + const struct rte_flow_action_rss *rss_act, + uint64_t pattern_type, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) +{ + const struct hns3_hash_map_info *map; + bool matched = false; + uint16_t i; + int ret; + + for (i = 0; i < RTE_DIM(hash_map_table); i++) { + map = &hash_map_table[i]; + if (map->pattern_type != pattern_type) { + /* + * If the target pattern type is already matched with + * the one before this pattern in the hash map table, + * no need to continue walk. + */ + if (matched) + break; + continue; + } + matched = true; + + /* + * If pattern type is matched and the 'types' is zero, all packet flow + * types related to this pattern type disable RSS hash. + * Otherwise, RSS types must match the pattern type and cannot have no + * extra or unsupported types. + */ + if (rss_act->types != 0 && !(map->rss_pctype & rss_act->types)) + continue; + + ret = hns3_flow_get_hw_pctype(hw, rss_act, map, rss_conf, error); + if (ret != 0) + return ret; + } + + if (rss_conf->hw_pctypes != 0) + return 0; + + if (matched) + return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION_CONF, - &rss->types, - "input RSS types are not supported"); + NULL, "RSS types are unsupported"); - act_index++; + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + NULL, "Pattern specified is unsupported"); +} - /* Check if the next not void action is END */ - NEXT_ITEM_OF_ACTION(act, actions, act_index); - if (act->type != RTE_FLOW_ACTION_TYPE_END) { - memset(rss_conf, 0, sizeof(struct hns3_rss_conf)); - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - act, "Not supported action."); +static uint64_t +hns3_flow_get_all_hw_pctypes(uint64_t types) +{ + uint64_t hw_pctypes = 0; + uint16_t i; + + for (i = 0; i < RTE_DIM(hash_map_table); i++) { + if (types & hash_map_table[i].rss_pctype) + hw_pctypes |= hash_map_table[i].hw_pctype; } - return 0; + return hw_pctypes; } static int -hns3_disable_rss(struct hns3_hw *hw) +hns3_flow_parse_rss_types(struct hns3_hw *hw, + const struct rte_flow_action_rss *rss_act, + uint64_t pattern_type, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) { + rss_conf->conf.types = rss_act->types; + + /* no pattern specified to set global RSS types. */ + if (pattern_type == 0) { + if (!hns3_check_rss_types_valid(hw, rss_act->types)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + NULL, "RSS types is invalid."); + rss_conf->hw_pctypes = + hns3_flow_get_all_hw_pctypes(rss_act->types); + return 0; + } + + return hns3_flow_parse_rss_types_by_ptype(hw, rss_act, pattern_type, + rss_conf, error); +} + +static int +hns3_flow_parse_hash_global_conf(struct rte_eth_dev *dev, + const struct rte_flow_action_rss *rss_act, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); int ret; - ret = hns3_set_rss_tuple_by_rss_hf(hw, 0); - if (ret) + ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error); + if (ret != 0) return ret; - return 0; + if (rss_act->queue_num > 0) { + ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error); + if (ret != 0) + return ret; + } + + if (rss_act->key_len > 0) { + ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error); + if (ret != 0) + return ret; + } + + return hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type, + rss_conf, error); } -static void -hns3_parse_rss_key(struct hns3_hw *hw, struct rte_flow_action_rss *rss_conf) +static int +hns3_flow_parse_pattern_type(const struct rte_flow_item pattern[], + uint64_t *ptype, struct rte_flow_error *error) { - if (rss_conf->key == NULL || rss_conf->key_len < HNS3_RSS_KEY_SIZE) { - hns3_warn(hw, "Default RSS hash key to be set"); - rss_conf->key = hns3_hash_key; - rss_conf->key_len = HNS3_RSS_KEY_SIZE; + enum rte_flow_item_type pre_type = RTE_FLOW_ITEM_TYPE_VOID; + const char *message = "Pattern specified isn't supported"; + uint64_t item_hdr, pattern_hdrs = 0; + enum rte_flow_item_type cur_type; + + for (; pattern->type != RTE_FLOW_ITEM_TYPE_END; pattern++) { + if (pattern->type == RTE_FLOW_ITEM_TYPE_VOID) + continue; + if (pattern->mask || pattern->spec || pattern->last) { + message = "Header info shouldn't be specified"; + goto unsup; + } + + /* Check the sub-item allowed by the previous item . */ + if (pre_type >= RTE_DIM(hash_pattern_next_allow_items) || + !(hash_pattern_next_allow_items[pre_type] & + BIT_ULL(pattern->type))) + goto unsup; + + cur_type = pattern->type; + /* Unsupported for current type being greater than array size. */ + if (cur_type >= RTE_DIM(hash_pattern_item_header)) + goto unsup; + + /* The value is zero, which means unsupported current header. */ + item_hdr = hash_pattern_item_header[cur_type]; + if (item_hdr == 0) + goto unsup; + + /* Have duplicate pattern header. */ + if (item_hdr & pattern_hdrs) + goto unsup; + pre_type = cur_type; + pattern_hdrs |= item_hdr; } + + if (pattern_hdrs != 0) { + *ptype = pattern_hdrs; + return 0; + } + +unsup: + return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, + pattern, message); } static int -hns3_parse_rss_algorithm(struct hns3_hw *hw, enum rte_eth_hash_function *func, - uint8_t *hash_algo) +hns3_flow_parse_pattern_act(struct rte_eth_dev *dev, + const struct rte_flow_item pattern[], + const struct rte_flow_action_rss *rss_act, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) { - enum rte_eth_hash_function algo_func = *func; - switch (algo_func) { - case RTE_ETH_HASH_FUNCTION_DEFAULT: - /* Keep *hash_algo as what it used to be */ - algo_func = hw->rss_info.conf.func; - break; - case RTE_ETH_HASH_FUNCTION_TOEPLITZ: - *hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; - break; - case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: - *hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; - break; - case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: - *hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; - break; - default: - hns3_err(hw, "Invalid RSS algorithm configuration(%d)", - algo_func); - return -EINVAL; + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret; + + ret = hns3_flow_parse_hash_func(rss_act, rss_conf, error); + if (ret != 0) + return ret; + + if (rss_act->key_len > 0) { + ret = hns3_flow_parse_hash_key(hw, rss_act, rss_conf, error); + if (ret != 0) + return ret; } - *func = algo_func; + + if (rss_act->queue_num > 0) { + ret = hns3_flow_parse_queues(hw, rss_act, rss_conf, error); + if (ret != 0) + return ret; + } + + ret = hns3_flow_parse_pattern_type(pattern, &rss_conf->pattern_type, + error); + if (ret != 0) + return ret; + + ret = hns3_flow_parse_rss_types(hw, rss_act, rss_conf->pattern_type, + rss_conf, error); + if (ret != 0) + return ret; + + if (rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT || + rss_act->key_len > 0 || rss_act->queue_num > 0) + hns3_warn(hw, "hash func, key and queues are global config, which work for all flow types. " + "Recommend: don't set them together with pattern."); return 0; } +static bool +hns3_rss_action_is_dup(struct hns3_hw *hw, + const struct hns3_flow_rss_conf *conf) +{ + struct hns3_rss_conf_ele *filter; + + TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) { + if (conf->pattern_type != filter->filter_info.pattern_type) + continue; + + if (hns3_action_rss_same(&filter->filter_info.conf, &conf->conf)) + return true; + } + + return false; +} + +/* + * This function is used to parse rss action validation. + */ static int -hns3_hw_rss_hash_set(struct hns3_hw *hw, struct rte_flow_action_rss *rss_config) +hns3_parse_rss_filter(struct rte_eth_dev *dev, + const struct rte_flow_item pattern[], + const struct rte_flow_action *actions, + struct hns3_flow_rss_conf *rss_conf, + struct rte_flow_error *error) { + struct hns3_adapter *hns = dev->data->dev_private; + const struct rte_flow_action_rss *rss_act; + const struct rte_flow_action *act; + const struct rte_flow_item *pat; + struct hns3_hw *hw = &hns->hw; + uint32_t index = 0; int ret; - hns3_parse_rss_key(hw, rss_config); + NEXT_ITEM_OF_ACTION(act, actions, index); + if (actions[1].type != RTE_FLOW_ACTION_TYPE_END) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + &actions[1], + "Only support one action for RSS."); - ret = hns3_parse_rss_algorithm(hw, &rss_config->func, - &hw->rss_info.hash_algo); - if (ret) - return ret; + rss_act = (const struct rte_flow_action_rss *)act->conf; + if (rss_act == NULL) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + act, "lost RSS action configuration"); + } - ret = hns3_set_rss_algo_key(hw, rss_config->key); - if (ret) - return ret; + if (rss_act->level != 0) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + act, + "RSS level is not supported"); - hw->rss_info.conf.func = rss_config->func; + index = 0; + NEXT_ITEM_OF_PATTERN(pat, pattern, index); + if (pat[0].type == RTE_FLOW_ITEM_TYPE_END) { + rss_conf->pattern_type = 0; + ret = hns3_flow_parse_hash_global_conf(dev, rss_act, + rss_conf, error); + } else { + ret = hns3_flow_parse_pattern_act(dev, pat, rss_act, + rss_conf, error); + } + if (ret != 0) + return ret; - ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_config->types); - if (ret) - hns3_err(hw, "Update RSS tuples by rss hf failed %d", ret); + if (hns3_rss_action_is_dup(hw, rss_conf)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + act, "duplicate RSS rule"); - return ret; + return 0; } static int @@ -1484,8 +1863,6 @@ uint32_t i; /* Fill in redirection table */ - memcpy(indir_tbl, hw->rss_info.rss_indirection_tbl, - sizeof(hw->rss_info.rss_indirection_tbl)); for (i = 0, j = 0; i < hw->rss_ind_tbl_size; i++, j++) { j %= num; if (conf->queue[j] >= hw->alloc_rss_size) { @@ -1500,82 +1877,105 @@ return hns3_set_rss_indir_table(hw, indir_tbl, hw->rss_ind_tbl_size); } +static uint64_t +hns3_flow_get_pctype_tuple_mask(uint64_t hw_pctype) +{ + uint64_t tuple_mask = 0; + uint16_t i; + + for (i = 0; i < RTE_DIM(hash_map_table); i++) { + if (hw_pctype == hash_map_table[i].hw_pctype) { + tuple_mask = hash_map_table[i].tuple_mask; + break; + } + } + + return tuple_mask; +} + +static int +hns3_flow_set_rss_ptype_tuple(struct hns3_hw *hw, + struct hns3_flow_rss_conf *rss_conf) +{ + uint64_t old_tuple_fields, new_tuple_fields; + uint64_t hw_pctypes, tuples, tuple_mask = 0; + bool cfg_global_tuple; + int ret; + + cfg_global_tuple = (rss_conf->pattern_type == 0); + if (!cfg_global_tuple) { + /* + * To ensure that different packets do not affect each other, + * we have to first read all tuple fields, and then only modify + * the tuples for the specified packet type. + */ + ret = hns3_get_rss_tuple_field(hw, &old_tuple_fields); + if (ret != 0) + return ret; + + new_tuple_fields = old_tuple_fields; + hw_pctypes = rss_conf->hw_pctypes; + while (hw_pctypes > 0) { + uint32_t idx = rte_bsf64(hw_pctypes); + uint64_t pctype = BIT_ULL(idx); + + tuple_mask = hns3_flow_get_pctype_tuple_mask(pctype); + tuples = hns3_rss_calc_tuple_filed(rss_conf->conf.types); + new_tuple_fields &= ~tuple_mask; + new_tuple_fields |= tuples; + hw_pctypes &= ~pctype; + } + } else { + new_tuple_fields = + hns3_rss_calc_tuple_filed(rss_conf->conf.types); + } + + ret = hns3_set_rss_tuple_field(hw, new_tuple_fields); + if (ret != 0) + return ret; + + hns3_info(hw, "RSS tuple fields changed from 0x%" PRIx64 " to 0x%" PRIx64, + old_tuple_fields, new_tuple_fields); + + return 0; +} + static int hns3_config_rss_filter(struct hns3_hw *hw, - const struct hns3_rss_conf *conf, bool add) + struct hns3_flow_rss_conf *rss_conf) { - struct hns3_rss_conf *rss_info; - uint64_t flow_types; - uint16_t num; - int ret; - - struct rte_flow_action_rss rss_flow_conf = { - .func = conf->conf.func, - .level = conf->conf.level, - .types = conf->conf.types, - .key_len = conf->conf.key_len, - .queue_num = conf->conf.queue_num, - .key = conf->conf.key_len ? - (void *)(uintptr_t)conf->conf.key : NULL, - .queue = conf->conf.queue, - }; - - /* Filter the unsupported flow types */ - flow_types = conf->conf.types ? - rss_flow_conf.types & HNS3_ETH_RSS_SUPPORT : - hw->rss_info.conf.types; - if (flow_types != rss_flow_conf.types) - hns3_warn(hw, "modified RSS types based on hardware support, " - "requested:0x%" PRIx64 " configured:0x%" PRIx64, - rss_flow_conf.types, flow_types); - /* Update the useful flow types */ - rss_flow_conf.types = flow_types; - - rss_info = &hw->rss_info; - if (!add) { - if (!conf->valid) - return 0; + struct rte_flow_action_rss *rss_act; + int ret; - ret = hns3_disable_rss(hw); + rss_act = &rss_conf->conf; + if (rss_act->queue_num > 0) { + ret = hns3_update_indir_table(hw, rss_act, rss_act->queue_num); if (ret) { - hns3_err(hw, "RSS disable failed(%d)", ret); + hns3_err(hw, "set queues action failed, ret = %d", ret); return ret; } + } - if (rss_flow_conf.queue_num) { - /* - * Due the content of queue pointer have been reset to - * 0, the rss_info->conf.queue should be set to NULL - */ - rss_info->conf.queue = NULL; - rss_info->conf.queue_num = 0; + if (rss_act->key_len > 0 || + rss_act->func != RTE_ETH_HASH_FUNCTION_DEFAULT) { + ret = hns3_update_rss_algo_key(hw, rss_act->func, rss_conf->key, + rss_act->key_len); + if (ret != 0) { + hns3_err(hw, "set func or hash key action failed, ret = %d", + ret); + return ret; } - - return 0; } - /* Set rx queues to use */ - num = RTE_MIN(hw->data->nb_rx_queues, rss_flow_conf.queue_num); - if (rss_flow_conf.queue_num > num) - hns3_warn(hw, "Config queue numbers %u are beyond the scope of truncated", - rss_flow_conf.queue_num); - hns3_info(hw, "Max of contiguous %u PF queues are configured", num); - if (num) { - ret = hns3_update_indir_table(hw, &rss_flow_conf, num); - if (ret) + if (rss_conf->hw_pctypes > 0) { + ret = hns3_flow_set_rss_ptype_tuple(hw, rss_conf); + if (ret != 0) { + hns3_err(hw, "set types action failed, ret = %d", ret); return ret; + } } - /* Set hash algorithm and flow types by the user's config */ - ret = hns3_hw_rss_hash_set(hw, &rss_flow_conf); - if (ret) - return ret; - - ret = hns3_rss_conf_copy(rss_info, &rss_flow_conf); - if (ret) - hns3_err(hw, "RSS config init fail(%d)", ret); - - return ret; + return 0; } static int @@ -1584,52 +1984,44 @@ struct hns3_adapter *hns = dev->data->dev_private; struct hns3_rss_conf_ele *rss_filter_ptr; struct hns3_hw *hw = &hns->hw; - int rss_rule_succ_cnt = 0; /* count for success of clearing RSS rules */ - int rss_rule_fail_cnt = 0; /* count for failure of clearing RSS rules */ - int ret = 0; rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); while (rss_filter_ptr) { TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); - ret = hns3_config_rss_filter(hw, &rss_filter_ptr->filter_info, - false); - if (ret) - rss_rule_fail_cnt++; - else - rss_rule_succ_cnt++; rte_free(rss_filter_ptr); rss_filter_ptr = TAILQ_FIRST(&hw->flow_rss_list); } - if (rss_rule_fail_cnt) { - hns3_err(hw, "fail to delete all RSS filters, success num = %d " - "fail num = %d", rss_rule_succ_cnt, - rss_rule_fail_cnt); - ret = -EIO; - } - - return ret; + return hns3_config_rss(hns); } static int -hns3_restore_rss_filter(struct hns3_hw *hw) +hns3_reconfig_all_rss_filter(struct hns3_hw *hw) { struct hns3_rss_conf_ele *filter; - int ret = 0; + uint32_t rule_no = 0; + int ret; - pthread_mutex_lock(&hw->flows_lock); TAILQ_FOREACH(filter, &hw->flow_rss_list, entries) { - if (!filter->filter_info.valid) - continue; - - ret = hns3_config_rss_filter(hw, &filter->filter_info, true); + ret = hns3_config_rss_filter(hw, &filter->filter_info); if (ret != 0) { - hns3_err(hw, "restore RSS filter failed, ret=%d", ret); - goto out; + hns3_err(hw, "config %uth RSS filter failed, ret = %d", + rule_no, ret); + return ret; } + rule_no++; } -out: + return 0; +} + +static int +hns3_restore_rss_filter(struct hns3_hw *hw) +{ + int ret; + + pthread_mutex_lock(&hw->flows_lock); + ret = hns3_reconfig_all_rss_filter(hw); pthread_mutex_unlock(&hw->flows_lock); return ret; @@ -1649,23 +2041,6 @@ } static int -hns3_flow_parse_rss(struct rte_eth_dev *dev, - const struct hns3_rss_conf *conf, bool add) -{ - struct hns3_adapter *hns = dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; - bool ret; - - ret = hns3_action_rss_same(&hw->rss_info.conf, &conf->conf); - if (ret) { - hns3_err(hw, "Enter duplicate RSS configuration : %d", ret); - return -EINVAL; - } - - return hns3_config_rss_filter(hw, conf, add); -} - -static int hns3_flow_args_check(const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], @@ -1698,31 +2073,55 @@ hns3_flow_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], const struct rte_flow_action actions[], - struct rte_flow_error *error) + struct rte_flow_error *error, + struct hns3_filter_info *filter_info) { - struct hns3_fdir_rule fdir_rule; + union hns3_filter_conf *conf; int ret; ret = hns3_flow_args_check(attr, pattern, actions, error); if (ret) return ret; - if (hns3_find_rss_general_action(pattern, actions)) - return hns3_parse_rss_filter(dev, actions, error); + hns3_parse_filter_type(pattern, actions, filter_info); + conf = &filter_info->conf; + if (filter_info->type == RTE_ETH_FILTER_HASH) + return hns3_parse_rss_filter(dev, pattern, actions, + &conf->rss_conf, error); - memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule)); - return hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error); + return hns3_parse_fdir_filter(dev, pattern, actions, + &conf->fdir_conf, error); +} + +static int +hns3_flow_rebuild_all_rss_filter(struct hns3_adapter *hns) +{ + struct hns3_hw *hw = &hns->hw; + int ret; + + ret = hns3_config_rss(hns); + if (ret != 0) { + hns3_err(hw, "restore original RSS configuration failed, ret = %d.", + ret); + return ret; + } + ret = hns3_reconfig_all_rss_filter(hw); + if (ret != 0) + hns3_err(hw, "rebuild all RSS filter failed, ret = %d.", ret); + + return ret; } static int hns3_flow_create_rss_rule(struct rte_eth_dev *dev, - const struct rte_flow_action *act, + struct hns3_flow_rss_conf *rss_conf, struct rte_flow *flow) { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_rss_conf_ele *rss_filter_ptr; - struct hns3_rss_conf_ele *filter_ptr; - const struct hns3_rss_conf *rss_conf; + struct hns3_flow_rss_conf *new_conf; + struct rte_flow_action_rss *rss_act; int ret; rss_filter_ptr = rte_zmalloc("hns3 rss filter", @@ -1732,28 +2131,29 @@ return -ENOMEM; } + new_conf = &rss_filter_ptr->filter_info; + memcpy(new_conf, rss_conf, sizeof(*new_conf)); + rss_act = &new_conf->conf; + if (rss_act->queue_num > 0) + new_conf->conf.queue = new_conf->queue; /* - * After all the preceding tasks are successfully configured, configure - * rules to the hardware to simplify the rollback of rules in the - * hardware. + * There are two ways to deliver hash key action: + * 1> 'key_len' is greater than zero and 'key' isn't NULL. + * 2> 'key_len' is greater than zero, but 'key' is NULL. + * For case 2, we need to keep 'key' of the new_conf is NULL so as to + * inherit the configuration from user in case of failing to verify + * duplicate rule later. */ - rss_conf = (const struct hns3_rss_conf *)act->conf; - ret = hns3_flow_parse_rss(dev, rss_conf, true); + if (rss_act->key_len > 0 && rss_act->key != NULL) + new_conf->conf.key = new_conf->key; + + ret = hns3_config_rss_filter(hw, new_conf); if (ret != 0) { rte_free(rss_filter_ptr); + (void)hns3_flow_rebuild_all_rss_filter(hns); return ret; } - hns3_rss_conf_copy(&rss_filter_ptr->filter_info, &rss_conf->conf); - rss_filter_ptr->filter_info.valid = true; - - /* - * When create a new RSS rule, the old rule will be overlaid and set - * invalid. - */ - TAILQ_FOREACH(filter_ptr, &hw->flow_rss_list, entries) - filter_ptr->filter_info.valid = false; - TAILQ_INSERT_TAIL(&hw->flow_rss_list, rss_filter_ptr, entries); flow->rule = rss_filter_ptr; flow->filter_type = RTE_ETH_FILTER_HASH; @@ -1763,29 +2163,22 @@ static int hns3_flow_create_fdir_rule(struct rte_eth_dev *dev, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], + struct hns3_fdir_rule *fdir_rule, struct rte_flow_error *error, struct rte_flow *flow) { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); struct hns3_fdir_rule_ele *fdir_rule_ptr; - struct hns3_fdir_rule fdir_rule; int ret; - memset(&fdir_rule, 0, sizeof(struct hns3_fdir_rule)); - ret = hns3_parse_fdir_filter(dev, pattern, actions, &fdir_rule, error); - if (ret != 0) - return ret; - - if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) { - ret = hns3_counter_new(dev, fdir_rule.act_cnt.shared, - fdir_rule.act_cnt.id, error); + if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER) { + ret = hns3_counter_new(dev, fdir_rule->act_cnt.shared, + fdir_rule->act_cnt.id, error); if (ret != 0) return ret; - flow->counter_id = fdir_rule.act_cnt.id; + flow->counter_id = fdir_rule->act_cnt.id; } fdir_rule_ptr = rte_zmalloc("hns3 fdir rule", @@ -1801,11 +2194,11 @@ * rules to the hardware to simplify the rollback of rules in the * hardware. */ - ret = hns3_fdir_filter_program(hns, &fdir_rule, false); + ret = hns3_fdir_filter_program(hns, fdir_rule, false); if (ret != 0) goto err_fdir_filter; - memcpy(&fdir_rule_ptr->fdir_conf, &fdir_rule, + memcpy(&fdir_rule_ptr->fdir_conf, fdir_rule, sizeof(struct hns3_fdir_rule)); TAILQ_INSERT_TAIL(&hw->flow_fdir_list, fdir_rule_ptr, entries); flow->rule = fdir_rule_ptr; @@ -1816,8 +2209,8 @@ err_fdir_filter: rte_free(fdir_rule_ptr); err_malloc: - if (fdir_rule.flags & HNS3_RULE_FLAG_COUNTER) - hns3_counter_release(dev, fdir_rule.act_cnt.id); + if (fdir_rule->flags & HNS3_RULE_FLAG_COUNTER) + hns3_counter_release(dev, fdir_rule->act_cnt.id); return ret; } @@ -1835,13 +2228,15 @@ struct rte_flow_error *error) { struct hns3_adapter *hns = dev->data->dev_private; - struct hns3_hw *hw = &hns->hw; + struct hns3_filter_info filter_info = {0}; struct hns3_flow_mem *flow_node; - const struct rte_flow_action *act; + struct hns3_hw *hw = &hns->hw; + union hns3_filter_conf *conf; struct rte_flow *flow; int ret; - ret = hns3_flow_validate(dev, attr, pattern, actions, error); + ret = hns3_flow_validate(dev, attr, pattern, actions, error, + &filter_info); if (ret) return NULL; @@ -1861,13 +2256,12 @@ } flow_node->flow = flow; + conf = &filter_info.conf; TAILQ_INSERT_TAIL(&hw->flow_list, flow_node, entries); - - act = hns3_find_rss_general_action(pattern, actions); - if (act) - ret = hns3_flow_create_rss_rule(dev, act, flow); + if (filter_info.type == RTE_ETH_FILTER_HASH) + ret = hns3_flow_create_rss_rule(dev, &conf->rss_conf, flow); else - ret = hns3_flow_create_fdir_rule(dev, pattern, actions, + ret = hns3_flow_create_fdir_rule(dev, &conf->fdir_conf, error, flow); if (ret == 0) return flow; @@ -1920,16 +2314,10 @@ break; case RTE_ETH_FILTER_HASH: rss_filter_ptr = (struct hns3_rss_conf_ele *)flow->rule; - ret = hns3_config_rss_filter(hw, &rss_filter_ptr->filter_info, - false); - if (ret) - return rte_flow_error_set(error, EIO, - RTE_FLOW_ERROR_TYPE_HANDLE, - flow, - "Destroy RSS fail.Try again"); TAILQ_REMOVE(&hw->flow_rss_list, rss_filter_ptr, entries); rte_free(rss_filter_ptr); rss_filter_ptr = NULL; + (void)hns3_flow_rebuild_all_rss_filter(hns); break; default: return rte_flow_error_set(error, EINVAL, @@ -2036,10 +2424,12 @@ struct rte_flow_error *error) { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct hns3_filter_info filter_info = {0}; int ret; pthread_mutex_lock(&hw->flows_lock); - ret = hns3_flow_validate(dev, attr, pattern, actions, error); + ret = hns3_flow_validate(dev, attr, pattern, actions, error, + &filter_info); pthread_mutex_unlock(&hw->flows_lock); return ret; diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_mp.c dpdk-20.11.8/drivers/net/hns3/hns3_mp.c --- dpdk-20.11.7/drivers/net/hns3/hns3_mp.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_mp.c 2023-04-27 17:57:22.000000000 +0000 @@ -87,7 +87,7 @@ case HNS3_MP_REQ_START_RXTX: PMD_INIT_LOG(INFO, "port %u starting datapath", dev->data->port_id); - hns3_set_rxtx_function(dev); + hns3_start_rxtx_datapath(dev); rte_mb(); mp_init_msg(dev, &mp_res, param->type); res->result = 0; @@ -96,7 +96,7 @@ case HNS3_MP_REQ_STOP_RXTX: PMD_INIT_LOG(INFO, "port %u stopping datapath", dev->data->port_id); - hns3_set_rxtx_function(dev); + hns3_stop_rxtx_datapath(dev); rte_mb(); mp_init_msg(dev, &mp_res, param->type); res->result = 0; diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_rss.c dpdk-20.11.8/drivers/net/hns3/hns3_rss.c --- dpdk-20.11.7/drivers/net/hns3/hns3_rss.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_rss.c 2023-04-27 17:57:22.000000000 +0000 @@ -18,56 +18,11 @@ 0x6A, 0x42, 0xB7, 0x3B, 0xBE, 0xAC, 0x01, 0xFA }; -enum hns3_tuple_field { - /* IPV4_TCP ENABLE FIELD */ - HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, - HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, - HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, - HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, - - /* IPV4_UDP ENABLE FIELD */ - HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, - HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, - HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, - HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, - - /* IPV4_SCTP ENABLE FIELD */ - HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, - HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, - HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, - HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, - HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, - - /* IPV4 ENABLE FIELD */ - HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, - HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, - HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, - HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, - - /* IPV6_TCP ENABLE FIELD */ - HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, - HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, - HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, - HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, - - /* IPV6_UDP ENABLE FIELD */ - HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, - HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, - HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, - HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, - - /* IPV6_SCTP ENABLE FIELD */ - HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48, - HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S, - HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D, - HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, - HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, - - /* IPV6 ENABLE FIELD */ - HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, - HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, - HNS3_RSS_FIELD_IPV6_FRAG_IP_D, - HNS3_RSS_FIELD_IPV6_FRAG_IP_S +const uint8_t hns3_hash_func_map[] = { + [RTE_ETH_HASH_FUNCTION_DEFAULT] = HNS3_RSS_HASH_ALGO_TOEPLITZ, + [RTE_ETH_HASH_FUNCTION_TOEPLITZ] = HNS3_RSS_HASH_ALGO_TOEPLITZ, + [RTE_ETH_HASH_FUNCTION_SIMPLE_XOR] = HNS3_RSS_HASH_ALGO_SIMPLE, + [RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ] = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP, }; enum hns3_rss_tuple_type { @@ -79,243 +34,285 @@ uint64_t rss_types; uint16_t tuple_type; uint64_t rss_field; + uint64_t tuple_mask; } hns3_set_tuple_table[] = { /* IPV4-FRAG */ { ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S), + HNS3_RSS_TUPLE_IPV4_FLAG_M }, { ETH_RSS_FRAG_IPV4 | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D), + HNS3_RSS_TUPLE_IPV4_FLAG_M }, { ETH_RSS_FRAG_IPV4, HNS3_RSS_IP_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D), + HNS3_RSS_TUPLE_IPV4_FLAG_M }, /* IPV4 */ { ETH_RSS_IPV4 | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S), + HNS3_RSS_TUPLE_IPV4_NONF_M }, { ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV4_NONF_M }, { ETH_RSS_IPV4, HNS3_RSS_IP_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV4_NONF_M }, /* IPV4-OTHER */ { ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S), + HNS3_RSS_TUPLE_IPV4_NONF_M }, { ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV4_NONF_M }, { ETH_RSS_NONFRAG_IPV4_OTHER, HNS3_RSS_IP_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV4_NONF_M }, /* IPV4-TCP */ { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S), + HNS3_RSS_TUPLE_IPV4_TCP_M }, { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D), + HNS3_RSS_TUPLE_IPV4_TCP_M }, { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S), + HNS3_RSS_TUPLE_IPV4_TCP_M }, { ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D), + HNS3_RSS_TUPLE_IPV4_TCP_M }, { ETH_RSS_NONFRAG_IPV4_TCP, HNS3_RSS_IP_L4_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D), + HNS3_RSS_TUPLE_IPV4_TCP_M }, /* IPV4-UDP */ { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S), + HNS3_RSS_TUPLE_IPV4_UDP_M }, { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D), + HNS3_RSS_TUPLE_IPV4_UDP_M }, { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S), + HNS3_RSS_TUPLE_IPV4_UDP_M }, { ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D), + HNS3_RSS_TUPLE_IPV4_UDP_M }, { ETH_RSS_NONFRAG_IPV4_UDP, HNS3_RSS_IP_L4_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D), + HNS3_RSS_TUPLE_IPV4_UDP_M }, /* IPV4-SCTP */ { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S), + HNS3_RSS_TUPLE_IPV4_SCTP_M }, { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D), + HNS3_RSS_TUPLE_IPV4_SCTP_M }, { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S), + HNS3_RSS_TUPLE_IPV4_SCTP_M }, { ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D), + HNS3_RSS_TUPLE_IPV4_SCTP_M }, { ETH_RSS_NONFRAG_IPV4_SCTP, HNS3_RSS_IP_L4_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D) | - BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER) }, + BIT_ULL(HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER), + HNS3_RSS_TUPLE_IPV4_SCTP_M }, /* IPV6-FRAG */ { ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S), + HNS3_RSS_TUPLE_IPV6_FLAG_M }, { ETH_RSS_FRAG_IPV6 | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D), + HNS3_RSS_TUPLE_IPV6_FLAG_M }, { ETH_RSS_FRAG_IPV6, HNS3_RSS_IP_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_FRAG_IP_D), + HNS3_RSS_TUPLE_IPV6_FLAG_M }, /* IPV6 */ { ETH_RSS_IPV6 | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S), + HNS3_RSS_TUPLE_IPV6_NONF_M }, { ETH_RSS_IPV6 | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV6_NONF_M }, { ETH_RSS_IPV6, HNS3_RSS_IP_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV6_NONF_M }, /* IPV6-OTHER */ { ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S), + HNS3_RSS_TUPLE_IPV6_NONF_M }, { ETH_RSS_NONFRAG_IPV6_OTHER | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV6_NONF_M }, { ETH_RSS_NONFRAG_IPV6_OTHER, HNS3_RSS_IP_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D), + HNS3_RSS_TUPLE_IPV6_NONF_M }, /* IPV6-TCP */ { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S), + HNS3_RSS_TUPLE_IPV6_TCP_M }, { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D), + HNS3_RSS_TUPLE_IPV6_TCP_M }, { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S), + HNS3_RSS_TUPLE_IPV6_TCP_M }, { ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D), + HNS3_RSS_TUPLE_IPV6_TCP_M }, { ETH_RSS_NONFRAG_IPV6_TCP, HNS3_RSS_IP_L4_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D), + HNS3_RSS_TUPLE_IPV6_TCP_M }, /* IPV6-UDP */ { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S), + HNS3_RSS_TUPLE_IPV6_UDP_M }, { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D), + HNS3_RSS_TUPLE_IPV6_UDP_M }, { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S), + HNS3_RSS_TUPLE_IPV6_UDP_M }, { ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D), + HNS3_RSS_TUPLE_IPV6_UDP_M }, { ETH_RSS_NONFRAG_IPV6_UDP, HNS3_RSS_IP_L4_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D), + HNS3_RSS_TUPLE_IPV6_UDP_M }, /* IPV6-SCTP */ { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S), + HNS3_RSS_TUPLE_IPV6_SCTP_M }, { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D), + HNS3_RSS_TUPLE_IPV6_SCTP_M }, { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_SRC_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S), + HNS3_RSS_TUPLE_IPV6_SCTP_M }, { ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_DST_ONLY, HNS3_RSS_IP_L4_TUPLE, - BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D), + HNS3_RSS_TUPLE_IPV6_SCTP_M }, { ETH_RSS_NONFRAG_IPV6_SCTP, HNS3_RSS_IP_L4_TUPLE, BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S) | BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) | BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S) | - BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER) }, + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER), + HNS3_RSS_TUPLE_IPV6_SCTP_M }, }; /* * rss_generic_config command function, opcode:0x0D01. - * Used to set algorithm, key_offset and hash key of rss. + * Used to set algorithm and hash key of RSS. */ int -hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key) +hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + const uint8_t *key, uint8_t key_len) { -#define HNS3_KEY_OFFSET_MAX 3 -#define HNS3_SET_HASH_KEY_BYTE_FOUR 2 - struct hns3_rss_generic_config_cmd *req; struct hns3_cmd_desc desc; - uint32_t key_offset, key_size; - const uint8_t *key_cur; - uint8_t cur_offset; + const uint8_t *cur_key; + uint16_t cur_key_size; + uint16_t max_bd_num; + uint16_t idx; int ret; req = (struct hns3_rss_generic_config_cmd *)desc.data; - /* - * key_offset=0, hash key byte0~15 is set to hardware. - * key_offset=1, hash key byte16~31 is set to hardware. - * key_offset=2, hash key byte32~39 is set to hardware. - */ - for (key_offset = 0; key_offset < HNS3_KEY_OFFSET_MAX; key_offset++) { + max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM); + for (idx = 0; idx < max_bd_num; idx++) { hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, false); - req->hash_config |= - (hw->rss_info.hash_algo & HNS3_RSS_HASH_ALGO_MASK); - req->hash_config |= (key_offset << HNS3_RSS_HASH_KEY_OFFSET_B); - - if (key_offset == HNS3_SET_HASH_KEY_BYTE_FOUR) - key_size = HNS3_RSS_KEY_SIZE - HNS3_RSS_HASH_KEY_NUM * - HNS3_SET_HASH_KEY_BYTE_FOUR; + req->hash_config |= (hash_algo & HNS3_RSS_HASH_ALGO_MASK); + req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); + + if (idx == max_bd_num - 1 && + (key_len % HNS3_RSS_HASH_KEY_NUM) != 0) + cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; else - key_size = HNS3_RSS_HASH_KEY_NUM; + cur_key_size = HNS3_RSS_HASH_KEY_NUM; - cur_offset = key_offset * HNS3_RSS_HASH_KEY_NUM; - key_cur = key + cur_offset; - memcpy(req->hash_key, key_cur, key_size); + cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM; + memcpy(req->hash_key, cur_key, cur_key_size); ret = hns3_cmd_send(hw, &desc, 1); if (ret) { @@ -323,8 +320,49 @@ return ret; } } - /* Update the shadow RSS key with user specified */ - memcpy(hw->rss_info.key, key, HNS3_RSS_KEY_SIZE); + + return 0; +} + +int +hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, + uint8_t *key, uint8_t key_len) +{ + struct hns3_rss_generic_config_cmd *req; + struct hns3_cmd_desc desc; + uint16_t cur_key_size; + uint16_t max_bd_num; + uint8_t *cur_key; + uint16_t idx; + int ret; + + req = (struct hns3_rss_generic_config_cmd *)desc.data; + max_bd_num = DIV_ROUND_UP(key_len, HNS3_RSS_HASH_KEY_NUM); + for (idx = 0; idx < max_bd_num; idx++) { + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_GENERIC_CONFIG, + true); + + req->hash_config |= (idx << HNS3_RSS_HASH_KEY_OFFSET_B); + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { + hns3_err(hw, "fail to obtain RSS algo and key from firmware, ret = %d", + ret); + return ret; + } + + if (idx == 0) + *hash_algo = req->hash_config & HNS3_RSS_HASH_ALGO_MASK; + + if (idx == max_bd_num - 1 && + (key_len % HNS3_RSS_HASH_KEY_NUM) != 0) + cur_key_size = key_len % HNS3_RSS_HASH_KEY_NUM; + else + cur_key_size = HNS3_RSS_HASH_KEY_NUM; + + cur_key = key + idx * HNS3_RSS_HASH_KEY_NUM; + memcpy(cur_key, req->hash_key, cur_key_size); + } + return 0; } @@ -336,6 +374,7 @@ hns3_set_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) { struct hns3_rss_indirection_table_cmd *req; + uint16_t max_bd_num, cfg_tbl_size; struct hns3_cmd_desc desc; uint8_t qid_msb_off; uint8_t qid_msb_val; @@ -344,14 +383,20 @@ int ret; req = (struct hns3_rss_indirection_table_cmd *)desc.data; - - for (i = 0; i < size / HNS3_RSS_CFG_TBL_SIZE; i++) { + max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE); + for (i = 0; i < max_bd_num; i++) { hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, false); req->start_table_index = rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); req->rss_set_bitmap = rte_cpu_to_le_16(HNS3_RSS_SET_BITMAP_MSK); - for (j = 0; j < HNS3_RSS_CFG_TBL_SIZE; j++) { + + if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0) + cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE; + else + cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE; + + for (j = 0; j < cfg_tbl_size; j++) { q_id = indir[i * HNS3_RSS_CFG_TBL_SIZE + j]; req->rss_result_l[j] = q_id & 0xff; @@ -372,9 +417,53 @@ } } - /* Update redirection table of hw */ - memcpy(hw->rss_info.rss_indirection_tbl, indir, - sizeof(uint16_t) * size); + return 0; +} + +static int +hns3_get_rss_indir_table(struct hns3_hw *hw, uint16_t *indir, uint16_t size) +{ + struct hns3_rss_indirection_table_cmd *req; + uint16_t max_bd_num, cfg_tbl_size; + uint8_t qid_msb_off, qid_msb_idx; + struct hns3_cmd_desc desc; + uint16_t q_id, q_hi, q_lo; + uint8_t rss_result_h; + uint16_t i, j; + int ret; + + req = (struct hns3_rss_indirection_table_cmd *)desc.data; + max_bd_num = DIV_ROUND_UP(size, HNS3_RSS_CFG_TBL_SIZE); + for (i = 0; i < max_bd_num; i++) { + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INDIR_TABLE, + true); + req->start_table_index = + rte_cpu_to_le_16(i * HNS3_RSS_CFG_TBL_SIZE); + ret = hns3_cmd_send(hw, &desc, 1); + if (ret) { + hns3_err(hw, "fail to get RSS indirection table from firmware, ret = %d", + ret); + return ret; + } + + if (i == max_bd_num - 1 && (size % HNS3_RSS_CFG_TBL_SIZE) != 0) + cfg_tbl_size = size % HNS3_RSS_CFG_TBL_SIZE; + else + cfg_tbl_size = HNS3_RSS_CFG_TBL_SIZE; + + for (j = 0; j < cfg_tbl_size; j++) { + qid_msb_idx = + j * HNS3_RSS_CFG_TBL_BW_H / HNS3_BITS_PER_BYTE; + rss_result_h = req->rss_result_h[qid_msb_idx]; + qid_msb_off = + j * HNS3_RSS_CFG_TBL_BW_H % HNS3_BITS_PER_BYTE; + q_hi = (rss_result_h >> qid_msb_off) & + HNS3_RSS_CFG_TBL_BW_H_M; + q_lo = req->rss_result_l[j]; + q_id = (q_hi << HNS3_RSS_CFG_TBL_BW_L) | q_lo; + indir[i * HNS3_RSS_CFG_TBL_SIZE + j] = q_id; + } + } return 0; } @@ -393,41 +482,72 @@ } ret = hns3_set_rss_indir_table(hw, lut, hw->rss_ind_tbl_size); - if (ret) - hns3_err(hw, "RSS uninit indir table failed: %d", ret); + if (ret != 0) + hns3_err(hw, "RSS uninit indir table failed, ret = %d.", ret); + else + memcpy(hw->rss_info.rss_indirection_tbl, lut, + sizeof(uint16_t) * hw->rss_ind_tbl_size); rte_free(lut); return ret; } -static void -hns3_rss_check_l3l4_types(struct hns3_hw *hw, uint64_t rss_hf) +bool +hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types) { uint64_t ip_mask = ETH_RSS_IPV4 | ETH_RSS_FRAG_IPV4 | ETH_RSS_NONFRAG_IPV4_OTHER | ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 | ETH_RSS_NONFRAG_IPV6_OTHER; - uint64_t l4_mask = ETH_RSS_NONFRAG_IPV4_TCP | + uint64_t ip_l4_mask = ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_NONFRAG_IPV6_SCTP; - uint64_t l3_src_dst_mask = ETH_RSS_L3_SRC_ONLY | - ETH_RSS_L3_DST_ONLY; - uint64_t l4_src_dst_mask = ETH_RSS_L4_SRC_ONLY | - ETH_RSS_L4_DST_ONLY; - - if (rss_hf & l3_src_dst_mask && - !(rss_hf & ip_mask || rss_hf & l4_mask)) - hns3_warn(hw, "packet type isn't specified, L3_SRC/DST_ONLY is ignored."); + bool has_l4_src_dst = !!(types & HNS3_RSS_SUPPORT_L4_SRC_DST); + bool has_ip_pkt = !!(types & ip_mask); + uint64_t final_types; + + if (types == 0) + return true; + + if ((types & HNS3_ETH_RSS_SUPPORT) == 0) { + hns3_err(hw, "specified types(0x%" PRIx64 ") are unsupported.", + types); + return false; + } + + if ((types & HNS3_RSS_SUPPORT_L3_SRC_DST) != 0 && + (types & HNS3_RSS_SUPPORT_FLOW_TYPE) == 0) { + hns3_err(hw, "IP or IP-TCP/UDP/SCTP packet type isn't specified, L3_SRC/DST_ONLY cannot be set."); + return false; + } + + if (has_l4_src_dst && (types & ip_l4_mask) == 0) { + if (!has_ip_pkt) { + hns3_err(hw, "IP-TCP/UDP/SCTP packet type isn't specified, L4_SRC/DST_ONLY cannot be set."); + return false; + } + /* + * For the case that the types has L4_SRC/DST_ONLY but hasn't + * IP-TCP/UDP/SCTP packet type, this types is considered valid + * if it also has IP packet type. + */ + hns3_warn(hw, "L4_SRC/DST_ONLY is ignored because of no including L4 packet."); + } - if (rss_hf & l4_src_dst_mask && !(rss_hf & l4_mask)) - hns3_warn(hw, "packet type isn't specified, L4_SRC/DST_ONLY is ignored."); + if ((types & ~HNS3_ETH_RSS_SUPPORT) != 0) { + final_types = types & HNS3_ETH_RSS_SUPPORT; + hns3_warn(hw, "set RSS types based on hardware support, requested:0x%" PRIx64 " configured:0x%" PRIx64 "", + types, final_types); + } + + return true; } -static uint64_t -hns3_rss_calc_tuple_filed(struct hns3_hw *hw, uint64_t rss_hf) +uint64_t +hns3_rss_calc_tuple_filed(uint64_t rss_hf) { uint64_t l3_only_mask = ETH_RSS_L3_SRC_ONLY | ETH_RSS_L3_DST_ONLY; @@ -456,34 +576,40 @@ !has_l3_l4_only) tuple |= hns3_set_tuple_table[i].rss_field; } - hns3_rss_check_l3l4_types(hw, rss_hf); return tuple; } int -hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) +hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields) { struct hns3_rss_input_tuple_cmd *req; struct hns3_cmd_desc desc; - uint64_t tuple_field; int ret; hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, false); req = (struct hns3_rss_input_tuple_cmd *)desc.data; - - tuple_field = hns3_rss_calc_tuple_filed(hw, rss_hf); - req->tuple_field = rte_cpu_to_le_64(tuple_field); + req->tuple_field = rte_cpu_to_le_64(tuple_fields); ret = hns3_cmd_send(hw, &desc, 1); - if (ret) { - hns3_err(hw, "Update RSS flow types tuples failed %d", ret); - return ret; - } + if (ret != 0) + hns3_err(hw, "set RSS hash tuple fields failed ret = %d", ret); - /* Update supported flow types when set tuple success */ - hw->rss_info.conf.types = rss_hf; + return ret; +} - return 0; +int +hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf) +{ + uint64_t tuple_fields; + int ret; + + tuple_fields = hns3_rss_calc_tuple_filed(rss_hf); + ret = hns3_set_rss_tuple_field(hw, tuple_fields); + if (ret != 0) + hns3_err(hw, "Update RSS flow types tuples failed, ret = %d", + ret); + + return ret; } /* @@ -500,28 +626,35 @@ struct rte_eth_rss_conf *rss_conf) { struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint64_t rss_hf_bk = hw->rss_info.conf.types; + uint64_t rss_hf_bk = hw->rss_info.rss_hf; uint8_t key_len = rss_conf->rss_key_len; uint64_t rss_hf = rss_conf->rss_hf; uint8_t *key = rss_conf->rss_key; int ret; - if (key && key_len != HNS3_RSS_KEY_SIZE) { + if (key && key_len != hw->rss_key_size) { hns3_err(hw, "the hash key len(%u) is invalid, must be %u", - key_len, HNS3_RSS_KEY_SIZE); + key_len, hw->rss_key_size); return -EINVAL; } + if (!hns3_check_rss_types_valid(hw, rss_hf)) + return -EINVAL; + rte_spinlock_lock(&hw->lock); ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); if (ret) goto set_tuple_fail; if (key) { - ret = hns3_set_rss_algo_key(hw, key); + ret = hns3_set_rss_algo_key(hw, hw->rss_info.hash_algo, + key, hw->rss_key_size); if (ret) goto set_algo_key_fail; + /* Update the shadow RSS key with user specified */ + memcpy(hw->rss_info.key, key, hw->rss_key_size); } + hw->rss_info.rss_hf = rss_hf; rte_spinlock_unlock(&hw->lock); return 0; @@ -533,6 +666,96 @@ return ret; } +int +hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields) +{ + struct hns3_rss_input_tuple_cmd *req; + struct hns3_cmd_desc desc; + int ret; + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_RSS_INPUT_TUPLE, true); + req = (struct hns3_rss_input_tuple_cmd *)desc.data; + ret = hns3_cmd_send(hw, &desc, 1); + if (ret != 0) { + hns3_err(hw, "fail to get RSS hash tuple fields from firmware, ret = %d", + ret); + return ret; + } + + *tuple_fields = rte_le_to_cpu_64(req->tuple_field); + + return 0; +} + +static uint64_t +hns3_rss_tuple_fields_to_rss_hf(struct hns3_hw *hw, uint64_t tuple_fields) +{ + uint64_t ipv6_sctp_l4_mask = + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D) | + BIT_ULL(HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S); + uint64_t rss_hf = 0; + uint64_t tuple_mask; + uint32_t i; + + for (i = 0; i < RTE_DIM(hns3_set_tuple_table); i++) { + tuple_mask = hns3_set_tuple_table[i].tuple_mask; + /* + * The RSS hash of the packet type is disabled if its tuples is + * zero. + */ + if ((tuple_fields & tuple_mask) == 0) + continue; + + /* + * Some hardware don't support to use src/dst port fields to + * hash for IPV6-SCTP packet. + */ + if ((hns3_set_tuple_table[i].rss_types & + ETH_RSS_NONFRAG_IPV6_SCTP) && + !hw->rss_info.ipv6_sctp_offload_supported) + tuple_mask &= ~ipv6_sctp_l4_mask; + + /* + * The framework (ethdev ops) or driver (rte flow API) ensure + * that both L3_SRC/DST_ONLY and L4_SRC/DST_ONLY cannot be set + * to driver at the same time. But if user doesn't specify + * anything L3/L4_SRC/DST_ONLY, driver enables all tuple fields. + * In this case, driver should not report L3/L4_SRC/DST_ONLY. + */ + if ((tuple_fields & tuple_mask) == tuple_mask) { + /* Skip the item enabled part tuples. */ + if ((tuple_fields & hns3_set_tuple_table[i].rss_field) != + tuple_mask) + continue; + + rss_hf |= hns3_set_tuple_table[i].rss_types; + continue; + } + + /* Match the item enabled part tuples.*/ + if ((tuple_fields & hns3_set_tuple_table[i].rss_field) == + hns3_set_tuple_table[i].rss_field) + rss_hf |= hns3_set_tuple_table[i].rss_types; + } + + return rss_hf; +} + +static int +hns3_rss_hash_get_rss_hf(struct hns3_hw *hw, uint64_t *rss_hf) +{ + uint64_t tuple_fields; + int ret; + + ret = hns3_get_rss_tuple_field(hw, &tuple_fields); + if (ret != 0) + return ret; + + *rss_hf = hns3_rss_tuple_fields_to_rss_hf(hw, tuple_fields); + + return 0; +} + /* * Get rss key and rss_hf types set of RSS hash configuration. * @param dev @@ -548,19 +771,32 @@ { struct hns3_adapter *hns = dev->data->dev_private; struct hns3_hw *hw = &hns->hw; - struct hns3_rss_conf *rss_cfg = &hw->rss_info; + uint8_t hash_algo; + int ret; rte_spinlock_lock(&hw->lock); - rss_conf->rss_hf = rss_cfg->conf.types; + ret = hns3_rss_hash_get_rss_hf(hw, &rss_conf->rss_hf); + if (ret != 0) { + hns3_err(hw, "obtain hash tuples failed, ret = %d", ret); + goto out; + } /* Get the RSS Key required by the user */ - if (rss_conf->rss_key && rss_conf->rss_key_len >= HNS3_RSS_KEY_SIZE) { - memcpy(rss_conf->rss_key, rss_cfg->key, HNS3_RSS_KEY_SIZE); - rss_conf->rss_key_len = HNS3_RSS_KEY_SIZE; + if (rss_conf->rss_key && rss_conf->rss_key_len >= hw->rss_key_size) { + ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_conf->rss_key, + hw->rss_key_size); + if (ret != 0) { + hns3_err(hw, "obtain hash algo and key failed, ret = %d", + ret); + goto out; + } + rss_conf->rss_key_len = hw->rss_key_size; } + +out: rte_spinlock_unlock(&hw->lock); - return 0; + return ret; } /* @@ -600,12 +836,12 @@ idx = i / RTE_RETA_GROUP_SIZE; shift = i % RTE_RETA_GROUP_SIZE; if (reta_conf[idx].reta[shift] >= hw->alloc_rss_size) { - rte_spinlock_unlock(&hw->lock); hns3_err(hw, "queue id(%u) set to redirection table " "exceeds queue number(%u) allocated to a TC", reta_conf[idx].reta[shift], hw->alloc_rss_size); - return -EINVAL; + ret = -EINVAL; + goto out; } if (reta_conf[idx].mask & (1ULL << shift)) @@ -614,7 +850,13 @@ ret = hns3_set_rss_indir_table(hw, indirection_tbl, hw->rss_ind_tbl_size); + if (ret != 0) + goto out; + + memcpy(rss_cfg->rss_indirection_tbl, indirection_tbl, + sizeof(uint16_t) * hw->rss_ind_tbl_size); +out: rte_spinlock_unlock(&hw->lock); return ret; } @@ -636,10 +878,11 @@ uint16_t reta_size) { struct hns3_adapter *hns = dev->data->dev_private; + uint16_t reta_table[HNS3_RSS_IND_TBL_SIZE_MAX]; struct hns3_hw *hw = &hns->hw; - struct hns3_rss_conf *rss_cfg = &hw->rss_info; uint16_t idx, shift; uint16_t i; + int ret; if (reta_size != hw->rss_ind_tbl_size) { hns3_err(hw, "The size of hash lookup table configured (%u)" @@ -648,14 +891,22 @@ return -EINVAL; } rte_spinlock_lock(&hw->lock); + ret = hns3_get_rss_indir_table(hw, reta_table, reta_size); + if (ret != 0) { + rte_spinlock_unlock(&hw->lock); + hns3_err(hw, "query RSS redirection table failed, ret = %d.", + ret); + return ret; + } + rte_spinlock_unlock(&hw->lock); + for (i = 0; i < reta_size; i++) { idx = i / RTE_RETA_GROUP_SIZE; shift = i % RTE_RETA_GROUP_SIZE; if (reta_conf[idx].mask & (1ULL << shift)) - reta_conf[idx].reta[shift] = - rss_cfg->rss_indirection_tbl[i]; + reta_conf[idx].reta[shift] = reta_table[i]; } - rte_spinlock_unlock(&hw->lock); + return 0; } @@ -733,6 +984,52 @@ return ret; } +/* + * Note: the 'hash_algo' is defined by enum rte_eth_hash_function. + */ +int +hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_func, + uint8_t *key, uint8_t key_len) +{ + uint8_t rss_key[HNS3_RSS_KEY_SIZE_MAX] = {0}; + bool modify_key, modify_algo; + uint8_t hash_algo; + int ret; + + modify_key = (key != NULL && key_len > 0); + modify_algo = hash_func != RTE_ETH_HASH_FUNCTION_DEFAULT; + if (!modify_key && !modify_algo) + return 0; + + if (modify_algo && hash_func >= RTE_DIM(hns3_hash_func_map)) { + hns3_err(hw, "hash func (%u) is unsupported.", hash_func); + return -ENOTSUP; + } + if (modify_key && key_len != hw->rss_key_size) { + hns3_err(hw, "hash key length (%u) is invalid.", key_len); + return -EINVAL; + } + + ret = hns3_rss_get_algo_key(hw, &hash_algo, rss_key, hw->rss_key_size); + if (ret != 0) { + hns3_err(hw, "fail to get RSS hash algorithm and key, ret = %d", + ret); + return ret; + } + + if (modify_algo) + hash_algo = hns3_hash_func_map[hash_func]; + if (modify_key) + memcpy(rss_key, key, key_len); + + ret = hns3_set_rss_algo_key(hw, hash_algo, rss_key, hw->rss_key_size); + if (ret != 0) + hns3_err(hw, "fail to set RSS hash algorithm and key, ret = %d", + ret); + + return ret; +} + static void hns3_rss_tuple_uninit(struct hns3_hw *hw) { @@ -764,10 +1061,11 @@ int i; /* Default hash algorithm */ - rss_cfg->conf.func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; + rss_cfg->hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; - /* Default RSS key */ - memcpy(rss_cfg->key, hns3_hash_key, HNS3_RSS_KEY_SIZE); + hw->rss_info.rss_hf = 0; + memcpy(rss_cfg->key, hns3_hash_key, + RTE_MIN(sizeof(hns3_hash_key), hw->rss_key_size)); /* Initialize RSS indirection table */ for (i = 0; i < hw->rss_ind_tbl_size; i++) @@ -788,20 +1086,8 @@ enum rte_eth_rx_mq_mode mq_mode = hw->data->dev_conf.rxmode.mq_mode; - switch (hw->rss_info.conf.func) { - case RTE_ETH_HASH_FUNCTION_SIMPLE_XOR: - hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SIMPLE; - break; - case RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ: - hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_SYMMETRIC_TOEP; - break; - default: - hw->rss_info.hash_algo = HNS3_RSS_HASH_ALGO_TOEPLITZ; - break; - } - - /* Configure RSS hash algorithm and hash key offset */ - ret = hns3_set_rss_algo_key(hw, hash_key); + ret = hns3_set_rss_algo_key(hw, rss_cfg->hash_algo, + hash_key, hw->rss_key_size); if (ret) return ret; @@ -815,15 +1101,22 @@ return ret; /* - * When muli-queue RSS mode flag is not set or unsupported tuples are + * When multi-queue RSS mode flag is not set or unsupported tuples are * set, disable all tuples. */ - rss_hf = hw->rss_info.conf.types; + rss_hf = hw->rss_info.rss_hf; if (!((uint32_t)mq_mode & ETH_MQ_RX_RSS_FLAG) || !(rss_hf & HNS3_ETH_RSS_SUPPORT)) rss_hf = 0; - return hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); + ret = hns3_set_rss_tuple_by_rss_hf(hw, rss_hf); + if (ret != 0) { + hns3_err(hw, "set RSS tuples failed, ret = %d.", ret); + return ret; + } + hw->rss_info.rss_hf = rss_hf; + + return 0; } /* @@ -841,5 +1134,5 @@ return; /* Disable RSS */ - hw->rss_info.conf.types = 0; + hw->rss_info.rss_hf = 0; } diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_rss.h dpdk-20.11.8/drivers/net/hns3/hns3_rss.h --- dpdk-20.11.7/drivers/net/hns3/hns3_rss.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_rss.h 2023-04-27 17:57:22.000000000 +0000 @@ -8,27 +8,107 @@ #include #include -#define HNS3_ETH_RSS_SUPPORT ( \ - ETH_RSS_IPV4 | \ - ETH_RSS_FRAG_IPV4 | \ - ETH_RSS_NONFRAG_IPV4_TCP | \ - ETH_RSS_NONFRAG_IPV4_UDP | \ - ETH_RSS_NONFRAG_IPV4_SCTP | \ - ETH_RSS_NONFRAG_IPV4_OTHER | \ - ETH_RSS_IPV6 | \ - ETH_RSS_FRAG_IPV6 | \ - ETH_RSS_NONFRAG_IPV6_TCP | \ - ETH_RSS_NONFRAG_IPV6_UDP | \ - ETH_RSS_NONFRAG_IPV6_SCTP | \ - ETH_RSS_NONFRAG_IPV6_OTHER | \ - ETH_RSS_L3_SRC_ONLY | \ - ETH_RSS_L3_DST_ONLY | \ - ETH_RSS_L4_SRC_ONLY | \ - ETH_RSS_L4_DST_ONLY) +#define HNS3_RSS_SUPPORT_L3_SRC_DST (ETH_RSS_L3_SRC_ONLY | \ + ETH_RSS_L3_DST_ONLY) +#define HNS3_RSS_SUPPORT_L4_SRC_DST (ETH_RSS_L4_SRC_ONLY | \ + ETH_RSS_L4_DST_ONLY) +#define HNS3_RSS_SUPPORT_L3L4 (HNS3_RSS_SUPPORT_L3_SRC_DST | \ + HNS3_RSS_SUPPORT_L4_SRC_DST) + +#define HNS3_RSS_SUPPORT_FLOW_TYPE (ETH_RSS_IPV4 | \ + ETH_RSS_FRAG_IPV4 | \ + ETH_RSS_NONFRAG_IPV4_TCP | \ + ETH_RSS_NONFRAG_IPV4_UDP | \ + ETH_RSS_NONFRAG_IPV4_SCTP | \ + ETH_RSS_NONFRAG_IPV4_OTHER | \ + ETH_RSS_IPV6 | \ + ETH_RSS_FRAG_IPV6 | \ + ETH_RSS_NONFRAG_IPV6_TCP | \ + ETH_RSS_NONFRAG_IPV6_UDP | \ + ETH_RSS_NONFRAG_IPV6_SCTP | \ + ETH_RSS_NONFRAG_IPV6_OTHER) + +#define HNS3_ETH_RSS_SUPPORT (HNS3_RSS_SUPPORT_FLOW_TYPE | \ + HNS3_RSS_SUPPORT_L3L4) + +enum hns3_tuple_field { + /* IPV4_TCP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_D = 0, + HNS3_RSS_FIELD_IPV4_TCP_EN_TCP_S, + HNS3_RSS_FIELD_IPV4_TCP_EN_IP_D, + HNS3_RSS_FIELD_IPV4_TCP_EN_IP_S, + + /* IPV4_UDP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_D = 8, + HNS3_RSS_FIELD_IPV4_UDP_EN_UDP_S, + HNS3_RSS_FIELD_IPV4_UDP_EN_IP_D, + HNS3_RSS_FIELD_IPV4_UDP_EN_IP_S, + + /* IPV4_SCTP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_D = 16, + HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_S, + HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_D, + HNS3_RSS_FIELD_IPV4_SCTP_EN_IP_S, + HNS3_RSS_FIELD_IPV4_SCTP_EN_SCTP_VER, + + /* IPV4 ENABLE FIELD */ + HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_D = 24, + HNS3_RSS_FIELD_IPV4_EN_NONFRAG_IP_S, + HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_D, + HNS3_RSS_FIELD_IPV4_EN_FRAG_IP_S, + + /* IPV6_TCP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_D = 32, + HNS3_RSS_FIELD_IPV6_TCP_EN_TCP_S, + HNS3_RSS_FIELD_IPV6_TCP_EN_IP_D, + HNS3_RSS_FIELD_IPV6_TCP_EN_IP_S, + + /* IPV6_UDP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_D = 40, + HNS3_RSS_FIELD_IPV6_UDP_EN_UDP_S, + HNS3_RSS_FIELD_IPV6_UDP_EN_IP_D, + HNS3_RSS_FIELD_IPV6_UDP_EN_IP_S, + + /* IPV6_SCTP ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_D = 48, + HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_S, + HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_D, + HNS3_RSS_FIELD_IPV6_SCTP_EN_IP_S, + HNS3_RSS_FIELD_IPV6_SCTP_EN_SCTP_VER, + + /* IPV6 ENABLE FIELD */ + HNS3_RSS_FIELD_IPV6_NONFRAG_IP_D = 56, + HNS3_RSS_FIELD_IPV6_NONFRAG_IP_S, + HNS3_RSS_FIELD_IPV6_FRAG_IP_D, + HNS3_RSS_FIELD_IPV6_FRAG_IP_S +}; + +#define HNS3_RSS_PCTYPE_IPV4_TCP BIT_ULL(0) +#define HNS3_RSS_PCTYPE_IPV4_UDP BIT_ULL(8) +#define HNS3_RSS_PCTYPE_IPV4_SCTP BIT_ULL(16) +#define HNS3_RSS_PCTYPE_IPV4_NONF BIT_ULL(24) +#define HNS3_RSS_PCTYPE_IPV4_FLAG BIT_ULL(26) +#define HNS3_RSS_PCTYPE_IPV6_TCP BIT_ULL(32) +#define HNS3_RSS_PCTYPE_IPV6_UDP BIT_ULL(40) +#define HNS3_RSS_PCTYPE_IPV6_SCTP BIT_ULL(48) +#define HNS3_RSS_PCTYPE_IPV6_NONF BIT_ULL(56) +#define HNS3_RSS_PCTYPE_IPV6_FLAG BIT_ULL(58) + +#define HNS3_RSS_TUPLE_IPV4_TCP_M GENMASK(3, 0) +#define HNS3_RSS_TUPLE_IPV4_UDP_M GENMASK(11, 8) +#define HNS3_RSS_TUPLE_IPV4_SCTP_M GENMASK(20, 16) +#define HNS3_RSS_TUPLE_IPV4_NONF_M GENMASK(25, 24) +#define HNS3_RSS_TUPLE_IPV4_FLAG_M GENMASK(27, 26) +#define HNS3_RSS_TUPLE_IPV6_TCP_M GENMASK(35, 32) +#define HNS3_RSS_TUPLE_IPV6_UDP_M GENMASK(43, 40) +#define HNS3_RSS_TUPLE_IPV6_SCTP_M GENMASK(52, 48) +#define HNS3_RSS_TUPLE_IPV6_NONF_M GENMASK(57, 56) +#define HNS3_RSS_TUPLE_IPV6_FLAG_M GENMASK(59, 58) #define HNS3_RSS_IND_TBL_SIZE 512 /* The size of hash lookup table */ #define HNS3_RSS_IND_TBL_SIZE_MAX 2048 #define HNS3_RSS_KEY_SIZE 40 +#define HNS3_RSS_KEY_SIZE_MAX 128 #define HNS3_RSS_SET_BITMAP_MSK 0xffff #define HNS3_RSS_HASH_ALGO_TOEPLITZ 0 @@ -40,15 +120,13 @@ uint64_t rss_tuple_fields; }; -#define HNS3_RSS_QUEUES_BUFFER_NUM 64 /* Same as the Max rx/tx queue num */ +/* Same as the Max queue num under TC */ +#define HNS3_RSS_QUEUES_BUFFER_NUM 512 struct hns3_rss_conf { - /* RSS parameters :algorithm, flow_types, key, queue */ - struct rte_flow_action_rss conf; + uint64_t rss_hf; uint8_t hash_algo; /* hash function type defined by hardware */ - uint8_t key[HNS3_RSS_KEY_SIZE]; /* Hash key */ + uint8_t key[HNS3_RSS_KEY_SIZE_MAX]; /* Hash key */ uint16_t rss_indirection_tbl[HNS3_RSS_IND_TBL_SIZE_MAX]; - uint16_t queue[HNS3_RSS_QUEUES_BUFFER_NUM]; /* Queues indices to use */ - bool valid; /* check if RSS rule is valid */ /* * For IPv6 SCTP packets type, check whether the NIC hardware support * RSS hash using the src/dst port as the input tuple. For Kunpeng920 @@ -112,8 +190,17 @@ int hns3_rss_reset_indir_table(struct hns3_hw *hw); int hns3_config_rss(struct hns3_adapter *hns); void hns3_rss_uninit(struct hns3_adapter *hns); +bool hns3_check_rss_types_valid(struct hns3_hw *hw, uint64_t types); int hns3_set_rss_tuple_by_rss_hf(struct hns3_hw *hw, uint64_t rss_hf); -int hns3_set_rss_algo_key(struct hns3_hw *hw, const uint8_t *key); +int hns3_set_rss_tuple_field(struct hns3_hw *hw, uint64_t tuple_fields); +int hns3_get_rss_tuple_field(struct hns3_hw *hw, uint64_t *tuple_fields); +int hns3_set_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + const uint8_t *key, uint8_t key_len); int hns3_restore_filter(struct hns3_adapter *hns); +int hns3_rss_get_algo_key(struct hns3_hw *hw, uint8_t *hash_algo, + uint8_t *key, uint8_t key_len); +uint64_t hns3_rss_calc_tuple_filed(uint64_t rss_hf); +int hns3_update_rss_algo_key(struct hns3_hw *hw, uint8_t hash_algo, + uint8_t *key, uint8_t key_len); #endif /* _HNS3_RSS_H_ */ diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_rxtx.c dpdk-20.11.8/drivers/net/hns3/hns3_rxtx.c --- dpdk-20.11.7/drivers/net/hns3/hns3_rxtx.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_rxtx.c 2023-04-27 17:57:22.000000000 +0000 @@ -19,10 +19,16 @@ #include "hns3_regs.h" #include "hns3_logs.h" #include "hns3_rxtx.h" +#include "hns3_mp.h" #define HNS3_CFG_DESC_NUM(num) ((num) / 8 - 1) #define HNS3_RX_RING_PREFETCTH_MASK 3 +static uint16_t +hns3_dummy_rxtx_burst(void *dpdk_txq __rte_unused, + struct rte_mbuf **pkts __rte_unused, + uint16_t pkts_n __rte_unused); + static void hns3_rx_queue_release_mbufs(struct hns3_rx_queue *rxq) { @@ -2527,10 +2533,11 @@ eth_rx_burst_t pkt_burst; const char *info; } burst_infos[] = { - { hns3_recv_pkts, "Scalar" }, + { hns3_recv_pkts, "Scalar" }, { hns3_recv_scattered_pkts, "Scalar Scattered" }, - { hns3_recv_pkts_vec, "Vector Neon" }, - { hns3_recv_pkts_vec_sve, "Vector Sve" }, + { hns3_recv_pkts_vec, "Vector Neon" }, + { hns3_recv_pkts_vec_sve, "Vector Sve" }, + { hns3_dummy_rxtx_burst, "Dummy" }, }; eth_rx_burst_t pkt_burst = dev->rx_pkt_burst; @@ -3867,24 +3874,31 @@ hns3_tx_burst_mode_get(struct rte_eth_dev *dev, __rte_unused uint16_t queue_id, struct rte_eth_burst_mode *mode) { - eth_tx_burst_t pkt_burst = dev->tx_pkt_burst; - const char *info = NULL; - - if (pkt_burst == hns3_xmit_pkts_simple) - info = "Scalar Simple"; - else if (pkt_burst == hns3_xmit_pkts) - info = "Scalar"; - else if (pkt_burst == hns3_xmit_pkts_vec) - info = "Vector Neon"; - else if (pkt_burst == hns3_xmit_pkts_vec_sve) - info = "Vector Sve"; + static const struct { + eth_tx_burst_t pkt_burst; + const char *info; + } burst_infos[] = { + { hns3_xmit_pkts_simple, "Scalar Simple" }, + { hns3_xmit_pkts, "Scalar" }, + { hns3_xmit_pkts_vec, "Vector Neon" }, + { hns3_xmit_pkts_vec_sve, "Vector Sve" }, + { hns3_dummy_rxtx_burst, "Dummy" }, + }; - if (info == NULL) - return -EINVAL; + eth_tx_burst_t pkt_burst = dev->tx_pkt_burst; + int ret = -EINVAL; + unsigned int i; - snprintf(mode->info, sizeof(mode->info), "%s", info); + for (i = 0; i < RTE_DIM(burst_infos); i++) { + if (pkt_burst == burst_infos[i].pkt_burst) { + snprintf(mode->info, sizeof(mode->info), "%s", + burst_infos[i].info); + ret = 0; + break; + } + } - return 0; + return ret; } static eth_tx_burst_t @@ -4117,3 +4131,31 @@ else return fbd_num - driver_hold_bd_num; } + +void +hns3_stop_rxtx_datapath(struct rte_eth_dev *dev) +{ + struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + hns3_set_rxtx_function(dev); + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) + return; + + rte_wmb(); + /* Disable datapath on secondary process. */ + hns3_mp_req_stop_rxtx(dev); + /* Prevent crashes when queues are still in use. */ + rte_delay_ms(hw->cfg_max_queues); +} + +void +hns3_start_rxtx_datapath(struct rte_eth_dev *dev) +{ + hns3_set_rxtx_function(dev); + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) + return; + + hns3_mp_req_start_rxtx(dev); +} diff -Nru dpdk-20.11.7/drivers/net/hns3/hns3_rxtx.h dpdk-20.11.8/drivers/net/hns3/hns3_rxtx.h --- dpdk-20.11.7/drivers/net/hns3/hns3_rxtx.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/hns3/hns3_rxtx.h 2023-04-27 17:57:22.000000000 +0000 @@ -702,5 +702,7 @@ int hns3_start_all_rxqs(struct rte_eth_dev *dev); void hns3_stop_all_txqs(struct rte_eth_dev *dev); void hns3_restore_tqp_enable_state(struct hns3_hw *hw); +void hns3_stop_rxtx_datapath(struct rte_eth_dev *dev); +void hns3_start_rxtx_datapath(struct rte_eth_dev *dev); #endif /* _HNS3_RXTX_H_ */ diff -Nru dpdk-20.11.7/drivers/net/i40e/i40e_ethdev.c dpdk-20.11.8/drivers/net/i40e/i40e_ethdev.c --- dpdk-20.11.7/drivers/net/i40e/i40e_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/i40e/i40e_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -397,7 +397,6 @@ struct rte_ether_addr *mac_addr); static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); -static void i40e_set_mac_max_frame(struct rte_eth_dev *dev, uint16_t size); static int i40e_ethertype_filter_convert( const struct rte_eth_ethertype_filter *input, @@ -1779,6 +1778,11 @@ /* initialize mirror rule list */ TAILQ_INIT(&pf->mirror_list); + /* Set the max frame size to 0x2600 by default, + * in case other drivers changed the default value. + */ + i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, TRUE, false, 0, NULL); + /* initialize RSS rule list */ TAILQ_INIT(&pf->rss_config_list); @@ -2430,7 +2434,6 @@ uint32_t intr_vector = 0; struct i40e_vsi *vsi; uint16_t nb_rxq, nb_txq; - uint16_t max_frame_size; hw->adapter_stopped = 0; @@ -2517,10 +2520,21 @@ } } + /* Disable mac loopback mode */ + if (dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_MODE_NONE) { + ret = i40e_aq_set_lb_modes(hw, I40E_AQ_LB_MODE_NONE, NULL); + if (ret != I40E_SUCCESS) { + PMD_DRV_LOG(ERR, "fail to set loopback link"); + goto tx_err; + } + } + /* Enable mac loopback mode */ - if (dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_MODE_NONE || - dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_PHY_LOCAL) { - ret = i40e_aq_set_lb_modes(hw, dev->data->dev_conf.lpbk_mode, NULL); + if (dev->data->dev_conf.lpbk_mode == I40E_AQ_LB_MODE_EN) { + if (hw->mac.type == I40E_MAC_X722) + ret = i40e_aq_set_lb_modes(hw, I40E_AQ_LB_MAC_LOCAL_X722, NULL); + else + ret = i40e_aq_set_lb_modes(hw, I40E_AQ_LB_MAC, NULL); if (ret != I40E_SUCCESS) { PMD_DRV_LOG(ERR, "fail to set loopback link"); goto tx_err; @@ -2572,9 +2586,6 @@ "please call hierarchy_commit() " "before starting the port"); - max_frame_size = dev->data->mtu + I40E_ETH_OVERHEAD; - i40e_set_mac_max_frame(dev, max_frame_size); - return I40E_SUCCESS; tx_err: @@ -2942,9 +2953,6 @@ return i40e_phy_conf_link(hw, abilities, speed, false); } -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ - static __rte_always_inline void update_link_reg(struct i40e_hw *hw, struct rte_eth_link *link) { @@ -3012,6 +3020,8 @@ update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link, bool enable_lse, int wait_to_complete) { +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ uint32_t rep_cnt = MAX_REPEAT_TIME; struct i40e_link_status link_status; int status; @@ -6814,7 +6824,6 @@ if (!ret) rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL); - break; default: PMD_DRV_LOG(DEBUG, "Request %u is not supported yet", @@ -13132,40 +13141,6 @@ return 0; } -static void -i40e_set_mac_max_frame(struct rte_eth_dev *dev, uint16_t size) -{ - struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint32_t rep_cnt = MAX_REPEAT_TIME; - struct rte_eth_link link; - enum i40e_status_code status; - bool can_be_set = true; - - /* - * I40E_MEDIA_TYPE_BASET link up can be ignored - * I40E_MEDIA_TYPE_BASET link down that hw->phy.media_type - * is I40E_MEDIA_TYPE_UNKNOWN - */ - if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET && - hw->phy.media_type != I40E_MEDIA_TYPE_UNKNOWN) { - do { - update_link_reg(hw, &link); - if (link.link_status) - break; - rte_delay_ms(CHECK_INTERVAL); - } while (--rep_cnt); - can_be_set = !!link.link_status; - } - - if (can_be_set) { - status = i40e_aq_set_mac_config(hw, size, TRUE, 0, false, NULL); - if (status != I40E_SUCCESS) - PMD_DRV_LOG(ERR, "Failed to set max frame size at port level"); - } else { - PMD_DRV_LOG(ERR, "Set max frame size at port level not applicable on link down"); - } -} - RTE_LOG_REGISTER(i40e_logtype_init, pmd.net.i40e.init, NOTICE); RTE_LOG_REGISTER(i40e_logtype_driver, pmd.net.i40e.driver, NOTICE); #ifdef RTE_LIBRTE_I40E_DEBUG_RX diff -Nru dpdk-20.11.7/drivers/net/i40e/i40e_ethdev.h dpdk-20.11.8/drivers/net/i40e/i40e_ethdev.h --- dpdk-20.11.7/drivers/net/i40e/i40e_ethdev.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/i40e/i40e_ethdev.h 2023-04-27 17:57:22.000000000 +0000 @@ -47,6 +47,9 @@ #define I40E_MAX_VF 128 /*flag of no loopback*/ #define I40E_AQ_LB_MODE_NONE 0x0 +#define I40E_AQ_LB_MODE_EN 0x01 +#define I40E_AQ_LB_MAC 0x01 +#define I40E_AQ_LB_MAC_LOCAL_X722 0x04 /* * vlan_id is a 12 bit number. * The VFTA array is actually a 4096 bit array, 128 of 32bit elements. @@ -1560,7 +1563,7 @@ uint16_t interval = 0; if (is_multi_drv) { - interval = I40E_QUEUE_ITR_INTERVAL_MAX; + interval = I40E_QUEUE_ITR_INTERVAL_DEFAULT; } else { if (is_pf) interval = I40E_QUEUE_ITR_INTERVAL_DEFAULT; diff -Nru dpdk-20.11.7/drivers/net/i40e/i40e_flow.c dpdk-20.11.8/drivers/net/i40e/i40e_flow.c --- dpdk-20.11.7/drivers/net/i40e/i40e_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/i40e/i40e_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -1992,6 +1992,14 @@ } /* Not supported */ + if (attr->transfer) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, + attr, "Not support transfer."); + return -rte_errno; + } + + /* Not supported */ if (attr->priority) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, diff -Nru dpdk-20.11.7/drivers/net/iavf/iavf.h dpdk-20.11.8/drivers/net/iavf/iavf.h --- dpdk-20.11.7/drivers/net/iavf/iavf.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/iavf/iavf.h 2023-04-27 17:57:22.000000000 +0000 @@ -160,6 +160,7 @@ struct iavf_qv_map *qv_map; /* queue vector mapping */ struct iavf_flow_list flow_list; rte_spinlock_t flow_ops_lock; + rte_spinlock_t aq_lock; struct iavf_parser_list rss_parser_list; struct iavf_parser_list dist_parser_list; diff -Nru dpdk-20.11.7/drivers/net/iavf/iavf_ethdev.c dpdk-20.11.8/drivers/net/iavf/iavf_ethdev.c --- dpdk-20.11.7/drivers/net/iavf/iavf_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/iavf/iavf_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -750,6 +750,9 @@ PMD_INIT_FUNC_TRACE(); + if (vf->vf_reset) + return 0; + if (adapter->stopped == 1) return 0; diff -Nru dpdk-20.11.7/drivers/net/iavf/iavf_generic_flow.c dpdk-20.11.8/drivers/net/iavf/iavf_generic_flow.c --- dpdk-20.11.7/drivers/net/iavf/iavf_generic_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/iavf/iavf_generic_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -1246,11 +1246,12 @@ } flow->engine = engine; + rte_spinlock_lock(&vf->flow_ops_lock); TAILQ_INSERT_TAIL(&vf->flow_list, flow, node); + rte_spinlock_unlock(&vf->flow_ops_lock); PMD_DRV_LOG(INFO, "Succeeded to create (%d) flow", engine->type); free_flow: - rte_spinlock_unlock(&vf->flow_ops_lock); return flow; } diff -Nru dpdk-20.11.7/drivers/net/iavf/iavf_vchnl.c dpdk-20.11.8/drivers/net/iavf/iavf_vchnl.c --- dpdk-20.11.7/drivers/net/iavf/iavf_vchnl.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/iavf/iavf_vchnl.c 2023-04-27 17:57:22.000000000 +0000 @@ -387,6 +387,20 @@ return err; } +static int +iavf_execute_vf_cmd_safe(struct iavf_adapter *adapter, + struct iavf_cmd_info *args) +{ + struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter); + int ret; + + rte_spinlock_lock(&vf->aq_lock); + ret = iavf_execute_vf_cmd(adapter, args); + rte_spinlock_unlock(&vf->aq_lock); + + return ret; +} + static void iavf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg, uint16_t msglen) @@ -504,7 +518,7 @@ args.in_args_size = 0; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - ret = iavf_execute_vf_cmd(adapter, &args); + ret = iavf_execute_vf_cmd_safe(adapter, &args); if (ret) PMD_DRV_LOG(ERR, "Failed to execute command of" " OP_ENABLE_VLAN_STRIPPING"); @@ -525,7 +539,7 @@ args.in_args_size = 0; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - ret = iavf_execute_vf_cmd(adapter, &args); + ret = iavf_execute_vf_cmd_safe(adapter, &args); if (ret) PMD_DRV_LOG(ERR, "Failed to execute command of" " OP_DISABLE_VLAN_STRIPPING"); @@ -554,7 +568,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_INIT_LOG(ERR, "Fail to execute command of OP_VERSION"); return err; @@ -609,7 +623,7 @@ args.in_args = (uint8_t *)∩︀ args.in_args_size = sizeof(caps); - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, @@ -654,7 +668,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - ret = iavf_execute_vf_cmd(adapter, &args); + ret = iavf_execute_vf_cmd_safe(adapter, &args); if (ret) { PMD_DRV_LOG(ERR, "Failed to execute command of OP_GET_SUPPORTED_RXDIDS"); @@ -686,7 +700,7 @@ args.in_args_size = sizeof(queue_select); args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "Failed to execute command of OP_ENABLE_QUEUES"); @@ -714,7 +728,7 @@ args.in_args_size = sizeof(queue_select); args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "Failed to execute command of OP_DISABLE_QUEUES"); @@ -747,7 +761,7 @@ args.in_args_size = sizeof(queue_select); args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of %s", on ? "OP_ENABLE_QUEUES" : "OP_DISABLE_QUEUES"); @@ -789,7 +803,7 @@ args.in_args_size = len; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of OP_ENABLE_QUEUES_V2"); @@ -833,7 +847,7 @@ args.in_args_size = len; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of OP_DISABLE_QUEUES_V2"); @@ -879,7 +893,7 @@ args.in_args_size = len; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of %s", on ? "OP_ENABLE_QUEUES_V2" : "OP_DISABLE_QUEUES_V2"); @@ -911,7 +925,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of OP_CONFIG_RSS_LUT"); @@ -943,7 +957,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of OP_CONFIG_RSS_KEY"); @@ -1035,7 +1049,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of" " VIRTCHNL_OP_CONFIG_VSI_QUEUES"); @@ -1076,7 +1090,7 @@ args.in_args_size = len; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "fail to execute command OP_CONFIG_IRQ_MAP"); @@ -1117,7 +1131,7 @@ args.in_args_size = len; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "fail to execute command OP_MAP_QUEUE_VECTOR"); @@ -1179,7 +1193,7 @@ args.in_args_size = len; args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "fail to execute command %s", add ? "OP_ADD_ETHER_ADDRESS" : @@ -1206,7 +1220,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS"); *pstats = NULL; @@ -1241,7 +1255,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, @@ -1281,7 +1295,7 @@ args.in_args_size = sizeof(cmd_buffer); args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "fail to execute command %s", add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR"); @@ -1308,7 +1322,7 @@ args.in_args_size = sizeof(cmd_buffer); args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "fail to execute command %s", add ? "OP_ADD_VLAN" : "OP_DEL_VLAN"); @@ -1335,7 +1349,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "fail to execute command OP_ADD_FDIR_FILTER"); return err; @@ -1395,7 +1409,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "fail to execute command OP_DEL_FDIR_FILTER"); return err; @@ -1442,7 +1456,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "fail to check flow director rule"); return err; @@ -1483,7 +1497,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) PMD_DRV_LOG(ERR, "Failed to execute command of %s", @@ -1536,7 +1550,7 @@ i * sizeof(struct virtchnl_ether_addr); args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "fail to execute command %s", @@ -1580,10 +1594,14 @@ /* * disable interrupt to avoid the admin queue message to be read * before iavf_read_msg_from_pf. + * + * don't disable interrupt handler until ready to execute vf cmd. */ + rte_spinlock_lock(&vf->aq_lock); rte_intr_disable(&pci_dev->intr_handle); err = iavf_execute_vf_cmd(adapter, &args); rte_intr_enable(&pci_dev->intr_handle); + rte_spinlock_unlock(&vf->aq_lock); if (err) { PMD_DRV_LOG(ERR, "fail to execute command OP_REQUEST_QUEUES"); return err; @@ -1618,7 +1636,7 @@ args.out_buffer = vf->aq_resp; args.out_size = IAVF_AQ_BUF_SZ; - err = iavf_execute_vf_cmd(adapter, &args); + err = iavf_execute_vf_cmd_safe(adapter, &args); if (err) { PMD_DRV_LOG(ERR, "Failed to execute command of VIRTCHNL_OP_GET_MAX_RSS_QREGION"); return err; diff -Nru dpdk-20.11.7/drivers/net/ice/ice_generic_flow.c dpdk-20.11.8/drivers/net/ice/ice_generic_flow.c --- dpdk-20.11.7/drivers/net/ice/ice_generic_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/ice/ice_generic_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -1946,6 +1946,14 @@ return -rte_errno; } + /* Not supported */ + if (attr->transfer) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, + attr, "Not support transfer."); + return -rte_errno; + } + /* Check pipeline mode support to set classification stage */ if (ad->devargs.pipe_mode_support) { if (attr->priority == 0) diff -Nru dpdk-20.11.7/drivers/net/ipn3ke/ipn3ke_ethdev.c dpdk-20.11.8/drivers/net/ipn3ke/ipn3ke_ethdev.c --- dpdk-20.11.7/drivers/net/ipn3ke/ipn3ke_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/ipn3ke/ipn3ke_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -561,7 +561,7 @@ snprintf(name, sizeof(name), "net_%s_representor_%d", afu_dev->device.name, i); - ethdev = rte_eth_dev_allocated(afu_dev->device.name); + ethdev = rte_eth_dev_allocated(name); if (ethdev != NULL) rte_eth_dev_destroy(ethdev, ipn3ke_rpst_uninit); } diff -Nru dpdk-20.11.7/drivers/net/ipn3ke/ipn3ke_representor.c dpdk-20.11.8/drivers/net/ipn3ke/ipn3ke_representor.c --- dpdk-20.11.7/drivers/net/ipn3ke/ipn3ke_representor.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/ipn3ke/ipn3ke_representor.c 2023-04-27 17:57:22.000000000 +0000 @@ -2589,7 +2589,7 @@ } rte_delay_us(50 * MS); - if (num == 0xffffff) + if (num == 0 || num == 0xffffff) return NULL; } diff -Nru dpdk-20.11.7/drivers/net/ixgbe/ixgbe_ethdev.c dpdk-20.11.8/drivers/net/ixgbe/ixgbe_ethdev.c --- dpdk-20.11.7/drivers/net/ixgbe/ixgbe_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/ixgbe/ixgbe_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -3869,23 +3869,32 @@ ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - u16 eeprom_verh, eeprom_verl; - u32 etrack_id; + struct ixgbe_nvm_version nvm_ver; int ret; - ixgbe_read_eeprom(hw, 0x2e, &eeprom_verh); - ixgbe_read_eeprom(hw, 0x2d, &eeprom_verl); + ixgbe_get_oem_prod_version(hw, &nvm_ver); + if (nvm_ver.oem_valid) { + snprintf(fw_version, fw_size, "%x.%x.%x", + nvm_ver.oem_major, nvm_ver.oem_minor, + nvm_ver.oem_release); + return 0; + } + + ixgbe_get_etk_id(hw, &nvm_ver); + ixgbe_get_orom_version(hw, &nvm_ver); - etrack_id = (eeprom_verh << 16) | eeprom_verl; - ret = snprintf(fw_version, fw_size, "0x%08x", etrack_id); + if (nvm_ver.or_valid) { + snprintf(fw_version, fw_size, "0x%08x, %d.%d.%d", + nvm_ver.etk_id, nvm_ver.or_major, + nvm_ver.or_build, nvm_ver.or_patch); + return 0; + } + + ret = snprintf(fw_version, fw_size, "0x%08x", nvm_ver.etk_id); if (ret < 0) return -EINVAL; - ret += 1; /* add the size of '\0' */ - if (fw_size < (size_t)ret) - return ret; - else - return 0; + return (fw_size < (size_t)ret++) ? ret : 0; } static int diff -Nru dpdk-20.11.7/drivers/net/ixgbe/ixgbe_flow.c dpdk-20.11.8/drivers/net/ixgbe/ixgbe_flow.c --- dpdk-20.11.7/drivers/net/ixgbe/ixgbe_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/ixgbe/ixgbe_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -1918,9 +1918,9 @@ /* check src addr mask */ for (j = 0; j < 16; j++) { - if (ipv6_mask->hdr.src_addr[j] == UINT8_MAX) { - rule->mask.src_ipv6_mask |= 1 << j; - } else if (ipv6_mask->hdr.src_addr[j] != 0) { + if (ipv6_mask->hdr.src_addr[j] == 0) { + rule->mask.src_ipv6_mask &= ~(1 << j); + } else if (ipv6_mask->hdr.src_addr[j] != UINT8_MAX) { memset(rule, 0, sizeof(struct ixgbe_fdir_rule)); rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, @@ -1931,9 +1931,9 @@ /* check dst addr mask */ for (j = 0; j < 16; j++) { - if (ipv6_mask->hdr.dst_addr[j] == UINT8_MAX) { - rule->mask.dst_ipv6_mask |= 1 << j; - } else if (ipv6_mask->hdr.dst_addr[j] != 0) { + if (ipv6_mask->hdr.dst_addr[j] == 0) { + rule->mask.dst_ipv6_mask &= ~(1 << j); + } else if (ipv6_mask->hdr.dst_addr[j] != UINT8_MAX) { memset(rule, 0, sizeof(struct ixgbe_fdir_rule)); rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, diff -Nru dpdk-20.11.7/drivers/net/mlx5/linux/mlx5_ethdev_os.c dpdk-20.11.8/drivers/net/mlx5/linux/mlx5_ethdev_os.c --- dpdk-20.11.7/drivers/net/mlx5/linux/mlx5_ethdev_os.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/linux/mlx5_ethdev_os.c 2023-04-27 17:57:22.000000000 +0000 @@ -1074,7 +1074,8 @@ mlx5_sysfs_switch_info(unsigned int ifindex, struct mlx5_switch_info *info) { char ifname[IF_NAMESIZE]; - char port_name[IF_NAMESIZE]; + char *port_name = NULL; + size_t port_name_size = 0; FILE *file; struct mlx5_switch_info data = { .master = 0, @@ -1087,6 +1088,7 @@ bool port_switch_id_set = false; bool device_dir = false; char c; + ssize_t line_size; if (!if_indextoname(ifindex, ifname)) { rte_errno = errno; @@ -1102,8 +1104,21 @@ file = fopen(phys_port_name, "rb"); if (file != NULL) { - if (fgets(port_name, IF_NAMESIZE, file) != NULL) + char *tail_nl; + + line_size = getline(&port_name, &port_name_size, file); + if (line_size < 0) { + fclose(file); + rte_errno = errno; + return -rte_errno; + } else if (line_size > 0) { + /* Remove tailing newline character. */ + tail_nl = strchr(port_name, '\n'); + if (tail_nl) + *tail_nl = '\0'; mlx5_translate_port_name(port_name, &data); + } + free(port_name); fclose(file); } file = fopen(phys_switch_id, "rb"); diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_flow.c dpdk-20.11.8/drivers/net/mlx5/mlx5_flow.c --- dpdk-20.11.7/drivers/net/mlx5/mlx5_flow.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_flow.c 2023-04-27 17:57:22.000000000 +0000 @@ -4821,13 +4821,14 @@ if (!fdb_tx) { /* Prepare the prefix tag action. */ set_tag = (void *)(actions_pre + actions_n + 1); - ret = mlx5_flow_get_reg_id(dev, MLX5_SAMPLE_ID, 0, error); /* Trust VF/SF on CX5 not supported meter so that the reserved * metadata regC is REG_NON, back to use application tag * index 0. */ - if (unlikely(ret == REG_NON)) + if (unlikely(priv->mtr_color_reg == REG_NON)) ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error); + else + ret = mlx5_flow_get_reg_id(dev, MLX5_SAMPLE_ID, 0, error); if (ret < 0) return ret; set_tag->id = ret; diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx.c dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx.c --- dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx.c 2023-04-27 17:57:22.000000000 +0000 @@ -86,7 +86,8 @@ static __rte_always_inline int mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, - uint16_t cqe_cnt, volatile struct mlx5_mini_cqe8 **mcqe); + uint16_t cqe_cnt, volatile struct mlx5_mini_cqe8 **mcqe, + uint16_t *skip_cnt, bool mprq); static __rte_always_inline uint32_t rxq_cq_to_ol_flags(volatile struct mlx5_cqe *cqe); @@ -784,7 +785,7 @@ mlx5_dump_debug_information(name, "MLX5 Error CQ:", (const void *)((uintptr_t) txq->cqes), - sizeof(*err_cqe) * + sizeof(struct mlx5_cqe) * (1 << txq->cqe_n)); mlx5_dump_debug_information(name, "MLX5 Error SQ:", (const void *)((uintptr_t) @@ -983,10 +984,14 @@ return ret; } +#define MLX5_ERROR_CQE_MASK 0x40000000 /* Must be negative. */ -#define MLX5_ERROR_CQE_RET (-1) +#define MLX5_REGULAR_ERROR_CQE_RET (-5) +#define MLX5_CRITICAL_ERROR_CQE_RET (-4) /* Must not be negative. */ #define MLX5_RECOVERY_ERROR_RET 0 +#define MLX5_RECOVERY_IGNORE_RET 1 +#define MLX5_RECOVERY_COMPLETED_RET 2 /** * Handle a Rx error. @@ -1000,12 +1005,18 @@ * @param[in] vec * 1 when called from vectorized Rx burst, need to prepare mbufs for the RQ. * 0 when called from non-vectorized Rx burst. + * @param[in] err_n + * Number of CQEs to check for an error. * * @return - * MLX5_RECOVERY_ERROR_RET in case of recovery error, otherwise the CQE status. + * MLX5_RECOVERY_ERROR_RET in case of recovery error, + * MLX5_RECOVERY_IGNORE_RET in case of non-critical error syndrome, + * MLX5_RECOVERY_COMPLETED_RET in case of recovery is completed, + * otherwise the CQE status after ignored error syndrome or queue reset. */ int -mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec) +mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec, + uint16_t err_n, uint16_t *skip_cnt) { const uint16_t cqe_n = 1 << rxq->cqe_n; const uint16_t cqe_mask = cqe_n - 1; @@ -1017,13 +1028,39 @@ volatile struct mlx5_cqe *cqe; volatile struct mlx5_err_cqe *err_cqe; } u = { - .cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_mask], + .cqe = &(*rxq->cqes)[(rxq->cq_ci - vec) & cqe_mask], }; struct mlx5_mp_arg_queue_state_modify sm; - int ret; + bool critical_syndrome = false; + int ret, i; switch (rxq->err_state) { + case MLX5_RXQ_ERR_STATE_IGNORE: + ret = check_cqe(u.cqe, cqe_n, rxq->cq_ci - vec); + if (ret != MLX5_CQE_STATUS_ERR) { + rxq->err_state = MLX5_RXQ_ERR_STATE_NO_ERROR; + return ret; + } + /* Fall-through */ case MLX5_RXQ_ERR_STATE_NO_ERROR: + for (i = 0; i < (int)err_n; i++) { + u.cqe = &(*rxq->cqes)[(rxq->cq_ci - vec - i) & cqe_mask]; + if (MLX5_CQE_OPCODE(u.cqe->op_own) == MLX5_CQE_RESP_ERR) { + if (u.err_cqe->syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || + u.err_cqe->syndrome == MLX5_CQE_SYNDROME_LOCAL_PROT_ERR || + u.err_cqe->syndrome == MLX5_CQE_SYNDROME_WR_FLUSH_ERR) + critical_syndrome = true; + break; + } + } + if (!critical_syndrome) { + if (rxq->err_state == MLX5_RXQ_ERR_STATE_NO_ERROR) { + *skip_cnt = 0; + if (i == err_n) + rxq->err_state = MLX5_RXQ_ERR_STATE_IGNORE; + } + return MLX5_RECOVERY_IGNORE_RET; + } rxq->err_state = MLX5_RXQ_ERR_STATE_NEED_RESET; /* Fall-through */ case MLX5_RXQ_ERR_STATE_NEED_RESET: @@ -1083,7 +1120,6 @@ rxq->elts_ci : rxq->rq_ci; uint32_t elt_idx; struct rte_mbuf **elt; - int i; unsigned int n = elts_n - (elts_ci - rxq->rq_pi); @@ -1116,6 +1152,7 @@ } mlx5_rxq_initialize(rxq); rxq->err_state = MLX5_RXQ_ERR_STATE_NO_ERROR; + return MLX5_RECOVERY_COMPLETED_RET; } return ret; default: @@ -1135,19 +1172,24 @@ * @param[out] mcqe * Store pointer to mini-CQE if compressed. Otherwise, the pointer is not * written. - * + * @param[out] skip_cnt + * Number of packets skipped due to recoverable errors. + * @param mprq + * Indication if it is called from MPRQ. * @return - * 0 in case of empty CQE, MLX5_ERROR_CQE_RET in case of error CQE, - * otherwise the packet size in regular RxQ, and striding byte - * count format in mprq case. + * 0 in case of empty CQE, MLX5_REGULAR_ERROR_CQE_RET in case of error CQE, + * MLX5_CRITICAL_ERROR_CQE_RET in case of error CQE lead to Rx queue reset, + * otherwise the packet size in regular RxQ, + * and striding byte count format in mprq case. */ static inline int mlx5_rx_poll_len(struct mlx5_rxq_data *rxq, volatile struct mlx5_cqe *cqe, - uint16_t cqe_cnt, volatile struct mlx5_mini_cqe8 **mcqe) + uint16_t cqe_cnt, volatile struct mlx5_mini_cqe8 **mcqe, + uint16_t *skip_cnt, bool mprq) { struct rxq_zip *zip = &rxq->zip; uint16_t cqe_n = cqe_cnt + 1; - int len; + int len = 0, ret = 0; uint16_t idx, end; do { @@ -1196,7 +1238,6 @@ * compressed. */ } else { - int ret; int8_t op_own; uint32_t cq_ci; @@ -1204,10 +1245,12 @@ if (unlikely(ret != MLX5_CQE_STATUS_SW_OWN)) { if (unlikely(ret == MLX5_CQE_STATUS_ERR || rxq->err_state)) { - ret = mlx5_rx_err_handle(rxq, 0); - if (ret == MLX5_CQE_STATUS_HW_OWN || - ret == MLX5_RECOVERY_ERROR_RET) - return MLX5_ERROR_CQE_RET; + ret = mlx5_rx_err_handle(rxq, 0, 1, skip_cnt); + if (ret == MLX5_CQE_STATUS_HW_OWN) + return MLX5_ERROR_CQE_MASK; + if (ret == MLX5_RECOVERY_ERROR_RET || + ret == MLX5_RECOVERY_COMPLETED_RET) + return MLX5_CRITICAL_ERROR_CQE_RET; } else { return 0; } @@ -1260,8 +1303,15 @@ } } if (unlikely(rxq->err_state)) { + if (rxq->err_state == MLX5_RXQ_ERR_STATE_IGNORE && + ret == MLX5_CQE_STATUS_SW_OWN) { + rxq->err_state = MLX5_RXQ_ERR_STATE_NO_ERROR; + return len & MLX5_ERROR_CQE_MASK; + } cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_cnt]; ++rxq->stats.idropped; + (*skip_cnt) += mprq ? (len & MLX5_MPRQ_STRIDE_NUM_MASK) >> + MLX5_MPRQ_STRIDE_NUM_SHIFT : 1; } else { return len; } @@ -1412,6 +1462,7 @@ int len = 0; /* keep its value across iterations. */ while (pkts_n) { + uint16_t skip_cnt; unsigned int idx = rq_ci & wqe_cnt; volatile struct mlx5_wqe_data_seg *wqe = &((volatile struct mlx5_wqe_data_seg *)rxq->wqes)[idx]; @@ -1450,11 +1501,24 @@ } if (!pkt) { cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_cnt]; - len = mlx5_rx_poll_len(rxq, cqe, cqe_cnt, &mcqe); - if (len <= 0) { - rte_mbuf_raw_free(rep); - if (unlikely(len == MLX5_ERROR_CQE_RET)) + len = mlx5_rx_poll_len(rxq, cqe, cqe_cnt, &mcqe, &skip_cnt, false); + if (unlikely(len & MLX5_ERROR_CQE_MASK)) { + if (len == MLX5_CRITICAL_ERROR_CQE_RET) { + rte_mbuf_raw_free(rep); rq_ci = rxq->rq_ci << sges_n; + break; + } + rq_ci >>= sges_n; + rq_ci += skip_cnt; + rq_ci <<= sges_n; + idx = rq_ci & wqe_cnt; + wqe = &((volatile struct mlx5_wqe_data_seg *)rxq->wqes)[idx]; + seg = (*rxq->elts)[idx]; + cqe = &(*rxq->cqes)[rxq->cq_ci & cqe_cnt]; + len = len & ~MLX5_ERROR_CQE_MASK; + } + if (len == 0) { + rte_mbuf_raw_free(rep); break; } pkt = seg; @@ -1678,6 +1742,7 @@ uint16_t strd_cnt; uint16_t strd_idx; uint32_t byte_cnt; + uint16_t skip_cnt; volatile struct mlx5_mini_cqe8 *mcqe = NULL; enum mlx5_rqx_code rxq_code; @@ -1690,14 +1755,26 @@ buf = (*rxq->mprq_bufs)[rq_ci & wq_mask]; } cqe = &(*rxq->cqes)[rxq->cq_ci & cq_mask]; - ret = mlx5_rx_poll_len(rxq, cqe, cq_mask, &mcqe); + ret = mlx5_rx_poll_len(rxq, cqe, cq_mask, &mcqe, &skip_cnt, true); + if (unlikely(ret & MLX5_ERROR_CQE_MASK)) { + if (ret == MLX5_CRITICAL_ERROR_CQE_RET) { + rq_ci = rxq->rq_ci; + consumed_strd = rxq->consumed_strd; + break; + } + consumed_strd += skip_cnt; + while (consumed_strd >= strd_n) { + /* Replace WQE if the buffer is still in use. */ + mprq_buf_replace(rxq, rq_ci & wq_mask); + /* Advance to the next WQE. */ + consumed_strd -= strd_n; + ++rq_ci; + buf = (*rxq->mprq_bufs)[rq_ci & wq_mask]; + } + cqe = &(*rxq->cqes)[rxq->cq_ci & cq_mask]; + } if (ret == 0) break; - if (unlikely(ret == MLX5_ERROR_CQE_RET)) { - rq_ci = rxq->rq_ci; - consumed_strd = rxq->consumed_strd; - break; - } byte_cnt = ret; len = (byte_cnt & MLX5_MPRQ_LEN_MASK) >> MLX5_MPRQ_LEN_SHIFT; MLX5_ASSERT((int)len >= (rxq->crc_present << 2)); diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx.h dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx.h --- dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx.h 2023-04-27 17:57:22.000000000 +0000 @@ -91,6 +91,7 @@ MLX5_RXQ_ERR_STATE_NO_ERROR = 0, MLX5_RXQ_ERR_STATE_NEED_RESET, MLX5_RXQ_ERR_STATE_NEED_READY, + MLX5_RXQ_ERR_STATE_IGNORE, }; enum mlx5_rqx_code { @@ -427,7 +428,8 @@ void mlx5_set_swp_types_table(void); uint16_t mlx5_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n); void mlx5_rxq_initialize(struct mlx5_rxq_data *rxq); -__rte_noinline int mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec); +__rte_noinline int mlx5_rx_err_handle(struct mlx5_rxq_data *rxq, uint8_t vec, + uint16_t err_n, uint16_t *skip_cnt); void mlx5_mprq_buf_free_cb(void *addr, void *opaque); void mlx5_mprq_buf_free(struct mlx5_mprq_buf *buf); uint16_t mlx5_rx_burst_mprq(void *dpdk_rxq, struct rte_mbuf **pkts, diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec.c dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec.c --- dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec.c 2023-04-27 17:57:22.000000000 +0000 @@ -50,6 +50,7 @@ uint16_t pkts_n) { uint16_t n = 0; + uint16_t skip_cnt; unsigned int i; #ifdef MLX5_PMD_SOFT_COUNTERS uint32_t err_bytes = 0; @@ -73,7 +74,7 @@ rxq->stats.ipackets -= (pkts_n - n); rxq->stats.ibytes -= err_bytes; #endif - mlx5_rx_err_handle(rxq, 1); + mlx5_rx_err_handle(rxq, 1, pkts_n, &skip_cnt); return n; } @@ -247,8 +248,6 @@ } rxq->rq_pi += i; rxq->cq_ci += i; - rte_io_wmb(); - *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); if (rq_ci != rxq->rq_ci) { rxq->rq_ci = rq_ci; rte_io_wmb(); @@ -355,8 +354,6 @@ rxq->decompressed -= n; } } - rte_io_wmb(); - *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); *no_cq = !rcvd_pkt; return rcvd_pkt; } @@ -384,6 +381,7 @@ bool no_cq = false; do { + err = 0; nb_rx = rxq_burst_v(rxq, pkts + tn, pkts_n - tn, &err, &no_cq); if (unlikely(err | rxq->err_state)) @@ -391,6 +389,8 @@ tn += nb_rx; if (unlikely(no_cq)) break; + rte_io_wmb(); + *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); } while (tn != pkts_n); return tn; } @@ -518,6 +518,7 @@ bool no_cq = false; do { + err = 0; nb_rx = rxq_burst_mprq_v(rxq, pkts + tn, pkts_n - tn, &err, &no_cq); if (unlikely(err | rxq->err_state)) @@ -525,6 +526,8 @@ tn += nb_rx; if (unlikely(no_cq)) break; + rte_io_wmb(); + *rxq->cq_db = rte_cpu_to_be_32(rxq->cq_ci); } while (tn != pkts_n); return tn; } diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h --- dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec_altivec.h 2023-04-27 17:57:22.000000000 +0000 @@ -783,7 +783,7 @@ { const uint16_t q_n = 1 << rxq->cqe_n; const uint16_t q_mask = q_n - 1; - unsigned int pos; + unsigned int pos, adj; uint64_t n = 0; uint64_t comp_idx = MLX5_VPMD_DESCS_PER_LOOP; uint16_t nocmp_n = 0; @@ -866,7 +866,7 @@ vector unsigned char pkt_mb0, pkt_mb1, pkt_mb2, pkt_mb3; vector unsigned char op_own, op_own_tmp1, op_own_tmp2; vector unsigned char opcode, owner_mask, invalid_mask; - vector unsigned char comp_mask; + vector unsigned char comp_mask, mini_mask; vector unsigned char mask; #ifdef MLX5_PMD_SOFT_COUNTERS const vector unsigned char lower_half = { @@ -1174,6 +1174,16 @@ (vector unsigned long)mask); /* D.3 check error in opcode. */ + adj = (comp_idx != MLX5_VPMD_DESCS_PER_LOOP && comp_idx == n); + mask = (vector unsigned char)(vector unsigned long){ + (adj * sizeof(uint16_t) * 8), 0}; + lshift = vec_splat((vector unsigned long)mask, 0); + shmask = vec_cmpgt(shmax, lshift); + mini_mask = (vector unsigned char) + vec_sl((vector unsigned long)invalid_mask, lshift); + mini_mask = (vector unsigned char) + vec_sel((vector unsigned long)shmask, + (vector unsigned long)mini_mask, shmask); opcode = (vector unsigned char) vec_cmpeq((vector unsigned int)resp_err_check, (vector unsigned int)opcode); @@ -1182,7 +1192,7 @@ (vector unsigned int)zero); opcode = (vector unsigned char) vec_andc((vector unsigned long)opcode, - (vector unsigned long)invalid_mask); + (vector unsigned long)mini_mask); /* D.4 mark if any error is set */ *err |= ((vector unsigned long)opcode)[0]; diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec_neon.h dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec_neon.h --- dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec_neon.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec_neon.h 2023-04-27 17:57:22.000000000 +0000 @@ -524,7 +524,7 @@ { const uint16_t q_n = 1 << rxq->cqe_n; const uint16_t q_mask = q_n - 1; - unsigned int pos; + unsigned int pos, adj; uint64_t n = 0; uint64_t comp_idx = MLX5_VPMD_DESCS_PER_LOOP; uint16_t nocmp_n = 0; @@ -616,7 +616,7 @@ pos += MLX5_VPMD_DESCS_PER_LOOP) { uint16x4_t op_own; uint16x4_t opcode, owner_mask, invalid_mask; - uint16x4_t comp_mask; + uint16x4_t comp_mask, mini_mask; uint16x4_t mask; uint16x4_t byte_cnt; uint32x4_t ptype_info, flow_tag; @@ -780,8 +780,12 @@ -1UL >> (n * sizeof(uint16_t) * 8) : 0); invalid_mask = vorr_u16(invalid_mask, mask); /* D.3 check error in opcode. */ + adj = (comp_idx != MLX5_VPMD_DESCS_PER_LOOP && comp_idx == n); + mask = vcreate_u16(adj ? + -1UL >> ((n + 1) * sizeof(uint16_t) * 8) : -1UL); + mini_mask = vand_u16(invalid_mask, mask); opcode = vceq_u16(resp_err_check, opcode); - opcode = vbic_u16(opcode, invalid_mask); + opcode = vbic_u16(opcode, mini_mask); /* D.4 mark if any error is set */ *err |= vget_lane_u64(vreinterpret_u64_u16(opcode), 0); /* C.4 fill in mbuf - rearm_data and packet_type. */ diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec_sse.h dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec_sse.h --- dpdk-20.11.7/drivers/net/mlx5/mlx5_rxtx_vec_sse.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_rxtx_vec_sse.h 2023-04-27 17:57:22.000000000 +0000 @@ -523,7 +523,7 @@ { const uint16_t q_n = 1 << rxq->cqe_n; const uint16_t q_mask = q_n - 1; - unsigned int pos; + unsigned int pos, adj; uint64_t n = 0; uint64_t comp_idx = MLX5_VPMD_DESCS_PER_LOOP; uint16_t nocmp_n = 0; @@ -591,7 +591,7 @@ __m128i pkt_mb0, pkt_mb1, pkt_mb2, pkt_mb3; __m128i op_own, op_own_tmp1, op_own_tmp2; __m128i opcode, owner_mask, invalid_mask; - __m128i comp_mask; + __m128i comp_mask, mini_mask; __m128i mask; #ifdef MLX5_PMD_SOFT_COUNTERS __m128i byte_cnt; @@ -729,9 +729,12 @@ mask = _mm_sll_epi64(ones, mask); invalid_mask = _mm_or_si128(invalid_mask, mask); /* D.3 check error in opcode. */ + adj = (comp_idx != MLX5_VPMD_DESCS_PER_LOOP && comp_idx == n); + mask = _mm_set_epi64x(0, adj * sizeof(uint16_t) * 8); + mini_mask = _mm_sll_epi64(invalid_mask, mask); opcode = _mm_cmpeq_epi32(resp_err_check, opcode); opcode = _mm_packs_epi32(opcode, zero); - opcode = _mm_andnot_si128(invalid_mask, opcode); + opcode = _mm_andnot_si128(mini_mask, opcode); /* D.4 mark if any error is set */ *err |= _mm_cvtsi128_si64(opcode); /* D.5 fill in mbuf - rearm_data and packet_type. */ diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_stats.c dpdk-20.11.8/drivers/net/mlx5/mlx5_stats.c --- dpdk-20.11.7/drivers/net/mlx5/mlx5_stats.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_stats.c 2023-04-27 17:57:22.000000000 +0000 @@ -285,10 +285,9 @@ if (n >= mlx5_xstats_n && xstats_names) { for (i = 0; i != mlx5_xstats_n; ++i) { - strncpy(xstats_names[i].name, + strlcpy(xstats_names[i].name, xstats_ctrl->info[i].dpdk_name, RTE_ETH_XSTATS_NAME_SIZE); - xstats_names[i].name[RTE_ETH_XSTATS_NAME_SIZE - 1] = 0; } } mlx5_xstats_n = mlx5_txpp_xstats_get_names(dev, xstats_names, diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_trigger.c dpdk-20.11.8/drivers/net/mlx5/mlx5_trigger.c --- dpdk-20.11.7/drivers/net/mlx5/mlx5_trigger.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_trigger.c 2023-04-27 17:57:22.000000000 +0000 @@ -871,11 +871,11 @@ } /* Indeed, only the first used queue needs to be checked. */ if (txq_ctrl->hairpin_conf.manual_bind == 0) { + mlx5_txq_release(dev, i); if (cur_port != rx_port) { rte_errno = EINVAL; DRV_LOG(ERR, "port %u and port %u are in" " auto-bind mode", cur_port, rx_port); - mlx5_txq_release(dev, i); return -rte_errno; } else { return 0; diff -Nru dpdk-20.11.7/drivers/net/mlx5/mlx5_txpp.c dpdk-20.11.8/drivers/net/mlx5/mlx5_txpp.c --- dpdk-20.11.7/drivers/net/mlx5/mlx5_txpp.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/mlx5/mlx5_txpp.c 2023-04-27 17:57:22.000000000 +0000 @@ -1222,11 +1222,9 @@ if (n >= n_used + n_txpp && xstats_names) { for (i = 0; i < n_txpp; ++i) { - strncpy(xstats_names[i + n_used].name, + strlcpy(xstats_names[i + n_used].name, mlx5_txpp_stat_names[i], RTE_ETH_XSTATS_NAME_SIZE); - xstats_names[i + n_used].name - [RTE_ETH_XSTATS_NAME_SIZE - 1] = 0; } } return n_used + n_txpp; diff -Nru dpdk-20.11.7/drivers/net/nfp/nfp_net.c dpdk-20.11.8/drivers/net/nfp/nfp_net.c --- dpdk-20.11.7/drivers/net/nfp/nfp_net.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/nfp/nfp_net.c 2023-04-27 17:57:22.000000000 +0000 @@ -95,6 +95,8 @@ static int nfp_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr); +#define DEFAULT_FLBUF_SIZE 9216 + /* The offset of the queue controller queues in the PCIe Target */ #define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff))) @@ -2652,7 +2654,7 @@ cfg_rss_ctrl = nn_cfg_readl(hw, NFP_NET_CFG_RSS_CTRL); if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4) - rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV4_UDP; + rss_hf |= ETH_RSS_IPV4; if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV4_TCP) rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; @@ -2667,7 +2669,7 @@ rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; if (cfg_rss_ctrl & NFP_NET_CFG_RSS_IPV6) - rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP; + rss_hf |= ETH_RSS_IPV6; /* Propagate current RSS hash functions to caller */ rss_conf->rss_hf = rss_hf; @@ -2942,6 +2944,7 @@ hw->cap = nn_cfg_readl(hw, NFP_NET_CFG_CAP); hw->max_mtu = nn_cfg_readl(hw, NFP_NET_CFG_MAX_MTU); hw->mtu = RTE_ETHER_MTU; + hw->flbufsz = DEFAULT_FLBUF_SIZE; /* VLAN insertion is incompatible with LSOv2 */ if (hw->cap & NFP_NET_CFG_CTRL_LSO2) @@ -3538,7 +3541,7 @@ /* Then try the PCI name */ snprintf(fw_name, sizeof(fw_name), "%s/pci-%s.nffw", DEFAULT_FW_PATH, - dev->device.name); + dev->name); PMD_DRV_LOG(DEBUG, "Trying with fw file: %s", fw_name); fw_f = open(fw_name, O_RDONLY); diff -Nru dpdk-20.11.7/drivers/net/sfc/sfc_mae.c dpdk-20.11.8/drivers/net/sfc/sfc_mae.c --- dpdk-20.11.7/drivers/net/sfc/sfc_mae.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/sfc/sfc_mae.c 2023-04-27 17:57:22.000000000 +0000 @@ -2136,6 +2136,21 @@ if (rc != 0) goto fail_rule_parse_action; + /* + * A DPDK flow entry must specify a fate action, which the parser + * converts into a DELIVER action in a libefx action set. An + * attempt to replace the action in the action set should + * fail. If it succeeds then report an error, as the + * parsed flow entry did not contain a fate action. + */ + rc = efx_mae_action_set_populate_drop(spec); + if (rc == 0) { + rc = rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, NULL, + "no fate action found"); + goto fail_check_fate_action; + } + *action_setp = sfc_mae_action_set_attach(sa, spec); if (*action_setp != NULL) { efx_mae_action_set_spec_fini(sa->nic, spec); @@ -2149,6 +2164,7 @@ return 0; fail_action_set_add: +fail_check_fate_action: fail_rule_parse_action: efx_mae_action_set_spec_fini(sa->nic, spec); diff -Nru dpdk-20.11.7/drivers/net/txgbe/base/txgbe_phy.c dpdk-20.11.8/drivers/net/txgbe/base/txgbe_phy.c --- dpdk-20.11.7/drivers/net/txgbe/base/txgbe_phy.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/txgbe/base/txgbe_phy.c 2023-04-27 17:57:22.000000000 +0000 @@ -1491,9 +1491,10 @@ wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0x4F00); value = (0x1804 & ~0x3F3F); + value |= 40 << 8; wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - value = (0x50 & ~0x7F) | 40 | (1 << 6); + value = (0x50 & ~0x7F) | (1 << 6); wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); for (i = 0; i < 4; i++) { @@ -1701,10 +1702,10 @@ wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0x4F00); - value = (0x1804 & ~0x3F3F) | (24 << 8) | 4; + value = (0x1804 & ~0x3F3F) | (24 << 8); wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - value = (0x50 & ~0x7F) | 16 | (1 << 6); + value = (0x50 & ~0x7F) | (1 << 6); wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); for (i = 0; i < 4; i++) { diff -Nru dpdk-20.11.7/drivers/net/txgbe/txgbe_ethdev.c dpdk-20.11.8/drivers/net/txgbe/txgbe_ethdev.c --- dpdk-20.11.7/drivers/net/txgbe/txgbe_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/txgbe/txgbe_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -2682,9 +2682,6 @@ intr_handle->type != RTE_INTR_HANDLE_VFIO_MSIX) wr32(hw, TXGBE_PX_INTA, 1); - /* clear all cause mask */ - txgbe_disable_intr(hw); - /* read-on-clear nic registers here */ eicr = ((u32 *)hw->isb_mem)[TXGBE_ISB_MISC]; PMD_DRV_LOG(DEBUG, "eicr %x", eicr); @@ -2704,6 +2701,8 @@ if (eicr & TXGBE_ICRMISC_GPIO) intr->flags |= TXGBE_FLAG_PHY_INTERRUPT; + ((u32 *)hw->isb_mem)[TXGBE_ISB_MISC] = 0; + return 0; } diff -Nru dpdk-20.11.7/drivers/net/txgbe/txgbe_rxtx.c dpdk-20.11.8/drivers/net/txgbe/txgbe_rxtx.c --- dpdk-20.11.7/drivers/net/txgbe/txgbe_rxtx.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/txgbe/txgbe_rxtx.c 2023-04-27 17:57:22.000000000 +0000 @@ -495,20 +495,21 @@ return cmdtype; } -static inline uint8_t -tx_desc_ol_flags_to_ptid(uint64_t oflags, uint32_t ptype) +static inline uint32_t +tx_desc_ol_flags_to_ptype(uint64_t oflags) { + uint32_t ptype; bool tun; - if (ptype) - return txgbe_encode_ptype(ptype); - /* Only support flags in TXGBE_TX_OFFLOAD_MASK */ tun = !!(oflags & PKT_TX_TUNNEL_MASK); /* L2 level */ ptype = RTE_PTYPE_L2_ETHER; if (oflags & PKT_TX_VLAN) + ptype |= (tun ? RTE_PTYPE_INNER_L2_ETHER_VLAN : RTE_PTYPE_L2_ETHER_VLAN); + + if (oflags & PKT_TX_QINQ) /* tunnel + QINQ is not supported */ ptype |= RTE_PTYPE_L2_ETHER_VLAN; /* L3 level */ @@ -572,6 +573,16 @@ break; } + return ptype; +} + +static inline uint8_t +tx_desc_ol_flags_to_ptid(uint64_t oflags) +{ + uint32_t ptype; + + ptype = tx_desc_ol_flags_to_ptype(oflags); + return txgbe_encode_ptype(ptype); } @@ -731,8 +742,7 @@ /* If hardware offload required */ tx_ol_req = ol_flags & TXGBE_TX_OFFLOAD_MASK; if (tx_ol_req) { - tx_offload.ptid = tx_desc_ol_flags_to_ptid(tx_ol_req, - tx_pkt->packet_type); + tx_offload.ptid = tx_desc_ol_flags_to_ptid(tx_ol_req); tx_offload.l2_len = tx_pkt->l2_len; tx_offload.l3_len = tx_pkt->l3_len; tx_offload.l4_len = tx_pkt->l4_len; @@ -4233,7 +4243,7 @@ */ buf_size = (uint16_t)(rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM); - buf_size = ROUND_UP(buf_size, 0x1 << 10); + buf_size = ROUND_DOWN(buf_size, 0x1 << 10); srrctl |= TXGBE_RXCFG_PKTLEN(buf_size); wr32(hw, TXGBE_RXCFG(rxq->reg_idx), srrctl); diff -Nru dpdk-20.11.7/drivers/net/vhost/rte_eth_vhost.c dpdk-20.11.8/drivers/net/vhost/rte_eth_vhost.c --- dpdk-20.11.7/drivers/net/vhost/rte_eth_vhost.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/vhost/rte_eth_vhost.c 2023-04-27 17:57:22.000000000 +0000 @@ -97,8 +97,9 @@ uint16_t port; uint16_t virtqueue_id; struct vhost_stats stats; - int intr_enable; rte_spinlock_t intr_lock; + struct epoll_event ev; + int kickfd; }; struct pmd_internal { @@ -525,112 +526,68 @@ return list; } -static int +static void eth_vhost_update_intr(struct rte_eth_dev *eth_dev, uint16_t rxq_idx) { - struct rte_intr_handle *handle = eth_dev->intr_handle; - struct rte_epoll_event rev; - int epfd, ret; + struct rte_vhost_vring vring; + struct vhost_queue *vq; - if (!handle) - return 0; + vq = eth_dev->data->rx_queues[rxq_idx]; + if (vq == NULL || vq->vid < 0) + return; - if (handle->efds[rxq_idx] == handle->elist[rxq_idx].fd) - return 0; + if (rte_vhost_get_vhost_vring(vq->vid, (rxq_idx << 1) + 1, &vring) < 0) { + VHOST_LOG(DEBUG, "Failed to get rxq-%d's vring, skip!\n", rxq_idx); + return; + } - VHOST_LOG(INFO, "kickfd for rxq-%d was changed, updating handler.\n", - rxq_idx); + rte_spinlock_lock(&vq->intr_lock); - if (handle->elist[rxq_idx].fd != -1) - VHOST_LOG(ERR, "Unexpected previous kickfd value (Got %d, expected -1).\n", - handle->elist[rxq_idx].fd); - - /* - * First remove invalid epoll event, and then install - * the new one. May be solved with a proper API in the - * future. - */ - epfd = handle->elist[rxq_idx].epfd; - rev = handle->elist[rxq_idx]; - ret = rte_epoll_ctl(epfd, EPOLL_CTL_DEL, rev.fd, - &handle->elist[rxq_idx]); - if (ret) { - VHOST_LOG(ERR, "Delete epoll event failed.\n"); - return ret; - } - - rev.fd = handle->efds[rxq_idx]; - handle->elist[rxq_idx] = rev; - ret = rte_epoll_ctl(epfd, EPOLL_CTL_ADD, rev.fd, - &handle->elist[rxq_idx]); - if (ret) { - VHOST_LOG(ERR, "Add epoll event failed.\n"); - return ret; + /* Remove previous kickfd from proxy epoll */ + if (vq->kickfd >= 0 && vq->kickfd != vring.kickfd) { + if (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_DEL, vq->kickfd, &vq->ev) < 0) { + VHOST_LOG(DEBUG, "Failed to unregister %d from rxq-%d epoll: %s\n", + vq->kickfd, rxq_idx, strerror(errno)); + } else { + VHOST_LOG(DEBUG, "Unregistered %d from rxq-%d epoll\n", + vq->kickfd, rxq_idx); + } + vq->kickfd = -1; } - return 0; + /* Add new one, if valid */ + if (vq->kickfd != vring.kickfd && vring.kickfd >= 0) { + if (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_ADD, vring.kickfd, &vq->ev) < 0) { + VHOST_LOG(ERR, "Failed to register %d in rxq-%d epoll: %s\n", + vring.kickfd, rxq_idx, strerror(errno)); + } else { + vq->kickfd = vring.kickfd; + VHOST_LOG(DEBUG, "Registered %d in rxq-%d epoll\n", + vq->kickfd, rxq_idx); + } + } + + rte_spinlock_unlock(&vq->intr_lock); } static int eth_rxq_intr_enable(struct rte_eth_dev *dev, uint16_t qid) { - struct rte_vhost_vring vring; - struct vhost_queue *vq; - int old_intr_enable, ret = 0; + struct vhost_queue *vq = dev->data->rx_queues[qid]; - vq = dev->data->rx_queues[qid]; - if (!vq) { - VHOST_LOG(ERR, "rxq%d is not setup yet\n", qid); - return -1; - } + if (vq->vid >= 0) + rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 1); - rte_spinlock_lock(&vq->intr_lock); - old_intr_enable = vq->intr_enable; - vq->intr_enable = 1; - ret = eth_vhost_update_intr(dev, qid); - rte_spinlock_unlock(&vq->intr_lock); - - if (ret < 0) { - VHOST_LOG(ERR, "Failed to update rxq%d's intr\n", qid); - vq->intr_enable = old_intr_enable; - return ret; - } - - ret = rte_vhost_get_vhost_vring(vq->vid, (qid << 1) + 1, &vring); - if (ret < 0) { - VHOST_LOG(ERR, "Failed to get rxq%d's vring\n", qid); - return ret; - } - VHOST_LOG(INFO, "Enable interrupt for rxq%d\n", qid); - rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 1); - rte_wmb(); - - return ret; + return 0; } static int eth_rxq_intr_disable(struct rte_eth_dev *dev, uint16_t qid) { - struct rte_vhost_vring vring; - struct vhost_queue *vq; - int ret = 0; - - vq = dev->data->rx_queues[qid]; - if (!vq) { - VHOST_LOG(ERR, "rxq%d is not setup yet\n", qid); - return -1; - } + struct vhost_queue *vq = dev->data->rx_queues[qid]; - ret = rte_vhost_get_vhost_vring(vq->vid, (qid << 1) + 1, &vring); - if (ret < 0) { - VHOST_LOG(ERR, "Failed to get rxq%d's vring", qid); - return ret; - } - VHOST_LOG(INFO, "Disable interrupt for rxq%d\n", qid); - rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 0); - rte_wmb(); - - vq->intr_enable = 0; + if (vq->vid >= 0) + rte_vhost_enable_guest_notification(vq->vid, (qid << 1) + 1, 0); return 0; } @@ -641,70 +598,64 @@ struct rte_intr_handle *intr_handle = dev->intr_handle; if (intr_handle) { + int i; + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + int epoll_fd = intr_handle->efds[i]; + + if (epoll_fd >= 0) + close(epoll_fd); + } if (intr_handle->intr_vec) free(intr_handle->intr_vec); free(intr_handle); } - dev->intr_handle = NULL; } static int eth_vhost_install_intr(struct rte_eth_dev *dev) { - struct rte_vhost_vring vring; - struct vhost_queue *vq; int nb_rxq = dev->data->nb_rx_queues; - int i; - int ret; + struct vhost_queue *vq; - /* uninstall firstly if we are reconnecting */ - if (dev->intr_handle) - eth_vhost_uninstall_intr(dev); + int ret; + int i; dev->intr_handle = malloc(sizeof(*dev->intr_handle)); if (!dev->intr_handle) { VHOST_LOG(ERR, "Fail to allocate intr_handle\n"); - return -ENOMEM; + ret = -ENOMEM; + goto error; } memset(dev->intr_handle, 0, sizeof(*dev->intr_handle)); - dev->intr_handle->efd_counter_size = sizeof(uint64_t); - dev->intr_handle->intr_vec = malloc(nb_rxq * sizeof(dev->intr_handle->intr_vec[0])); if (!dev->intr_handle->intr_vec) { VHOST_LOG(ERR, "Failed to allocate memory for interrupt vector\n"); - free(dev->intr_handle); - return -ENOMEM; + ret = -ENOMEM; + goto error; } - VHOST_LOG(INFO, "Prepare intr vec\n"); + VHOST_LOG(DEBUG, "Prepare intr vec\n"); for (i = 0; i < nb_rxq; i++) { - dev->intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + i; - dev->intr_handle->efds[i] = -1; - vq = dev->data->rx_queues[i]; - if (!vq) { - VHOST_LOG(INFO, "rxq-%d not setup yet, skip!\n", i); - continue; - } + int epoll_fd = epoll_create1(0); - ret = rte_vhost_get_vhost_vring(vq->vid, (i << 1) + 1, &vring); - if (ret < 0) { - VHOST_LOG(INFO, - "Failed to get rxq-%d's vring, skip!\n", i); - continue; + if (epoll_fd < 0) { + VHOST_LOG(ERR, "Failed to create proxy epoll fd for rxq-%d\n", i); + ret = -errno; + goto error; } - if (vring.kickfd < 0) { - VHOST_LOG(INFO, - "rxq-%d's kickfd is invalid, skip!\n", i); - continue; - } - dev->intr_handle->efds[i] = vring.kickfd; - VHOST_LOG(INFO, "Installed intr vec for rxq-%d\n", i); + dev->intr_handle->intr_vec[i] = RTE_INTR_VEC_RXTX_OFFSET + i; + dev->intr_handle->efds[i] = epoll_fd; + vq = dev->data->rx_queues[i]; + memset(&vq->ev, 0, sizeof(vq->ev)); + vq->ev.events = EPOLLIN; + vq->ev.data.fd = epoll_fd; } dev->intr_handle->nb_efd = nb_rxq; @@ -712,6 +663,50 @@ dev->intr_handle->type = RTE_INTR_HANDLE_VDEV; return 0; + +error: + eth_vhost_uninstall_intr(dev); + return ret; +} + +static void +eth_vhost_configure_intr(struct rte_eth_dev *dev) +{ + int i; + + VHOST_LOG(DEBUG, "Configure intr vec\n"); + for (i = 0; i < dev->data->nb_rx_queues; i++) + eth_vhost_update_intr(dev, i); +} + +static void +eth_vhost_unconfigure_intr(struct rte_eth_dev *eth_dev) +{ + struct vhost_queue *vq; + int i; + + VHOST_LOG(DEBUG, "Unconfigure intr vec\n"); + for (i = 0; i < eth_dev->data->nb_rx_queues; i++) { + vq = eth_dev->data->rx_queues[i]; + if (vq == NULL || vq->vid < 0) + continue; + + rte_spinlock_lock(&vq->intr_lock); + + /* Remove previous kickfd from proxy epoll */ + if (vq->kickfd >= 0) { + if (epoll_ctl(vq->ev.data.fd, EPOLL_CTL_DEL, vq->kickfd, &vq->ev) < 0) { + VHOST_LOG(DEBUG, "Failed to unregister %d from rxq-%d epoll: %s\n", + vq->kickfd, i, strerror(errno)); + } else { + VHOST_LOG(DEBUG, "Unregistered %d from rxq-%d epoll\n", + vq->kickfd, i); + } + vq->kickfd = -1; + } + + rte_spinlock_unlock(&vq->intr_lock); + } } static void @@ -815,16 +810,8 @@ internal->vid = vid; if (rte_atomic32_read(&internal->started) == 1) { queue_setup(eth_dev, internal); - - if (dev_conf->intr_conf.rxq) { - if (eth_vhost_install_intr(eth_dev) < 0) { - VHOST_LOG(INFO, - "Failed to install interrupt handler."); - return -1; - } - } - } else { - VHOST_LOG(INFO, "RX/TX queues not exist yet\n"); + if (dev_conf->intr_conf.rxq) + eth_vhost_configure_intr(eth_dev); } for (i = 0; i < rte_vhost_get_vring_num(vid); i++) @@ -866,6 +853,7 @@ rte_atomic32_set(&internal->dev_attached, 0); update_queuing_status(eth_dev, true); + eth_vhost_unconfigure_intr(eth_dev); eth_dev->data->dev_link.link_status = ETH_LINK_DOWN; @@ -894,53 +882,11 @@ rte_spinlock_unlock(&state->lock); VHOST_LOG(INFO, "Vhost device %d destroyed\n", vid); - eth_vhost_uninstall_intr(eth_dev); rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL); } static int -vring_conf_update(int vid, struct rte_eth_dev *eth_dev, uint16_t vring_id) -{ - struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf; - struct pmd_internal *internal = eth_dev->data->dev_private; - struct vhost_queue *vq; - struct rte_vhost_vring vring; - int rx_idx = vring_id % 2 ? (vring_id - 1) >> 1 : -1; - int ret = 0; - - /* - * The vring kickfd may be changed after the new device notification. - * Update it when the vring state is updated. - */ - if (rx_idx >= 0 && rx_idx < eth_dev->data->nb_rx_queues && - rte_atomic32_read(&internal->dev_attached) && - rte_atomic32_read(&internal->started) && - dev_conf->intr_conf.rxq) { - ret = rte_vhost_get_vhost_vring(vid, vring_id, &vring); - if (ret) { - VHOST_LOG(ERR, "Failed to get vring %d information.\n", - vring_id); - return ret; - } - eth_dev->intr_handle->efds[rx_idx] = vring.kickfd; - - vq = eth_dev->data->rx_queues[rx_idx]; - if (!vq) { - VHOST_LOG(ERR, "rxq%d is not setup yet\n", rx_idx); - return -1; - } - - rte_spinlock_lock(&vq->intr_lock); - if (vq->intr_enable) - ret = eth_vhost_update_intr(eth_dev, rx_idx); - rte_spinlock_unlock(&vq->intr_lock); - } - - return ret; -} - -static int vring_state_changed(int vid, uint16_t vring, int enable) { struct rte_vhost_vring_state *state; @@ -959,9 +905,8 @@ /* won't be NULL */ state = vring_states[eth_dev->data->port_id]; - if (enable && vring_conf_update(vid, eth_dev, vring)) - VHOST_LOG(INFO, "Failed to update vring-%d configuration.\n", - (int)vring); + if (eth_dev->data->dev_conf.intr_conf.rxq && vring % 2) + eth_vhost_update_intr(eth_dev, (vring - 1) >> 1); rte_spinlock_lock(&state->lock); if (state->cur[vring] == enable) { @@ -1146,18 +1091,17 @@ struct pmd_internal *internal = eth_dev->data->dev_private; struct rte_eth_conf *dev_conf = ð_dev->data->dev_conf; - queue_setup(eth_dev, internal); - - if (rte_atomic32_read(&internal->dev_attached) == 1) { - if (dev_conf->intr_conf.rxq) { - if (eth_vhost_install_intr(eth_dev) < 0) { - VHOST_LOG(INFO, - "Failed to install interrupt handler."); - return -1; - } - } + eth_vhost_uninstall_intr(eth_dev); + if (dev_conf->intr_conf.rxq && eth_vhost_install_intr(eth_dev) < 0) { + VHOST_LOG(ERR, "Failed to install interrupt handler.\n"); + return -1; } + queue_setup(eth_dev, internal); + if (rte_atomic32_read(&internal->dev_attached) == 1 && + dev_conf->intr_conf.rxq) + eth_vhost_configure_intr(eth_dev); + rte_atomic32_set(&internal->started, 1); update_queuing_status(eth_dev, false); @@ -1212,6 +1156,8 @@ rte_free(internal->iface_name); rte_free(internal); + eth_vhost_uninstall_intr(dev); + dev->data->dev_private = NULL; rte_free(vring_states[dev->data->port_id]); @@ -1239,6 +1185,7 @@ vq->mb_pool = mb_pool; vq->virtqueue_id = rx_queue_id * VIRTIO_QNUM + VIRTIO_TXQ; rte_spinlock_init(&vq->intr_lock); + vq->kickfd = -1; dev->data->rx_queues[rx_queue_id] = vq; return 0; @@ -1261,6 +1208,7 @@ vq->virtqueue_id = tx_queue_id * VIRTIO_QNUM + VIRTIO_RXQ; rte_spinlock_init(&vq->intr_lock); + vq->kickfd = -1; dev->data->tx_queues[tx_queue_id] = vq; return 0; diff -Nru dpdk-20.11.7/drivers/net/virtio/virtio_ethdev.c dpdk-20.11.8/drivers/net/virtio/virtio_ethdev.c --- dpdk-20.11.7/drivers/net/virtio/virtio_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/virtio/virtio_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -2097,6 +2097,9 @@ static int vdpa_check_handler(__rte_unused const char *key, const char *value, void *ret_val) { + if (value == NULL || ret_val == NULL) + return -EINVAL; + if (strcmp(value, "1") == 0) *(int *)ret_val = 1; else @@ -2134,6 +2137,9 @@ static int vectorized_check_handler(__rte_unused const char *key, const char *value, void *ret_val) { + if (value == NULL || ret_val == NULL) + return -EINVAL; + if (strcmp(value, "1") == 0) *(int *)ret_val = 1; else diff -Nru dpdk-20.11.7/drivers/net/virtio/virtio_pci.c dpdk-20.11.8/drivers/net/virtio/virtio_pci.c --- dpdk-20.11.7/drivers/net/virtio/virtio_pci.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/virtio/virtio_pci.c 2023-04-27 17:57:22.000000000 +0000 @@ -31,22 +31,6 @@ #define VIRTIO_PCI_CONFIG(hw) \ (((hw)->use_msix == VIRTIO_MSIX_ENABLED) ? 24 : 20) -static inline int -check_vq_phys_addr_ok(struct virtqueue *vq) -{ - /* Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit, - * and only accepts 32 bit page frame number. - * Check if the allocated physical memory exceeds 16TB. - */ - if ((vq->vq_ring_mem + vq->vq_ring_size - 1) >> - (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) { - PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!"); - return 0; - } - - return 1; -} - /* * Since we are in legacy mode: * http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf @@ -213,8 +197,15 @@ { uint32_t src; - if (!check_vq_phys_addr_ok(vq)) + /* Virtio PCI device VIRTIO_PCI_QUEUE_PFN register is 32bit, + * and only accepts 32 bit page frame number. + * Check if the allocated physical memory exceeds 16TB. + */ + if ((vq->vq_ring_mem + vq->vq_ring_size - 1) >> + (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) { + PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!"); return -1; + } rte_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2, VIRTIO_PCI_QUEUE_SEL); @@ -366,9 +357,6 @@ uint64_t desc_addr, avail_addr, used_addr; uint16_t notify_off; - if (!check_vq_phys_addr_ok(vq)) - return -1; - desc_addr = vq->vq_ring_mem; avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc); used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail, diff -Nru dpdk-20.11.7/drivers/net/virtio/virtio_rxtx.c dpdk-20.11.8/drivers/net/virtio/virtio_rxtx.c --- dpdk-20.11.7/drivers/net/virtio/virtio_rxtx.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/virtio/virtio_rxtx.c 2023-04-27 17:57:22.000000000 +0000 @@ -421,29 +421,36 @@ if (likely(rte_pktmbuf_data_len(m) >= m->l2_len + m->l3_len + m->l4_len)) { struct rte_ipv4_hdr *iph; - struct rte_ipv6_hdr *ip6h; struct rte_tcp_hdr *th; - uint16_t prev_cksum, new_cksum, ip_len, ip_paylen; + uint16_t prev_cksum, new_cksum; + uint32_t ip_paylen; uint32_t tmp; iph = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *, m->l2_len); th = RTE_PTR_ADD(iph, m->l3_len); + + /* + * Calculate IPv4 header checksum with current total length value + * (whatever it is) to have correct checksum after update on edits + * done by TSO. + */ if ((iph->version_ihl >> 4) == 4) { iph->hdr_checksum = 0; iph->hdr_checksum = rte_ipv4_cksum(iph); - ip_len = iph->total_length; - ip_paylen = rte_cpu_to_be_16(rte_be_to_cpu_16(ip_len) - - m->l3_len); - } else { - ip6h = (struct rte_ipv6_hdr *)iph; - ip_paylen = ip6h->payload_len; } + /* + * Do not use IPv4 total length and IPv6 payload length fields to get + * TSO payload length since it could not fit into 16 bits. + */ + ip_paylen = rte_cpu_to_be_32(rte_pktmbuf_pkt_len(m) - m->l2_len - + m->l3_len); + /* calculate the new phdr checksum not including ip_paylen */ prev_cksum = th->cksum; tmp = prev_cksum; - tmp += ip_paylen; + tmp += (ip_paylen & 0xffff) + (ip_paylen >> 16); tmp = (tmp & 0xffff) + (tmp >> 16); new_cksum = tmp; diff -Nru dpdk-20.11.7/drivers/net/virtio/virtio_user_ethdev.c dpdk-20.11.8/drivers/net/virtio/virtio_user_ethdev.c --- dpdk-20.11.7/drivers/net/virtio/virtio_user_ethdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/net/virtio/virtio_user_ethdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -317,10 +317,15 @@ if (status & VIRTIO_CONFIG_STATUS_FEATURES_OK && ~old_status & VIRTIO_CONFIG_STATUS_FEATURES_OK) virtio_user_dev_set_features(dev); - if (status & VIRTIO_CONFIG_STATUS_DRIVER_OK) - virtio_user_start_device(dev); - else if (status == VIRTIO_CONFIG_STATUS_RESET) + + if (status & VIRTIO_CONFIG_STATUS_DRIVER_OK) { + if (virtio_user_start_device(dev)) { + virtio_user_dev_update_status(dev); + return; + } + } else if (status == VIRTIO_CONFIG_STATUS_RESET) { virtio_user_reset(hw); + } virtio_user_dev_set_status(dev, status); } diff -Nru dpdk-20.11.7/drivers/raw/ifpga/base/opae_hw_api.c dpdk-20.11.8/drivers/raw/ifpga/base/opae_hw_api.c --- dpdk-20.11.7/drivers/raw/ifpga/base/opae_hw_api.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/raw/ifpga/base/opae_hw_api.c 2023-04-27 17:57:22.000000000 +0000 @@ -380,7 +380,7 @@ PROT_READ | PROT_WRITE, MAP_SHARED, shm_id, 0); adapter->lock = (pthread_mutex_t *)ptr; - if (ptr) { + if (ptr != MAP_FAILED) { dev_info(NULL, "shared memory %s address is %p\n", shm_name, ptr); @@ -497,7 +497,7 @@ adapter->shm.size = size; adapter->shm.ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_id, 0); - if (adapter->shm.ptr) { + if (adapter->shm.ptr != MAP_FAILED) { dev_info(NULL, "shared memory %s address is %p\n", shm_name, adapter->shm.ptr); diff -Nru dpdk-20.11.7/drivers/raw/skeleton/skeleton_rawdev.c dpdk-20.11.8/drivers/raw/skeleton/skeleton_rawdev.c --- dpdk-20.11.7/drivers/raw/skeleton/skeleton_rawdev.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/raw/skeleton/skeleton_rawdev.c 2023-04-27 17:57:22.000000000 +0000 @@ -421,7 +421,7 @@ * help in complex implementation which require more information than * just an integer - for example, a queue-pair. */ - q_id = *((int *)context); + q_id = *((uint16_t *)context); for (i = 0; i < count; i++) queue_buf[q_id].bufs[i] = buffers[i]->buf_addr; @@ -443,7 +443,7 @@ * help in complex implementation which require more information than * just an integer - for example, a queue-pair. */ - q_id = *((int *)context); + q_id = *((uint16_t *)context); for (i = 0; i < count; i++) buffers[i]->buf_addr = queue_buf[q_id].bufs[i]; @@ -659,6 +659,8 @@ void *opaque) { int *flag = opaque; + if (value == NULL || opaque == NULL) + return -EINVAL; *flag = atoi(value); return 0; } diff -Nru dpdk-20.11.7/drivers/raw/skeleton/skeleton_rawdev_test.c dpdk-20.11.8/drivers/raw/skeleton/skeleton_rawdev_test.c --- dpdk-20.11.7/drivers/raw/skeleton/skeleton_rawdev_test.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/raw/skeleton/skeleton_rawdev_test.c 2023-04-27 17:57:22.000000000 +0000 @@ -368,42 +368,34 @@ test_rawdev_enqdeq(void) { int ret; - unsigned int count = 1; uint16_t queue_id = 0; - struct rte_rawdev_buf buffers[1]; - struct rte_rawdev_buf *deq_buffers = NULL; - - buffers[0].buf_addr = malloc(strlen(TEST_DEV_NAME) + 3); - if (!buffers[0].buf_addr) - goto cleanup; - snprintf(buffers[0].buf_addr, strlen(TEST_DEV_NAME) + 2, "%s%d", + struct rte_rawdev_buf buffer; + struct rte_rawdev_buf *buffers[1]; + struct rte_rawdev_buf deq_buffer; + struct rte_rawdev_buf *deq_buffers[1]; + + buffers[0] = &buffer; + buffer.buf_addr = malloc(strlen(TEST_DEV_NAME) + 3); + if (!buffer.buf_addr) + return TEST_FAILED; + snprintf(buffer.buf_addr, strlen(TEST_DEV_NAME) + 2, "%s%d", TEST_DEV_NAME, 0); - ret = rte_rawdev_enqueue_buffers(test_dev_id, - (struct rte_rawdev_buf **)&buffers, - count, &queue_id); - RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count, + ret = rte_rawdev_enqueue_buffers(test_dev_id, buffers, + RTE_DIM(buffers), &queue_id); + RTE_TEST_ASSERT_EQUAL((unsigned int)ret, RTE_DIM(buffers), "Unable to enqueue buffers"); - deq_buffers = malloc(sizeof(struct rte_rawdev_buf) * count); - if (!deq_buffers) - goto cleanup; - - ret = rte_rawdev_dequeue_buffers(test_dev_id, - (struct rte_rawdev_buf **)&deq_buffers, - count, &queue_id); - RTE_TEST_ASSERT_EQUAL((unsigned int)ret, count, + deq_buffers[0] = &deq_buffer; + ret = rte_rawdev_dequeue_buffers(test_dev_id, deq_buffers, + RTE_DIM(deq_buffers), &queue_id); + RTE_TEST_ASSERT_EQUAL((unsigned int)ret, RTE_DIM(buffers), "Unable to dequeue buffers"); + RTE_TEST_ASSERT_EQUAL(deq_buffers[0]->buf_addr, buffers[0]->buf_addr, + "Did not retrieve expected object"); - if (deq_buffers) - free(deq_buffers); - + free(buffer.buf_addr); return TEST_SUCCESS; -cleanup: - if (buffers[0].buf_addr) - free(buffers[0].buf_addr); - - return TEST_FAILED; } static void skeldev_test_run(int (*setup)(void), diff -Nru dpdk-20.11.7/drivers/vdpa/ifc/ifcvf_vdpa.c dpdk-20.11.8/drivers/vdpa/ifc/ifcvf_vdpa.c --- dpdk-20.11.7/drivers/vdpa/ifc/ifcvf_vdpa.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/drivers/vdpa/ifc/ifcvf_vdpa.c 2023-04-27 17:57:22.000000000 +0000 @@ -842,6 +842,8 @@ vdpa_ifcvf_stop(internal); vdpa_disable_vfio_intr(internal); + rte_atomic32_set(&internal->running, 0); + ret = rte_vhost_host_notifier_ctrl(vid, RTE_VHOST_QUEUE_ALL, false); if (ret && ret != -ENOTSUP) goto error; @@ -1253,6 +1255,11 @@ goto error; } internal->sw_lm = sw_fallback_lm; + if (!internal->sw_lm && !internal->hw.lm_cfg) { + DRV_LOG(ERR, "Device %s does not support HW assist live migration, please enable sw-live-migration!", + pci_dev->name); + goto error; + } internal->vdev = rte_vdpa_register_device(&pci_dev->device, &ifcvf_ops); if (internal->vdev == NULL) { diff -Nru dpdk-20.11.7/examples/cmdline/parse_obj_list.h dpdk-20.11.8/examples/cmdline/parse_obj_list.h --- dpdk-20.11.7/examples/cmdline/parse_obj_list.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/examples/cmdline/parse_obj_list.h 2023-04-27 17:57:22.000000000 +0000 @@ -12,8 +12,9 @@ #include #include +#include -#define OBJ_NAME_LEN_MAX 64 +#define OBJ_NAME_LEN_MAX sizeof(cmdline_fixed_string_t) struct object { SLIST_ENTRY(object) next; diff -Nru dpdk-20.11.7/examples/qos_sched/init.c dpdk-20.11.8/examples/qos_sched/init.c --- dpdk-20.11.7/examples/qos_sched/init.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/examples/qos_sched/init.c 2023-04-27 17:57:22.000000000 +0000 @@ -82,6 +82,7 @@ if (app_inited_port_mask & (1u << portid)) return 0; + memset(&rx_conf, 0, sizeof(struct rte_eth_rxconf)); rx_conf.rx_thresh.pthresh = rx_thresh.pthresh; rx_conf.rx_thresh.hthresh = rx_thresh.hthresh; rx_conf.rx_thresh.wthresh = rx_thresh.wthresh; @@ -89,6 +90,7 @@ rx_conf.rx_drop_en = 0; rx_conf.rx_deferred_start = 0; + memset(&tx_conf, 0, sizeof(struct rte_eth_txconf)); tx_conf.tx_thresh.pthresh = tx_thresh.pthresh; tx_conf.tx_thresh.hthresh = tx_thresh.hthresh; tx_conf.tx_thresh.wthresh = tx_thresh.wthresh; @@ -385,6 +387,8 @@ for(i = 0; i < nb_pfc; i++) { uint32_t socket = rte_lcore_to_socket_id(qos_conf[i].rx_core); struct rte_ring *ring; + struct rte_eth_link link = {0}; + int retry_count = 100, retry_delay = 100; /* try every 100ms for 10 sec */ snprintf(ring_name, MAX_NAME_LEN, "ring-%u-%u", i, qos_conf[i].rx_core); ring = rte_ring_lookup(ring_name); @@ -415,6 +419,14 @@ app_init_port(qos_conf[i].rx_port, qos_conf[i].mbuf_pool); app_init_port(qos_conf[i].tx_port, qos_conf[i].mbuf_pool); + rte_eth_link_get(qos_conf[i].tx_port, &link); + if (link.link_status == 0) + printf("Waiting for link on port %u\n", qos_conf[i].tx_port); + while (link.link_status == 0 && retry_count--) { + rte_delay_ms(retry_delay); + rte_eth_link_get(qos_conf[i].tx_port, &link); + } + qos_conf[i].sched_port = app_init_sched_port(qos_conf[i].tx_port, socket); } diff -Nru dpdk-20.11.7/examples/qos_sched/profile.cfg dpdk-20.11.8/examples/qos_sched/profile.cfg --- dpdk-20.11.7/examples/qos_sched/profile.cfg 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/examples/qos_sched/profile.cfg 2023-04-27 17:57:22.000000000 +0000 @@ -26,6 +26,8 @@ number of pipes per subport = 4096 queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 +pipe 0-4095 = 0 ; These pipes are configured with pipe profile 0 + [subport profile 0] tb rate = 1250000000 ; Bytes per second tb size = 1000000 ; Bytes @@ -46,8 +48,6 @@ tc period = 10 ; Milliseconds -pipe 0-4095 = 0 ; These pipes are configured with pipe profile 0 - ; Pipe configuration [pipe profile 0] tb rate = 305175 ; Bytes per second diff -Nru dpdk-20.11.7/examples/qos_sched/profile_ov.cfg dpdk-20.11.8/examples/qos_sched/profile_ov.cfg --- dpdk-20.11.7/examples/qos_sched/profile_ov.cfg 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/examples/qos_sched/profile_ov.cfg 2023-04-27 17:57:22.000000000 +0000 @@ -6,12 +6,14 @@ frame overhead = 24 number of subports per port = 1 +subport 0-8 = 0 + ; Subport configuration [subport 0] number of pipes per subport = 32 queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 -subport 0-8 = 0 +pipe 0-31 = 0 ; These pipes are configured with pipe profile 0 [subport profile 0] tb rate = 8400000 ; Bytes per second @@ -32,8 +34,6 @@ tc 12 rate = 8400000 ; Bytes per second tc period = 10 ; Milliseconds -pipe 0-31 = 0 ; These pipes are configured with pipe profile 0 - ; Pipe configuration [pipe profile 0] tb rate = 16800000 ; Bytes per second diff -Nru dpdk-20.11.7/examples/vm_power_manager/channel_manager.c dpdk-20.11.8/examples/vm_power_manager/channel_manager.c --- dpdk-20.11.7/examples/vm_power_manager/channel_manager.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/examples/vm_power_manager/channel_manager.c 2023-04-27 17:57:22.000000000 +0000 @@ -23,7 +23,6 @@ #include #include #include -#include #include @@ -60,16 +59,16 @@ virDomainInfo info; rte_spinlock_t config_spinlock; int allow_query; - RTE_TAILQ_ENTRY(virtual_machine_info) vms_info; + LIST_ENTRY(virtual_machine_info) vms_info; }; -RTE_TAILQ_HEAD(, virtual_machine_info) vm_list_head; +LIST_HEAD(, virtual_machine_info) vm_list_head; static struct virtual_machine_info * find_domain_by_name(const char *name) { struct virtual_machine_info *info; - RTE_TAILQ_FOREACH(info, &vm_list_head, vms_info) { + LIST_FOREACH(info, &vm_list_head, vms_info) { if (!strncmp(info->name, name, CHANNEL_MGR_MAX_NAME_LEN-1)) return info; } @@ -878,7 +877,7 @@ new_domain->allow_query = 0; rte_spinlock_init(&(new_domain->config_spinlock)); - TAILQ_INSERT_HEAD(&vm_list_head, new_domain, vms_info); + LIST_INSERT_HEAD(&vm_list_head, new_domain, vms_info); return 0; } @@ -900,7 +899,7 @@ rte_spinlock_unlock(&vm_info->config_spinlock); return -1; } - TAILQ_REMOVE(&vm_list_head, vm_info, vms_info); + LIST_REMOVE(vm_info, vms_info); rte_spinlock_unlock(&vm_info->config_spinlock); rte_free(vm_info); return 0; @@ -953,7 +952,7 @@ { virNodeInfo info; - TAILQ_INIT(&vm_list_head); + LIST_INIT(&vm_list_head); if (connect_hypervisor(path) < 0) { global_n_host_cpus = 64; global_hypervisor_available = 0; @@ -1005,9 +1004,9 @@ { unsigned i; char mask[RTE_MAX_LCORE]; - struct virtual_machine_info *vm_info, *tmp; + struct virtual_machine_info *vm_info; - RTE_TAILQ_FOREACH_SAFE(vm_info, &vm_list_head, vms_info, tmp) { + LIST_FOREACH(vm_info, &vm_list_head, vms_info) { rte_spinlock_lock(&(vm_info->config_spinlock)); @@ -1022,7 +1021,7 @@ } rte_spinlock_unlock(&(vm_info->config_spinlock)); - TAILQ_REMOVE(&vm_list_head, vm_info, vms_info); + LIST_REMOVE(vm_info, vms_info); rte_free(vm_info); } diff -Nru dpdk-20.11.7/kernel/linux/kni/compat.h dpdk-20.11.8/kernel/linux/kni/compat.h --- dpdk-20.11.7/kernel/linux/kni/compat.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/kernel/linux/kni/compat.h 2023-04-27 17:57:22.000000000 +0000 @@ -146,6 +146,8 @@ #define HAVE_ETH_HW_ADDR_SET #endif -#if KERNEL_VERSION(5, 18, 0) > LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 18, 0) > LINUX_VERSION_CODE && \ + (!(defined(RHEL_RELEASE_CODE) && \ + RHEL_RELEASE_VERSION(9, 1) <= RHEL_RELEASE_CODE)) #define HAVE_NETIF_RX_NI #endif diff -Nru dpdk-20.11.7/lib/librte_acl/acl_run_altivec.h dpdk-20.11.8/lib/librte_acl/acl_run_altivec.h --- dpdk-20.11.7/lib/librte_acl/acl_run_altivec.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_acl/acl_run_altivec.h 2023-04-27 17:57:22.000000000 +0000 @@ -102,7 +102,7 @@ /* * Process 4 transitions (in 2 XMM registers) in parallel */ -static inline __attribute__((optimize("O2"))) xmm_t +static __rte_always_inline xmm_t transition4(xmm_t next_input, const uint64_t *trans, xmm_t *indices1, xmm_t *indices2) { diff -Nru dpdk-20.11.7/lib/librte_cmdline/cmdline.c dpdk-20.11.8/lib/librte_cmdline/cmdline.c --- dpdk-20.11.7/lib/librte_cmdline/cmdline.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cmdline/cmdline.c 2023-04-27 17:57:22.000000000 +0000 @@ -181,6 +181,7 @@ { if (!cl) return; + cmdline_cancel(cl); rdline_quit(&cl->rdl); } @@ -205,9 +206,14 @@ if (read_status < 0) return read_status; - status = cmdline_in(cl, &c, 1); - if (status < 0 && cl->rdl.status != RDLINE_EXITED) - return status; + if (read_status == 0) { + /* end of file is implicit quit */ + cmdline_quit(cl); + } else { + status = cmdline_in(cl, &c, 1); + if (status < 0 && cl->rdl.status != RDLINE_EXITED) + return status; + } } return cl->rdl.status; diff -Nru dpdk-20.11.7/lib/librte_cmdline/cmdline_os_unix.c dpdk-20.11.8/lib/librte_cmdline/cmdline_os_unix.c --- dpdk-20.11.7/lib/librte_cmdline/cmdline_os_unix.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cmdline/cmdline_os_unix.c 2023-04-27 17:57:22.000000000 +0000 @@ -51,3 +51,9 @@ { return vdprintf(fd, format, op); } + +/* This function is not needed on Linux, instead use sigaction() */ +void +cmdline_cancel(__rte_unused struct cmdline *cl) +{ +} diff -Nru dpdk-20.11.7/lib/librte_cmdline/cmdline_os_windows.c dpdk-20.11.8/lib/librte_cmdline/cmdline_os_windows.c --- dpdk-20.11.7/lib/librte_cmdline/cmdline_os_windows.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cmdline/cmdline_os_windows.c 2023-04-27 17:57:22.000000000 +0000 @@ -205,3 +205,17 @@ return ret; } + +void +cmdline_cancel(struct cmdline *cl) +{ + if (!cl) + return; + + /* force the outstanding read on console to exit */ + if (cl->oldterm.is_console_input) { + HANDLE handle = (HANDLE)_get_osfhandle(cl->s_in); + + CancelIoEx(handle, NULL); + } +} diff -Nru dpdk-20.11.7/lib/librte_cmdline/cmdline_private.h dpdk-20.11.8/lib/librte_cmdline/cmdline_private.h --- dpdk-20.11.7/lib/librte_cmdline/cmdline_private.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cmdline/cmdline_private.h 2023-04-27 17:57:22.000000000 +0000 @@ -46,6 +46,9 @@ /* Read one character from input. */ ssize_t cmdline_read_char(struct cmdline *cl, char *c); +/* Force current cmdline read to unblock. */ +void cmdline_cancel(struct cmdline *cl); + /* vdprintf(3) */ __rte_format_printf(2, 0) int cmdline_vdprintf(int fd, const char *format, va_list op); diff -Nru dpdk-20.11.7/lib/librte_compressdev/rte_compressdev.h dpdk-20.11.8/lib/librte_compressdev/rte_compressdev.h --- dpdk-20.11.7/lib/librte_compressdev/rte_compressdev.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_compressdev/rte_compressdev.h 2023-04-27 17:57:22.000000000 +0000 @@ -353,7 +353,7 @@ * @note The capabilities field of dev_info is set to point to the first * element of an array of struct rte_compressdev_capabilities. * The element after the last valid element has it's op field set to - * RTE_COMP_ALGO_LIST_END. + * RTE_COMP_ALGO_UNSPECIFIED. */ __rte_experimental void diff -Nru dpdk-20.11.7/lib/librte_compressdev/rte_compressdev_pmd.c dpdk-20.11.8/lib/librte_compressdev/rte_compressdev_pmd.c --- dpdk-20.11.7/lib/librte_compressdev/rte_compressdev_pmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_compressdev/rte_compressdev_pmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -20,6 +20,9 @@ struct rte_compressdev_pmd_init_params *params = extra_args; int n; + if (value == NULL || extra_args == NULL) + return -EINVAL; + n = strlcpy(params->name, value, RTE_COMPRESSDEV_NAME_MAX_LEN); if (n >= RTE_COMPRESSDEV_NAME_MAX_LEN) return -EINVAL; @@ -37,6 +40,9 @@ int i; char *end; + if (value == NULL || extra_args == NULL) + return -EINVAL; + errno = 0; i = strtol(value, &end, 10); if (*end != 0 || errno != 0 || i < 0) diff -Nru dpdk-20.11.7/lib/librte_cryptodev/rte_crypto_sym.h dpdk-20.11.8/lib/librte_cryptodev/rte_crypto_sym.h --- dpdk-20.11.7/lib/librte_cryptodev/rte_crypto_sym.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cryptodev/rte_crypto_sym.h 2023-04-27 17:57:22.000000000 +0000 @@ -540,6 +540,7 @@ * hold a single transform, the type field is used to specify which transform * is contained within the union */ +/* Structure rte_crypto_sym_xform 8< */ struct rte_crypto_sym_xform { struct rte_crypto_sym_xform *next; /**< next xform in chain */ @@ -555,6 +556,7 @@ /**< AEAD xform */ }; }; +/* >8 End of structure rte_crypto_sym_xform. */ struct rte_cryptodev_sym_session; @@ -588,6 +590,7 @@ * destination buffer being at a different alignment, relative to buffer start, * to the data in the source buffer. */ +/* Structure rte_crypto_sym_op 8< */ struct rte_crypto_sym_op { struct rte_mbuf *m_src; /**< source mbuf */ struct rte_mbuf *m_dst; /**< destination mbuf */ @@ -850,6 +853,7 @@ }; }; }; +/* >8 End of structure rte_crypto_sym_op. */ /** diff -Nru dpdk-20.11.7/lib/librte_cryptodev/rte_cryptodev.h dpdk-20.11.8/lib/librte_cryptodev/rte_cryptodev.h --- dpdk-20.11.7/lib/librte_cryptodev/rte_cryptodev.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cryptodev/rte_cryptodev.h 2023-04-27 17:57:22.000000000 +0000 @@ -474,6 +474,7 @@ rte_cryptodev_get_feature_name(uint64_t flag); /** Crypto device information */ +/* Structure rte_cryptodev_info 8< */ struct rte_cryptodev_info { const char *driver_name; /**< Driver name. */ uint8_t driver_id; /**< Driver identifier */ @@ -502,6 +503,7 @@ */ } sym; }; +/* >8 End of structure rte_cryptodev_info. */ #define RTE_CRYPTODEV_DETACHED (0) #define RTE_CRYPTODEV_ATTACHED (1) @@ -514,6 +516,7 @@ }; /** Crypto device queue pair configuration structure. */ +/* Structure rte_cryptodev_qp_conf 8<*/ struct rte_cryptodev_qp_conf { uint32_t nb_descriptors; /**< Number of descriptors per queue pair */ struct rte_mempool *mp_session; @@ -521,6 +524,7 @@ struct rte_mempool *mp_session_private; /**< The mempool for creating sess private data in sessionless mode */ }; +/* >8 End of structure rte_cryptodev_qp_conf. */ /** * Typedef for application callback function to be registered by application @@ -625,6 +629,7 @@ rte_cryptodev_socket_id(uint8_t dev_id); /** Crypto device configuration structure */ +/* Structure rte_cryptodev_config 8< */ struct rte_cryptodev_config { int socket_id; /**< Socket to allocate resources on */ uint16_t nb_queue_pairs; @@ -637,6 +642,7 @@ * - RTE_CRYTPODEV_FF_SECURITY */ }; +/* >8 End of structure rte_cryptodev_config. */ /** * Configure a device. diff -Nru dpdk-20.11.7/lib/librte_cryptodev/rte_cryptodev_pmd.c dpdk-20.11.8/lib/librte_cryptodev/rte_cryptodev_pmd.c --- dpdk-20.11.7/lib/librte_cryptodev/rte_cryptodev_pmd.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cryptodev/rte_cryptodev_pmd.c 2023-04-27 17:57:22.000000000 +0000 @@ -17,6 +17,9 @@ struct rte_cryptodev_pmd_init_params *params = extra_args; int n; + if (value == NULL || extra_args == NULL) + return -EINVAL; + n = strlcpy(params->name, value, RTE_CRYPTODEV_NAME_MAX_LEN); if (n >= RTE_CRYPTODEV_NAME_MAX_LEN) return -EINVAL; @@ -33,6 +36,10 @@ { int i; char *end; + + if (value == NULL || extra_args == NULL) + return -EINVAL; + errno = 0; i = strtol(value, &end, 10); diff -Nru dpdk-20.11.7/lib/librte_cryptodev/rte_cryptodev_pmd.h dpdk-20.11.8/lib/librte_cryptodev/rte_cryptodev_pmd.h --- dpdk-20.11.7/lib/librte_cryptodev/rte_cryptodev_pmd.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_cryptodev/rte_cryptodev_pmd.h 2023-04-27 17:57:22.000000000 +0000 @@ -491,9 +491,6 @@ * * * @param dev Pointer to cryptodev struct * @param event Crypto device interrupt event type. - * - * @return - * void */ void rte_cryptodev_pmd_callback_process(struct rte_cryptodev *dev, enum rte_cryptodev_event_type event); diff -Nru dpdk-20.11.7/lib/librte_eal/common/eal_common_fbarray.c dpdk-20.11.8/lib/librte_eal/common/eal_common_fbarray.c --- dpdk-20.11.7/lib/librte_eal/common/eal_common_fbarray.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/common/eal_common_fbarray.c 2023-04-27 17:57:22.000000000 +0000 @@ -1485,7 +1485,7 @@ if (fully_validate(arr->name, arr->elt_sz, arr->len)) { fprintf(f, "Invalid file-backed array\n"); - goto out; + return; } /* prevent array from changing under us */ @@ -1499,6 +1499,5 @@ for (i = 0; i < msk->n_masks; i++) fprintf(f, "msk idx %i: 0x%016" PRIx64 "\n", i, msk->data[i]); -out: rte_rwlock_read_unlock(&arr->rwlock); } diff -Nru dpdk-20.11.7/lib/librte_eal/freebsd/eal_alarm.c dpdk-20.11.8/lib/librte_eal/freebsd/eal_alarm.c --- dpdk-20.11.7/lib/librte_eal/freebsd/eal_alarm.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/freebsd/eal_alarm.c 2023-04-27 17:57:22.000000000 +0000 @@ -148,12 +148,12 @@ struct timespec now; struct alarm_entry *ap; - rte_spinlock_lock(&alarm_list_lk); - ap = LIST_FIRST(&alarm_list); - if (clock_gettime(CLOCK_TYPE_ID, &now) < 0) return; + rte_spinlock_lock(&alarm_list_lk); + ap = LIST_FIRST(&alarm_list); + while (ap != NULL && timespec_cmp(&now, &ap->time) >= 0) { ap->executing = 1; ap->executing_id = pthread_self(); diff -Nru dpdk-20.11.7/lib/librte_eal/freebsd/eal_hugepage_info.c dpdk-20.11.8/lib/librte_eal/freebsd/eal_hugepage_info.c --- dpdk-20.11.7/lib/librte_eal/freebsd/eal_hugepage_info.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/freebsd/eal_hugepage_info.c 2023-04-27 17:57:22.000000000 +0000 @@ -33,7 +33,7 @@ } retval = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); close(fd); - return retval; + return retval == MAP_FAILED ? NULL : retval; } static void * diff -Nru dpdk-20.11.7/lib/librte_eal/include/generic/rte_atomic.h dpdk-20.11.8/lib/librte_eal/include/generic/rte_atomic.h --- dpdk-20.11.7/lib/librte_eal/include/generic/rte_atomic.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/include/generic/rte_atomic.h 2023-04-27 17:57:22.000000000 +0000 @@ -175,11 +175,7 @@ static inline uint16_t rte_atomic16_exchange(volatile uint16_t *dst, uint16_t val) { -#if defined(__clang__) return __atomic_exchange_n(dst, val, __ATOMIC_SEQ_CST); -#else - return __atomic_exchange_2(dst, val, __ATOMIC_SEQ_CST); -#endif } #endif @@ -458,11 +454,7 @@ static inline uint32_t rte_atomic32_exchange(volatile uint32_t *dst, uint32_t val) { -#if defined(__clang__) return __atomic_exchange_n(dst, val, __ATOMIC_SEQ_CST); -#else - return __atomic_exchange_4(dst, val, __ATOMIC_SEQ_CST); -#endif } #endif @@ -740,11 +732,7 @@ static inline uint64_t rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val) { -#if defined(__clang__) return __atomic_exchange_n(dst, val, __ATOMIC_SEQ_CST); -#else - return __atomic_exchange_8(dst, val, __ATOMIC_SEQ_CST); -#endif } #endif diff -Nru dpdk-20.11.7/lib/librte_eal/include/rte_bitmap.h dpdk-20.11.8/lib/librte_eal/include/rte_bitmap.h --- dpdk-20.11.7/lib/librte_eal/include/rte_bitmap.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/include/rte_bitmap.h 2023-04-27 17:57:22.000000000 +0000 @@ -327,8 +327,6 @@ * Handle to bitmap instance * @param pos * Bit position - * @return - * 0 upon success, error code otherwise */ static inline void rte_bitmap_prefetch0(struct rte_bitmap *bmp, uint32_t pos) diff -Nru dpdk-20.11.7/lib/librte_eal/include/rte_hexdump.h dpdk-20.11.8/lib/librte_eal/include/rte_hexdump.h --- dpdk-20.11.7/lib/librte_eal/include/rte_hexdump.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/include/rte_hexdump.h 2023-04-27 17:57:22.000000000 +0000 @@ -27,8 +27,6 @@ * This is the buffer address to print out. * @param len * The number of bytes to dump out -* @return -* None. */ extern void @@ -45,8 +43,6 @@ * This is the buffer address to print out. * @param len * The number of bytes to dump out -* @return -* None. */ void diff -Nru dpdk-20.11.7/lib/librte_eal/include/rte_service_component.h dpdk-20.11.8/lib/librte_eal/include/rte_service_component.h --- dpdk-20.11.7/lib/librte_eal/include/rte_service_component.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/include/rte_service_component.h 2023-04-27 17:57:22.000000000 +0000 @@ -130,8 +130,6 @@ /** * @internal Free up the memory that has been initialized. * This routine is to be invoked prior to process termination. - * - * @retval None */ void rte_service_finalize(void); diff -Nru dpdk-20.11.7/lib/librte_eal/linux/eal_hugepage_info.c dpdk-20.11.8/lib/librte_eal/linux/eal_hugepage_info.c --- dpdk-20.11.7/lib/librte_eal/linux/eal_hugepage_info.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/linux/eal_hugepage_info.c 2023-04-27 17:57:22.000000000 +0000 @@ -57,7 +57,7 @@ retval = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); close(fd); - return retval; + return retval == MAP_FAILED ? NULL : retval; } static void * diff -Nru dpdk-20.11.7/lib/librte_eal/windows/eal.c dpdk-20.11.8/lib/librte_eal/windows/eal.c --- dpdk-20.11.7/lib/librte_eal/windows/eal.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/windows/eal.c 2023-04-27 17:57:22.000000000 +0000 @@ -437,6 +437,9 @@ */ rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MAIN); rte_eal_mp_wait_lcore(); + + eal_mcfg_complete(); + return fctret; } diff -Nru dpdk-20.11.7/lib/librte_eal/windows/include/pthread.h dpdk-20.11.8/lib/librte_eal/windows/include/pthread.h --- dpdk-20.11.7/lib/librte_eal/windows/include/pthread.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eal/windows/include/pthread.h 2023-04-27 17:57:22.000000000 +0000 @@ -134,7 +134,8 @@ { RTE_SET_USED(threadattr); HANDLE hThread; - hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, + hThread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE)(uintptr_t)threadfunc, args, 0, (LPDWORD)threadid); if (hThread) { SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); diff -Nru dpdk-20.11.7/lib/librte_eventdev/rte_event_eth_tx_adapter.c dpdk-20.11.8/lib/librte_eventdev/rte_event_eth_tx_adapter.c --- dpdk-20.11.7/lib/librte_eventdev/rte_event_eth_tx_adapter.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eventdev/rte_event_eth_tx_adapter.c 2023-04-27 17:57:22.000000000 +0000 @@ -582,7 +582,7 @@ RTE_ETH_FOREACH_DEV(i) { uint16_t q; - if (i == txa->dev_count) + if (i >= txa->dev_count) break; dev = tdi[i].dev; diff -Nru dpdk-20.11.7/lib/librte_eventdev/rte_event_timer_adapter.c dpdk-20.11.8/lib/librte_eventdev/rte_event_timer_adapter.c --- dpdk-20.11.7/lib/librte_eventdev/rte_event_timer_adapter.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_eventdev/rte_event_timer_adapter.c 2023-04-27 17:57:22.000000000 +0000 @@ -19,6 +19,7 @@ #include #include #include +#include #include "rte_eventdev.h" #include "rte_eventdev_pmd.h" @@ -645,13 +646,51 @@ } } -static __rte_always_inline uint64_t +static __rte_always_inline int get_timeout_cycles(struct rte_event_timer *evtim, - const struct rte_event_timer_adapter *adapter) + const struct rte_event_timer_adapter *adapter, + uint64_t *timeout_cycles) { - struct swtim *sw = swtim_pmd_priv(adapter); - uint64_t timeout_ns = evtim->timeout_ticks * sw->timer_tick_ns; - return timeout_ns * rte_get_timer_hz() / NSECPERSEC; + static struct rte_reciprocal_u64 nsecpersec_inverse; + static uint64_t timer_hz; + uint64_t rem_cycles, secs_cycles = 0; + uint64_t secs, timeout_nsecs; + uint64_t nsecpersec; + struct swtim *sw; + + sw = swtim_pmd_priv(adapter); + nsecpersec = (uint64_t)NSECPERSEC; + + timeout_nsecs = evtim->timeout_ticks * sw->timer_tick_ns; + if (timeout_nsecs > sw->max_tmo_ns) + return -1; + if (timeout_nsecs < sw->timer_tick_ns) + return -2; + + /* Set these values in the first invocation */ + if (!timer_hz) { + timer_hz = rte_get_timer_hz(); + nsecpersec_inverse = rte_reciprocal_value_u64(nsecpersec); + } + + /* If timeout_nsecs > nsecpersec, decrease timeout_nsecs by the number + * of whole seconds it contains and convert that value to a number + * of cycles. This keeps timeout_nsecs in the interval [0..nsecpersec) + * in order to avoid overflow when we later multiply by timer_hz. + */ + if (timeout_nsecs > nsecpersec) { + secs = rte_reciprocal_divide_u64(timeout_nsecs, + &nsecpersec_inverse); + secs_cycles = secs * timer_hz; + timeout_nsecs -= secs * nsecpersec; + } + + rem_cycles = rte_reciprocal_divide_u64(timeout_nsecs * timer_hz, + &nsecpersec_inverse); + + *timeout_cycles = secs_cycles + rem_cycles; + + return 0; } /* This function returns true if one or more (adapter) ticks have occurred since @@ -685,23 +724,6 @@ return false; } -/* Check that event timer timeout value is in range */ -static __rte_always_inline int -check_timeout(struct rte_event_timer *evtim, - const struct rte_event_timer_adapter *adapter) -{ - uint64_t tmo_nsec; - struct swtim *sw = swtim_pmd_priv(adapter); - - tmo_nsec = evtim->timeout_ticks * sw->timer_tick_ns; - if (tmo_nsec > sw->max_tmo_ns) - return -1; - if (tmo_nsec < sw->timer_tick_ns) - return -2; - - return 0; -} - /* Check that event timer event queue sched type matches destination event queue * sched type */ @@ -1072,21 +1094,6 @@ break; } - ret = check_timeout(evtims[i], adapter); - if (unlikely(ret == -1)) { - __atomic_store_n(&evtims[i]->state, - RTE_EVENT_TIMER_ERROR_TOOLATE, - __ATOMIC_RELAXED); - rte_errno = EINVAL; - break; - } else if (unlikely(ret == -2)) { - __atomic_store_n(&evtims[i]->state, - RTE_EVENT_TIMER_ERROR_TOOEARLY, - __ATOMIC_RELAXED); - rte_errno = EINVAL; - break; - } - if (unlikely(check_destination_event_queue(evtims[i], adapter) < 0)) { __atomic_store_n(&evtims[i]->state, @@ -1102,7 +1109,21 @@ evtims[i]->impl_opaque[0] = (uintptr_t)tim; evtims[i]->impl_opaque[1] = (uintptr_t)adapter; - cycles = get_timeout_cycles(evtims[i], adapter); + ret = get_timeout_cycles(evtims[i], adapter, &cycles); + if (unlikely(ret == -1)) { + __atomic_store_n(&evtims[i]->state, + RTE_EVENT_TIMER_ERROR_TOOLATE, + __ATOMIC_RELAXED); + rte_errno = EINVAL; + break; + } else if (unlikely(ret == -2)) { + __atomic_store_n(&evtims[i]->state, + RTE_EVENT_TIMER_ERROR_TOOEARLY, + __ATOMIC_RELAXED); + rte_errno = EINVAL; + break; + } + ret = rte_timer_alt_reset(sw->timer_data_id, tim, cycles, SINGLE, lcore_id, NULL, evtims[i]); if (ret < 0) { diff -Nru dpdk-20.11.7/lib/librte_fib/rte_fib.h dpdk-20.11.8/lib/librte_fib/rte_fib.h --- dpdk-20.11.7/lib/librte_fib/rte_fib.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_fib/rte_fib.h 2023-04-27 17:57:22.000000000 +0000 @@ -128,8 +128,6 @@ * * @param fib * FIB object handle - * @return - * None */ __rte_experimental void diff -Nru dpdk-20.11.7/lib/librte_fib/rte_fib6.h dpdk-20.11.8/lib/librte_fib/rte_fib6.h --- dpdk-20.11.7/lib/librte_fib/rte_fib6.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_fib/rte_fib6.h 2023-04-27 17:57:22.000000000 +0000 @@ -119,8 +119,6 @@ * * @param fib * FIB object handle - * @return - * None */ __rte_experimental void diff -Nru dpdk-20.11.7/lib/librte_graph/node.c dpdk-20.11.8/lib/librte_graph/node.c --- dpdk-20.11.7/lib/librte_graph/node.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_graph/node.c 2023-04-27 17:57:22.000000000 +0000 @@ -310,16 +310,16 @@ if (node->id == id) { if (node->nb_edges < size) { rte_errno = E2BIG; - goto fail; + } else { + node->nb_edges = size; + rc = size; } - node->nb_edges = size; - rc = size; break; } } -fail: graph_spinlock_unlock(); +fail: return rc; } diff -Nru dpdk-20.11.7/lib/librte_ipsec/rte_ipsec_sad.h dpdk-20.11.8/lib/librte_ipsec/rte_ipsec_sad.h --- dpdk-20.11.7/lib/librte_ipsec/rte_ipsec_sad.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_ipsec/rte_ipsec_sad.h 2023-04-27 17:57:22.000000000 +0000 @@ -139,8 +139,6 @@ * * @param sad * pointer to the SAD object - * @return - * None */ void rte_ipsec_sad_destroy(struct rte_ipsec_sad *sad); diff -Nru dpdk-20.11.7/lib/librte_kni/rte_kni.c dpdk-20.11.8/lib/librte_kni/rte_kni.c --- dpdk-20.11.7/lib/librte_kni/rte_kni.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_kni/rte_kni.c 2023-04-27 17:57:22.000000000 +0000 @@ -635,8 +635,8 @@ { unsigned int ret = kni_fifo_get(kni->tx_q, (void **)mbufs, num); - /* If buffers removed, allocate mbufs and then put them into alloc_q */ - if (ret) + /* If buffers removed or alloc_q is empty, allocate mbufs and then put them into alloc_q */ + if (ret || (kni_fifo_count(kni->alloc_q) == 0)) kni_allocate_mbufs(kni); return ret; diff -Nru dpdk-20.11.7/lib/librte_kvargs/rte_kvargs.h dpdk-20.11.8/lib/librte_kvargs/rte_kvargs.h --- dpdk-20.11.7/lib/librte_kvargs/rte_kvargs.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_kvargs/rte_kvargs.h 2023-04-27 17:57:22.000000000 +0000 @@ -36,7 +36,19 @@ /** separator character used between key and value */ #define RTE_KVARGS_KV_DELIM "=" -/** Type of callback function used by rte_kvargs_process() */ +/** + * Callback prototype used by rte_kvargs_process(). + * + * @param key + * The key to consider, it will not be NULL. + * @param value + * The value corresponding to the key, it may be NULL (e.g. only with key) + * @param opaque + * An opaque pointer coming from the caller. + * @return + * - >=0 handle key success. + * - <0 on error. + */ typedef int (*arg_handler_t)(const char *key, const char *value, void *opaque); /** A key/value association */ diff -Nru dpdk-20.11.7/lib/librte_lpm/rte_lpm.h dpdk-20.11.8/lib/librte_lpm/rte_lpm.h --- dpdk-20.11.7/lib/librte_lpm/rte_lpm.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_lpm/rte_lpm.h 2023-04-27 17:57:22.000000000 +0000 @@ -183,8 +183,6 @@ * * @param lpm * LPM object handle - * @return - * None */ void rte_lpm_free(struct rte_lpm *lpm); diff -Nru dpdk-20.11.7/lib/librte_lpm/rte_lpm6.h dpdk-20.11.8/lib/librte_lpm/rte_lpm6.h --- dpdk-20.11.7/lib/librte_lpm/rte_lpm6.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_lpm/rte_lpm6.h 2023-04-27 17:57:22.000000000 +0000 @@ -73,8 +73,6 @@ * * @param lpm * LPM object handle - * @return - * None */ void rte_lpm6_free(struct rte_lpm6 *lpm); diff -Nru dpdk-20.11.7/lib/librte_mempool/rte_mempool.h dpdk-20.11.8/lib/librte_mempool/rte_mempool.h --- dpdk-20.11.7/lib/librte_mempool/rte_mempool.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_mempool/rte_mempool.h 2023-04-27 17:57:22.000000000 +0000 @@ -1403,61 +1403,82 @@ * A pointer to a mempool cache structure. May be NULL if not needed. * @return * - >=0: Success; number of objects supplied. - * - <0: Error; code of ring dequeue function. + * - <0: Error; code of driver dequeue function. */ static __rte_always_inline int __mempool_generic_get(struct rte_mempool *mp, void **obj_table, unsigned int n, struct rte_mempool_cache *cache) { int ret; + unsigned int remaining = n; uint32_t index, len; void **cache_objs; - /* No cache provided or cannot be satisfied from cache */ - if (unlikely(cache == NULL || n >= cache->size)) - goto ring_dequeue; - - cache_objs = cache->objs; - - /* Can this be satisfied from the cache? */ - if (cache->len < n) { - /* No. Backfill the cache first, and then fill from it */ - uint32_t req = n + (cache->size - cache->len); - - /* How many do we require i.e. number to fill the cache + the request */ - ret = rte_mempool_ops_dequeue_bulk(mp, - &cache->objs[cache->len], req); - if (unlikely(ret < 0)) { - /* - * In the off chance that we are buffer constrained, - * where we are not able to allocate cache + n, go to - * the ring directly. If that fails, we are truly out of - * buffers. - */ - goto ring_dequeue; - } + /* No cache provided */ + if (unlikely(cache == NULL)) + goto driver_dequeue; + + /* Use the cache as much as we have to return hot objects first */ + len = RTE_MIN(remaining, cache->len); + cache_objs = &cache->objs[cache->len]; + cache->len -= len; + remaining -= len; + for (index = 0; index < len; index++) + *obj_table++ = *--cache_objs; + + if (remaining == 0) { + /* The entire request is satisfied from the cache. */ + + __MEMPOOL_STAT_ADD(mp, get_success, n); - cache->len += req; + return 0; } - /* Now fill in the response ... */ - for (index = 0, len = cache->len - 1; index < n; ++index, len--, obj_table++) - *obj_table = cache_objs[len]; + /* if dequeue below would overflow mem allocated for cache */ + if (unlikely(remaining > RTE_MEMPOOL_CACHE_MAX_SIZE)) + goto driver_dequeue; + + /* Fill the cache from the backend; fetch size + remaining objects. */ + ret = rte_mempool_ops_dequeue_bulk(mp, cache->objs, + cache->size + remaining); + if (unlikely(ret < 0)) { + /* + * We are buffer constrained, and not able to allocate + * cache + remaining. + * Do not fill the cache, just satisfy the remaining part of + * the request directly from the backend. + */ + goto driver_dequeue; + } + + /* Satisfy the remaining part of the request from the filled cache. */ + cache_objs = &cache->objs[cache->size + remaining]; + for (index = 0; index < remaining; index++) + *obj_table++ = *--cache_objs; - cache->len -= n; + cache->len = cache->size; __MEMPOOL_STAT_ADD(mp, get_success, n); return 0; -ring_dequeue: +driver_dequeue: + + /* Get remaining objects directly from the backend. */ + ret = rte_mempool_ops_dequeue_bulk(mp, obj_table, remaining); - /* get remaining objects from ring */ - ret = rte_mempool_ops_dequeue_bulk(mp, obj_table, n); + if (ret < 0) { + if (likely(cache != NULL)) { + cache->len = n - remaining; + /* + * No further action is required to roll the first part + * of the request back into the cache, as objects in + * the cache are intact. + */ + } - if (ret < 0) __MEMPOOL_STAT_ADD(mp, get_fail, n); - else + } else __MEMPOOL_STAT_ADD(mp, get_success, n); return ret; diff -Nru dpdk-20.11.7/lib/librte_pdump/rte_pdump.c dpdk-20.11.8/lib/librte_pdump/rte_pdump.c --- dpdk-20.11.7/lib/librte_pdump/rte_pdump.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_pdump/rte_pdump.c 2023-04-27 17:57:22.000000000 +0000 @@ -91,7 +91,7 @@ dup_bufs[d_pkts++] = p; } - ring_enq = rte_ring_enqueue_burst(ring, (void *)dup_bufs, d_pkts, NULL); + ring_enq = rte_ring_enqueue_burst(ring, (void *)&dup_bufs[0], d_pkts, NULL); if (unlikely(ring_enq < d_pkts)) { PDUMP_LOG(DEBUG, "only %d of packets enqueued to ring\n", ring_enq); diff -Nru dpdk-20.11.7/lib/librte_rcu/rte_rcu_qsbr.h dpdk-20.11.8/lib/librte_rcu/rte_rcu_qsbr.h --- dpdk-20.11.7/lib/librte_rcu/rte_rcu_qsbr.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_rcu/rte_rcu_qsbr.h 2023-04-27 17:57:22.000000000 +0000 @@ -130,9 +130,6 @@ * Pointer to the resource data stored on the defer queue * @param n * Number of resources to free. Currently, this is set to 1. - * - * @return - * None */ typedef void (*rte_rcu_qsbr_free_resource_t)(void *p, void *e, unsigned int n); diff -Nru dpdk-20.11.7/lib/librte_reorder/rte_reorder.c dpdk-20.11.8/lib/librte_reorder/rte_reorder.c --- dpdk-20.11.7/lib/librte_reorder/rte_reorder.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_reorder/rte_reorder.c 2023-04-27 17:57:22.000000000 +0000 @@ -61,6 +61,11 @@ { const unsigned int min_bufsize = sizeof(*b) + (2 * size * sizeof(struct rte_mbuf *)); + static const struct rte_mbuf_dynfield reorder_seqn_dynfield_desc = { + .name = RTE_REORDER_SEQN_DYNFIELD_NAME, + .size = sizeof(rte_reorder_seqn_t), + .align = __alignof__(rte_reorder_seqn_t), + }; if (b == NULL) { RTE_LOG(ERR, REORDER, "Invalid reorder buffer parameter:" @@ -87,6 +92,15 @@ return NULL; } + rte_reorder_seqn_dynfield_offset = rte_mbuf_dynfield_register(&reorder_seqn_dynfield_desc); + if (rte_reorder_seqn_dynfield_offset < 0) { + RTE_LOG(ERR, REORDER, + "Failed to register mbuf field for reorder sequence number, rte_errno: %i\n", + rte_errno); + rte_errno = ENOMEM; + return NULL; + } + memset(b, 0, bufsize); strlcpy(b->name, name, sizeof(b->name)); b->memsize = bufsize; @@ -99,21 +113,45 @@ return b; } +/* + * Insert new entry into global list. + * Returns pointer to already inserted entry if such exists, or to newly inserted one. + */ +static struct rte_tailq_entry * +rte_reorder_entry_insert(struct rte_tailq_entry *new_te) +{ + struct rte_reorder_list *reorder_list; + struct rte_reorder_buffer *b, *nb; + struct rte_tailq_entry *te; + + rte_mcfg_tailq_write_lock(); + + reorder_list = RTE_TAILQ_CAST(rte_reorder_tailq.head, rte_reorder_list); + /* guarantee there's no existing */ + TAILQ_FOREACH(te, reorder_list, next) { + b = (struct rte_reorder_buffer *) te->data; + nb = (struct rte_reorder_buffer *) new_te->data; + if (strncmp(nb->name, b->name, RTE_REORDER_NAMESIZE) == 0) + break; + } + + if (te == NULL) { + TAILQ_INSERT_TAIL(reorder_list, new_te, next); + te = new_te; + } + + rte_mcfg_tailq_write_unlock(); + + return te; +} + struct rte_reorder_buffer* rte_reorder_create(const char *name, unsigned socket_id, unsigned int size) { struct rte_reorder_buffer *b = NULL; - struct rte_tailq_entry *te; - struct rte_reorder_list *reorder_list; + struct rte_tailq_entry *te, *te_inserted; const unsigned int bufsize = sizeof(struct rte_reorder_buffer) + (2 * size * sizeof(struct rte_mbuf *)); - static const struct rte_mbuf_dynfield reorder_seqn_dynfield_desc = { - .name = RTE_REORDER_SEQN_DYNFIELD_NAME, - .size = sizeof(rte_reorder_seqn_t), - .align = __alignof__(rte_reorder_seqn_t), - }; - - reorder_list = RTE_TAILQ_CAST(rte_reorder_tailq.head, rte_reorder_list); /* Check user arguments. */ if (!rte_is_power_of_2(size)) { @@ -129,32 +167,12 @@ return NULL; } - rte_reorder_seqn_dynfield_offset = - rte_mbuf_dynfield_register(&reorder_seqn_dynfield_desc); - if (rte_reorder_seqn_dynfield_offset < 0) { - RTE_LOG(ERR, REORDER, "Failed to register mbuf field for reorder sequence number\n"); - rte_errno = ENOMEM; - return NULL; - } - - rte_mcfg_tailq_write_lock(); - - /* guarantee there's no existing */ - TAILQ_FOREACH(te, reorder_list, next) { - b = (struct rte_reorder_buffer *) te->data; - if (strncmp(name, b->name, RTE_REORDER_NAMESIZE) == 0) - break; - } - if (te != NULL) - goto exit; - /* allocate tailq entry */ te = rte_zmalloc("REORDER_TAILQ_ENTRY", sizeof(*te), 0); if (te == NULL) { RTE_LOG(ERR, REORDER, "Failed to allocate tailq entry\n"); rte_errno = ENOMEM; - b = NULL; - goto exit; + return NULL; } /* Allocate memory to store the reorder buffer structure. */ @@ -163,14 +181,23 @@ RTE_LOG(ERR, REORDER, "Memzone allocation failed\n"); rte_errno = ENOMEM; rte_free(te); + return NULL; } else { - rte_reorder_init(b, bufsize, name, size); + if (rte_reorder_init(b, bufsize, name, size) == NULL) { + rte_free(b); + rte_free(te); + return NULL; + } te->data = (void *)b; - TAILQ_INSERT_TAIL(reorder_list, te, next); } -exit: - rte_mcfg_tailq_write_unlock(); + te_inserted = rte_reorder_entry_insert(te); + if (te_inserted != te) { + rte_free(b); + rte_free(te); + return te_inserted->data; + } + return b; } @@ -392,6 +419,7 @@ /* Try to fetch requested number of mbufs from ready buffer */ while ((drain_cnt < max_mbufs) && (ready_buf->tail != ready_buf->head)) { mbufs[drain_cnt++] = ready_buf->entries[ready_buf->tail]; + ready_buf->entries[ready_buf->tail] = NULL; ready_buf->tail = (ready_buf->tail + 1) & ready_buf->mask; } diff -Nru dpdk-20.11.7/lib/librte_reorder/rte_reorder.h dpdk-20.11.8/lib/librte_reorder/rte_reorder.h --- dpdk-20.11.7/lib/librte_reorder/rte_reorder.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_reorder/rte_reorder.h 2023-04-27 17:57:22.000000000 +0000 @@ -81,6 +81,7 @@ * The initialized reorder buffer instance, or NULL on error * On error case, rte_errno will be set appropriately: * - EINVAL - invalid parameters + * - ENOMEM - not enough memory to register dynamic field */ struct rte_reorder_buffer * rte_reorder_init(struct rte_reorder_buffer *b, unsigned int bufsize, @@ -115,8 +116,6 @@ * * @param b * reorder buffer instance - * @return - * None */ void rte_reorder_free(struct rte_reorder_buffer *b); diff -Nru dpdk-20.11.7/lib/librte_rib/rte_rib.h dpdk-20.11.8/lib/librte_rib/rte_rib.h --- dpdk-20.11.7/lib/librte_rib/rte_rib.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_rib/rte_rib.h 2023-04-27 17:57:22.000000000 +0000 @@ -282,8 +282,6 @@ * * @param rib * RIB object handle - * @return - * None */ __rte_experimental void diff -Nru dpdk-20.11.7/lib/librte_rib/rte_rib6.h dpdk-20.11.8/lib/librte_rib/rte_rib6.h --- dpdk-20.11.7/lib/librte_rib/rte_rib6.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_rib/rte_rib6.h 2023-04-27 17:57:22.000000000 +0000 @@ -337,8 +337,6 @@ * * @param rib * RIB object handle - * @return - * None */ __rte_experimental void diff -Nru dpdk-20.11.7/lib/librte_ring/rte_ring_elem.h dpdk-20.11.8/lib/librte_ring/rte_ring_elem.h --- dpdk-20.11.7/lib/librte_ring/rte_ring_elem.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_ring/rte_ring_elem.h 2023-04-27 17:57:22.000000000 +0000 @@ -104,6 +104,12 @@ struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize, unsigned int count, int socket_id, unsigned int flags); +#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 120000) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#pragma GCC diagnostic ignored "-Wstringop-overread" +#endif + static __rte_always_inline void __rte_ring_enqueue_elems_32(struct rte_ring *r, const uint32_t size, uint32_t idx, const void *obj_table, uint32_t n) @@ -1076,6 +1082,10 @@ return 0; } +#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 120000) +#pragma GCC diagnostic pop +#endif + #ifdef ALLOW_EXPERIMENTAL_API #include #include diff -Nru dpdk-20.11.7/lib/librte_telemetry/telemetry.c dpdk-20.11.8/lib/librte_telemetry/telemetry.c --- dpdk-20.11.7/lib/librte_telemetry/telemetry.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_telemetry/telemetry.c 2023-04-27 17:57:22.000000000 +0000 @@ -281,7 +281,7 @@ static void perform_command(telemetry_cb fn, const char *cmd, const char *param, int s) { - struct rte_tel_data data; + struct rte_tel_data data = {0}; int ret = fn(cmd, param, &data); if (ret < 0) { diff -Nru dpdk-20.11.7/lib/librte_vhost/rte_vhost_async.h dpdk-20.11.8/lib/librte_vhost/rte_vhost_async.h --- dpdk-20.11.7/lib/librte_vhost/rte_vhost_async.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_vhost/rte_vhost_async.h 2023-04-27 17:57:22.000000000 +0000 @@ -48,15 +48,15 @@ /** * instruct async engines to perform copies for a batch of packets * - * @param vid + * vid * id of vhost device to perform data copies - * @param queue_id + * queue_id * queue id to perform data copies - * @param descs + * descs * an array of DMA transfer memory descriptors - * @param opaque_data + * opaque_data * opaque data pair sending to DMA engine - * @param count + * count * number of elements in the "descs" array * @return * number of descs processed @@ -67,13 +67,13 @@ uint16_t count); /** * check copy-completed packets from the async engine - * @param vid + * vid * id of vhost device to check copy completion - * @param queue_id + * queue_id * queue id to check copy completion - * @param opaque_data + * opaque_data * buffer to receive the opaque data pair from DMA engine - * @param max_packets + * max_packets * max number of packets could be completed * @return * number of async descs completed diff -Nru dpdk-20.11.7/lib/librte_vhost/socket.c dpdk-20.11.8/lib/librte_vhost/socket.c --- dpdk-20.11.7/lib/librte_vhost/socket.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_vhost/socket.c 2023-04-27 17:57:22.000000000 +0000 @@ -128,10 +128,12 @@ return ret; } - if (msgh.msg_flags & (MSG_TRUNC | MSG_CTRUNC)) { + if (msgh.msg_flags & MSG_TRUNC) VHOST_LOG_CONFIG(ERR, "truncated msg\n"); - return -1; - } + + /* MSG_CTRUNC may be caused by LSM misconfiguration */ + if (msgh.msg_flags & MSG_CTRUNC) + VHOST_LOG_CONFIG(ERR, "truncated control data (fd %d)\n", sockfd); for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) { diff -Nru dpdk-20.11.7/lib/librte_vhost/vhost.h dpdk-20.11.8/lib/librte_vhost/vhost.h --- dpdk-20.11.7/lib/librte_vhost/vhost.h 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_vhost/vhost.h 2023-04-27 17:57:22.000000000 +0000 @@ -663,7 +663,10 @@ static __rte_always_inline struct virtio_net * get_device(int vid) { - struct virtio_net *dev = vhost_devices[vid]; + struct virtio_net *dev = NULL; + + if (likely(vid >= 0 && vid < MAX_VHOST_DEVICE)) + dev = vhost_devices[vid]; if (unlikely(!dev)) { VHOST_LOG_CONFIG(ERR, diff -Nru dpdk-20.11.7/lib/librte_vhost/vhost_user.c dpdk-20.11.8/lib/librte_vhost/vhost_user.c --- dpdk-20.11.7/lib/librte_vhost/vhost_user.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_vhost/vhost_user.c 2023-04-27 17:57:22.000000000 +0000 @@ -1679,7 +1679,7 @@ if (!(msg->payload.u64 & VHOST_USER_VRING_NOFD_MASK)) close(msg->fds[0]); - VHOST_LOG_CONFIG(INFO, "not implemented\n"); + VHOST_LOG_CONFIG(DEBUG, "not implemented\n"); return RTE_VHOST_MSG_RESULT_OK; } @@ -2191,7 +2191,7 @@ return RTE_VHOST_MSG_RESULT_ERR; close(msg->fds[0]); - VHOST_LOG_CONFIG(INFO, "not implemented.\n"); + VHOST_LOG_CONFIG(DEBUG, "not implemented.\n"); return RTE_VHOST_MSG_RESULT_OK; } @@ -2609,30 +2609,37 @@ ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE, msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num); - if (ret <= 0) { - return ret; - } else if (ret != VHOST_USER_HDR_SIZE) { + if (ret <= 0) + goto out; + + if (ret != VHOST_USER_HDR_SIZE) { VHOST_LOG_CONFIG(ERR, "Unexpected header size read\n"); - close_msg_fds(msg); - return -1; + ret = -1; + goto out; } if (msg->size) { if (msg->size > sizeof(msg->payload)) { VHOST_LOG_CONFIG(ERR, "invalid msg size: %d\n", msg->size); - return -1; + ret = -1; + goto out; } ret = read(sockfd, &msg->payload, msg->size); if (ret <= 0) - return ret; + goto out; if (ret != (int)msg->size) { VHOST_LOG_CONFIG(ERR, "read control message failed\n"); - return -1; + ret = -1; + goto out; } } +out: + if (ret <= 0) + close_msg_fds(msg); + return ret; } @@ -2778,6 +2785,7 @@ } } + msg.request.master = VHOST_USER_NONE; ret = read_vhost_message(fd, &msg); if (ret <= 0) { if (ret < 0) diff -Nru dpdk-20.11.7/lib/librte_vhost/virtio_net.c dpdk-20.11.8/lib/librte_vhost/virtio_net.c --- dpdk-20.11.7/lib/librte_vhost/virtio_net.c 2022-12-13 10:50:22.000000000 +0000 +++ dpdk-20.11.8/lib/librte_vhost/virtio_net.c 2023-04-27 17:57:22.000000000 +0000 @@ -1329,6 +1329,12 @@ sizeof(struct virtio_net_hdr_mrg_rxbuf); } + if (rxvq_is_mergeable(dev)) { + vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) { + ASSIGN_UNLESS_EQUAL(hdrs[i]->num_buffers, 1); + } + } + vhost_for_each_try_unroll(i, 0, PACKED_BATCH_SIZE) virtio_enqueue_offload(pkts[i], &hdrs[i]->hdr);