From: Stephen Hemminger <stephen@networkplumber.org>
To: Kumara Parameshwaran <kumaraparamesh92@gmail.com>
Cc: dev@dpdk.org
Subject: Re: [PATCH v2] gro : improve GRO performance based on hash table
Date: Sun, 16 Nov 2025 08:52:37 -0800 [thread overview]
Message-ID: <20251116085237.61d9c340@phoenix> (raw)
In-Reply-To: <20251116060634.262352-1-kumaraparamesh92@gmail.com>
On Sun, 16 Nov 2025 11:36:34 +0530
Kumara Parameshwaran <kumaraparamesh92@gmail.com> wrote:
> Use cuckoo hash library in GRO for flow flookup
>
> Signed-off-by: Kumara Parameshwaran <kumaraparamesh92@gmail.com>
Need test about what happens when table is DoS attacked.
>
> Fix warnings and more validatation to the test
>
> app/test/meson.build | 1 +
> app/test/test_gro.c | 237 +++++++++++++++++++++++++++++++++++++++++++
> lib/gro/gro_tcp4.c | 60 ++++++-----
> lib/gro/gro_tcp4.h | 2 +
> lib/gro/meson.build | 2 +-
> 5 files changed, 278 insertions(+), 24 deletions(-)
> create mode 100644 app/test/test_gro.c
>
> diff --git a/app/test/meson.build b/app/test/meson.build
> index 8df8d3edd1..03bbe2be1f 100644
> --- a/app/test/meson.build
> +++ b/app/test/meson.build
> @@ -211,6 +211,7 @@ source_file_deps = {
> 'test_trace_register.c': [],
> 'test_vdev.c': ['kvargs', 'bus_vdev'],
> 'test_version.c': [],
> + 'test_gro.c':['net', 'gro'],
> }
>
> source_file_ext_deps = {
> diff --git a/app/test/test_gro.c b/app/test/test_gro.c
> new file mode 100644
> index 0000000000..3bd0035e68
> --- /dev/null
> +++ b/app/test/test_gro.c
> @@ -0,0 +1,237 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2018 Intel Corporation
> + */
> +
> +#include "test.h"
> +
> +#include <rte_net.h>
> +#include <rte_gro.h>
> +
> +#define NUM_MBUFS 128
> +#define BURST 32
> +
> +/*
> + * Sample TCP/IPv4 packets from Iperf run
> + * Each packet is 132 bytes long and TCP segment is 66 bytes long
> + *
> + * 10.1.0.4:52362=>10.1.0.5:5201 Seq = 4251552885 Ack = 428268870
> + */
> +unsigned char pkts[][132] = {
> + {
> + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x7c, 0xed, 0x8d, 0xc0,
> + 0xc1, 0xf5, 0x8, 0x0, 0x45, 0x0, 0x0, 0x76, 0xa4, 0xfb, 0x40,
> + 0x0, 0x40, 0x6, 0x81, 0x7c, 0xa, 0x1, 0x0, 0x4, 0xa, 0x1, 0x0,
> + 0x5, 0xcc, 0x8a, 0x14, 0x51, 0xfd, 0x69, 0x8c, 0x75, 0x19, 0x86,
> + 0xdd, 0x46, 0x80, 0x10, 0x2, 0x0, 0x14, 0x73, 0x0, 0x0, 0x1, 0x1,
> + 0x8, 0xa, 0x3c, 0x2, 0xd1, 0xa5, 0x36, 0xb6, 0x9e, 0xda, 0x7d, 0xe9,
> + 0x63, 0xf1, 0x67, 0xeb, 0xc4, 0x93, 0xcf, 0x74, 0xcd, 0xab, 0x93,
> + 0x86, 0xe8, 0xb0, 0x1c, 0x92, 0xc8, 0x82, 0xef, 0x72, 0x34, 0xe7, 0x86,
> + 0x6d, 0xd2, 0x96, 0x8, 0x70, 0xae, 0xda, 0x60, 0xe4, 0x25, 0x39, 0xd2,
> + 0x73, 0xe7, 0xef, 0xf5, 0xf6, 0x7f, 0xbf, 0x7f, 0x5, 0x5a, 0x40, 0x6,
> + 0x65, 0x13, 0x8f, 0xa4, 0x7, 0x73, 0x41, 0xcb, 0x56, 0x3, 0x15, 0x85,
> + 0x99, 0x8c, 0xa9, 0xc8, 0x14
> + },
> + {
> + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x7c, 0xed, 0x8d, 0xc0, 0xc1,
> + 0xf5, 0x8, 0x0, 0x45, 0x0, 0x0, 0x76, 0xa4, 0xfc, 0x40, 0x0, 0x40,
> + 0x6, 0x81, 0x7b, 0xa, 0x1, 0x0, 0x4, 0xa, 0x1, 0x0, 0x5, 0xcc, 0x8a,
> + 0x14, 0x51, 0xfd, 0x69, 0x8c, 0xb7, 0x19, 0x86, 0xdd, 0x46, 0x80, 0x10,
> + 0x2, 0x0, 0x14, 0x73, 0x0, 0x0, 0x1, 0x1, 0x8, 0xa, 0x3c, 0x2, 0xd1, 0xa5,
> + 0x36, 0xb6, 0x9e, 0xda, 0x2a, 0x6a, 0x4e, 0xf9, 0x94, 0x6, 0xaf, 0x2f, 0xeb,
> + 0xfb, 0xef, 0xa4, 0xaa, 0xe8, 0xd6, 0xc0, 0x34, 0xab, 0x8b, 0xfc, 0x14, 0xb9,
> + 0x89, 0xcb, 0xb6, 0x15, 0x58, 0xe5, 0x2a, 0x72, 0xcd, 0x1c, 0x71, 0x3, 0xf4,
> + 0xf9, 0x32, 0x7e, 0x58, 0xec, 0xe6, 0x52, 0x5a, 0x88, 0x8c, 0x24, 0x53, 0xd7,
> + 0x39, 0x80, 0xb6, 0x66, 0x9b, 0xe5, 0x45, 0xbe, 0x9, 0xf8, 0xac, 0xef, 0xc2,
> + 0x51, 0x31, 0x87, 0x9c, 0x56
> + },
> + {
> + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x7c, 0xed, 0x8d, 0xc0, 0xc1, 0xf5, 0x8,
> + 0x0, 0x45, 0x0, 0x0, 0x76, 0xa4, 0xfd, 0x40, 0x0, 0x40, 0x6, 0x81, 0x7a, 0xa,
> + 0x1, 0x0, 0x4, 0xa, 0x1, 0x0, 0x5, 0xcc, 0x8a, 0x14, 0x51, 0xfd, 0x69, 0x8c,
> + 0xf9, 0x19, 0x86, 0xdd, 0x46, 0x80, 0x10, 0x2, 0x0, 0x14, 0x73, 0x0, 0x0, 0x1,
> + 0x1, 0x8, 0xa, 0x3c, 0x2, 0xd1, 0xa5, 0x36, 0xb6, 0x9e, 0xda, 0x68, 0x93, 0xec,
> + 0x8a, 0x35, 0xba, 0xe8, 0x24, 0x9e, 0x78, 0x6c, 0xb8, 0x65, 0xe1, 0x23, 0xc1, 0x48,
> + 0x5, 0xca, 0xea, 0x6b, 0x5, 0xe7, 0x71, 0x1a, 0x97, 0x5a, 0x23, 0xd2, 0x81, 0xc9,
> + 0x9a, 0xad, 0x1e, 0x77, 0xb1, 0x9c, 0x43, 0xf, 0xbf, 0x6c, 0xb6, 0x36, 0x46,
> + 0x99, 0xcc, 0x4, 0xf4, 0xc2, 0x87, 0x41, 0xec, 0xc6, 0xc5, 0xd9, 0x48, 0xcf,
> + 0x9b, 0xec, 0xb7, 0x2f, 0x91, 0x5f, 0x83, 0x9f, 0xd
> + },
> + {
> + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x7c, 0xed, 0x8d, 0xc0, 0xc1, 0xf5, 0x8, 0x0,
> + 0x45, 0x0, 0x0, 0x76, 0xa4, 0xfe, 0x40, 0x0, 0x40, 0x6, 0x81, 0x79, 0xa, 0x1, 0x0,
> + 0x4, 0xa, 0x1, 0x0, 0x5, 0xcc, 0x8a, 0x14, 0x51, 0xfd, 0x69, 0x8d, 0x3b, 0x19, 0x86,
> + 0xdd, 0x46, 0x80, 0x10, 0x2, 0x0, 0x14, 0x73, 0x0, 0x0, 0x1, 0x1, 0x8, 0xa, 0x3c,
> + 0x2, 0xd1, 0xa5, 0x36, 0xb6, 0x9e, 0xda, 0xdd, 0x72, 0x54, 0xdc, 0x5, 0x51, 0xb6,
> + 0x4b, 0xdd, 0x10, 0xfb, 0x1c, 0xe8, 0x5d, 0x84, 0x75, 0xd7, 0x20, 0xd3, 0xc, 0xbd,
> + 0xba, 0x77, 0x1a, 0x14, 0x41, 0x15, 0xd0, 0x34, 0x64, 0x8d, 0x6, 0x32, 0x8f, 0x83,
> + 0x3e, 0xd6, 0xf, 0xaa, 0xe1, 0x7e, 0xdc, 0xbe, 0x33, 0x43, 0xc6, 0x38, 0xcf, 0x9b,
> + 0x6f, 0xf2, 0x1e, 0x50, 0x6f, 0xf3, 0x3b, 0x8f, 0xbf, 0x18, 0x60, 0xd5, 0x43, 0xac,
> + 0xd2, 0xbb, 0x49
> + },
> + {
> + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0x7c, 0xed, 0x8d, 0xc0, 0xc1, 0xf5, 0x8, 0x0,
> + 0x45, 0x0, 0x0, 0x76, 0xa4, 0xff, 0x40, 0x0, 0x40, 0x6, 0x81, 0x78, 0xa, 0x1, 0x0,
> + 0x4, 0xa, 0x1, 0x0, 0x5, 0xcc, 0x8a, 0x14, 0x51, 0xfd, 0x69, 0x8d, 0x7d, 0x19, 0x86,
> + 0xdd, 0x46, 0x80, 0x18, 0x2, 0x0, 0x14, 0x73, 0x0, 0x0, 0x1, 0x1, 0x8, 0xa, 0x3c,
> + 0x2, 0xd1, 0xa5, 0x36, 0xb6, 0x9e, 0xda, 0x5a, 0x95, 0x20, 0xf2, 0x20, 0x9b, 0xd,
> + 0xc1, 0x9, 0xe5, 0x3, 0x68, 0x52, 0x14, 0x2c, 0x7c, 0x98, 0x44, 0x63, 0x6c, 0xc6,
> + 0xe6, 0xba, 0x8a, 0x0, 0x10, 0x66, 0x45, 0xb1, 0xfd, 0x7b, 0x77, 0xf1, 0xf9, 0x95,
> + 0xcd, 0x7f, 0x61, 0x12, 0xeb, 0xa5, 0x23, 0xa0, 0x2, 0xe5, 0x31, 0xd8, 0x1f, 0x36,
> + 0x55, 0x59, 0x46, 0xce, 0x9f, 0xd2, 0x74, 0x6b, 0xf9, 0x63, 0xbe, 0xa1, 0xed, 0xc5,
> + 0x59, 0x22, 0x8c
> + }
> +};
I would prefer these packets were built by the test, rather than byte arrays.
Allows for more later, and testing other cases.
> +void *gro_tcp4_ctx;
> +static struct rte_mempool *pkt_pool;
> +
> +static int test_gro_tcp4_setup(void)
> +{
> + pkt_pool = rte_pktmbuf_pool_create("GRO_MBUF_POOL",
> + NUM_MBUFS, BURST, 0,
> + RTE_MBUF_DEFAULT_BUF_SIZE,
> + SOCKET_ID_ANY);
> + if (pkt_pool == NULL) {
> + printf("%s: Error creating pkt mempool\n", __func__);
> + goto failed;
> + }
> +
> + gro_tcp4_ctx = rte_gro_ctx_create(&(struct rte_gro_param) {
> + .max_flow_num = 1024,
> + .max_item_per_flow = 32,
> + .gro_types = RTE_GRO_TCP_IPV4,
> + });
> + if (gro_tcp4_ctx == NULL)
> + goto failed;
> +
> + return TEST_SUCCESS;
> +
> +failed:
> + if (pkt_pool)
> + rte_mempool_free(pkt_pool);
> + if (gro_tcp4_ctx)
> + rte_gro_ctx_destroy(gro_tcp4_ctx);
> +
> + pkt_pool = NULL;
> + gro_tcp4_ctx = NULL;
> +
> + return TEST_FAILED;
> +}
> +
> +static void test_gro_tcp4_teardown(void)
> +{
> + if (pkt_pool)
> + rte_mempool_free(pkt_pool);
> + if (gro_tcp4_ctx)
> + rte_gro_ctx_destroy(gro_tcp4_ctx);
> + pkt_pool = NULL;
> + gro_tcp4_ctx = NULL;
> +}
> +
> +static int testsuite_setup(void)
> +{
> + return TEST_SUCCESS;
> +}
> +
> +static void testsuite_teardown(void)
> +{
> +}
If testsuite does not need setup/teardown those callbacks
can be left NULL. I.E no need for stubs.
> +static int32_t
> +test_gro_tcp4(void)
> +{
> + struct rte_mbuf *pkts_mb[5];
> + struct rte_mbuf *gro_pkts[5];
> + int nb_pkts;
> + int nb_gro_pkts;
> + struct rte_net_hdr_lens hdr_lens = {0};
> + struct rte_ether_hdr *eth_hdr;
> + struct rte_ipv4_hdr *ipv4_hdr;
> + struct rte_tcp_hdr *tcp_hdr;
> + struct rte_ether_addr src_addr = {
> + .addr_bytes = {0x7c, 0xed, 0x8d, 0xc0, 0xc1, 0xf5}
> + };
> + struct rte_ether_addr dst_addr = {
> + .addr_bytes = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}
> + };
> +
> + for (int i = 0; i < 5; i++) {
> + pkts_mb[i] = rte_pktmbuf_alloc(pkt_pool);
> + if (pkts_mb[i] == NULL)
> + goto failed;
> + rte_memcpy(rte_pktmbuf_mtod(pkts_mb[i], void *), pkts[i], 132);
> + pkts_mb[i]->data_len = 132;
> + pkts_mb[i]->pkt_len = 132;
> + pkts_mb[i]->packet_type = rte_net_get_ptype(pkts_mb[i], &hdr_lens,
> + RTE_PTYPE_ALL_MASK);
Better to use rte_pktmbuf_append, it will fix all the lengths for yu.
> + pkts_mb[i]->l2_len = hdr_lens.l2_len;
> + pkts_mb[i]->l3_len = hdr_lens.l3_len;
> + pkts_mb[i]->l4_len = hdr_lens.l4_len;
> + }
> +
> + /* GRO reassemble */
> + nb_pkts = rte_gro_reassemble(&pkts_mb[0], 5, gro_tcp4_ctx);
> + TEST_ASSERT(nb_pkts == 0, "Not expected packets after GRO");
> + TEST_ASSERT(rte_gro_get_pkt_count(gro_tcp4_ctx) == 1, "GRO pkt count mismatch");
> +
> + /* GRO timeout flush */
> + nb_gro_pkts = rte_gro_timeout_flush(gro_tcp4_ctx, 0, RTE_GRO_TCP_IPV4, gro_pkts, 5);
> + TEST_ASSERT(nb_gro_pkts == 1, "GRO timeout flush pkt count mismatch");
> + TEST_ASSERT(rte_gro_get_pkt_count(gro_tcp4_ctx) == 0, "GRO pkt count after flush mismatch");
> + TEST_ASSERT(gro_pkts[0]->pkt_len == 396, "GRO merged pkt len mismatch");
> +
> + eth_hdr = rte_pktmbuf_mtod(gro_pkts[0], struct rte_ether_hdr *);
> + ipv4_hdr = (struct rte_ipv4_hdr *)(rte_pktmbuf_mtod(
> + gro_pkts[0], char *) + sizeof(struct rte_ether_hdr));
> + tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv4_hdr + sizeof(struct rte_ipv4_hdr));
> +
> + TEST_ASSERT_BUFFERS_ARE_EQUAL(eth_hdr->src_addr.addr_bytes,
> + src_addr.addr_bytes, RTE_ETHER_ADDR_LEN, "GRO merged pkt Ethernet SRC MAC mismatch");
> + TEST_ASSERT_BUFFERS_ARE_EQUAL(eth_hdr->dst_addr.addr_bytes,
> + dst_addr.addr_bytes, RTE_ETHER_ADDR_LEN, "GRO merged pkt Ethernet DST MAC mismatch");
> +
> + TEST_ASSERT(rte_be_to_cpu_32(ipv4_hdr->src_addr) == 0x0a010004,
> + "GRO merged pkt IP src addr mismatch");
> + TEST_ASSERT(rte_be_to_cpu_32(ipv4_hdr->dst_addr) == 0x0a010005,
> + "GRO merged pkt IP dst addr mismatch");
> + TEST_ASSERT(rte_be_to_cpu_16(ipv4_hdr->packet_id) == 0xa4fb,
> + "GRO merged pkt IP id mismatch");
> +
> + TEST_ASSERT(rte_be_to_cpu_16(tcp_hdr->src_port) == 52362,
> + "GRO merged pkt TCP src port mismatch");
> + TEST_ASSERT(rte_be_to_cpu_16(tcp_hdr->dst_port) == 5201,
> + "GRO merged pkt TCP dst port mismatch");
> + TEST_ASSERT(rte_be_to_cpu_32(tcp_hdr->sent_seq) == 4251552885,
> + "GRO merged pkt TCP seq num mismatch");
> + TEST_ASSERT(rte_be_to_cpu_32(tcp_hdr->recv_ack) == 428268870,
> + "GRO merged pkt TCP ack num mismatch");
> +
> + return TEST_SUCCESS;
> +
> +failed:
> + return TEST_FAILED;
> +}
> +
> +static struct unit_test_suite gro_testsuite = {
> + .suite_name = "GRO Unit Test Suite",
> + .setup = testsuite_setup,
> + .teardown = testsuite_teardown,
> + .unit_test_cases = {
> + TEST_CASE_ST(test_gro_tcp4_setup, test_gro_tcp4_teardown,
> + test_gro_tcp4),
> +
> + TEST_CASES_END() /**< NULL terminate unit test array */
> + }
> +};
> +
> +static int
> +test_gro(void)
> +{
> + rte_log_set_global_level(RTE_LOG_DEBUG);
> + rte_log_set_level(RTE_LOGTYPE_EAL, RTE_LOG_DEBUG);
> +
> + return unit_test_suite_runner(&gro_testsuite);
> +}
> +
> +
> +REGISTER_FAST_TEST(gro_autotest, false, true, test_gro);
> diff --git a/lib/gro/gro_tcp4.c b/lib/gro/gro_tcp4.c
> index 855cc7a71d..8459037eef 100644
> --- a/lib/gro/gro_tcp4.c
> +++ b/lib/gro/gro_tcp4.c
> @@ -5,6 +5,8 @@
> #include <rte_malloc.h>
> #include <rte_mbuf.h>
> #include <rte_ethdev.h>
> +#include <rte_hash.h>
> +#include <rte_jhash.h>
>
> #include "gro_tcp4.h"
> #include "gro_tcp_internal.h"
> @@ -57,6 +59,15 @@ gro_tcp4_tbl_create(uint16_t socket_id,
> tbl->flows[i].start_index = INVALID_ARRAY_INDEX;
> tbl->max_flow_num = entries_num;
>
> + /* Create Hash table for faster lookup of the flows */
> + tbl->flow_hash = rte_hash_create(&(struct rte_hash_parameters){
> + .name = "gro_tcp4_flow_hash",
> + .entries = tbl->max_flow_num,
> + .key_len = sizeof(struct tcp4_flow_key),
> + .hash_func = rte_jhash,
> + .hash_func_init_val = 0
> + });
> +
> return tbl;
> }
>
> @@ -69,6 +80,7 @@ gro_tcp4_tbl_destroy(void *tbl)
> rte_free(tcp_tbl->items);
> rte_free(tcp_tbl->flows);
> }
> + rte_hash_free(tcp_tbl->flow_hash);
> rte_free(tcp_tbl);
> }
>
> @@ -91,11 +103,17 @@ insert_new_flow(struct gro_tcp4_tbl *tbl,
> {
> struct tcp4_flow_key *dst;
> uint32_t flow_idx;
> + int32_t ret;
>
> flow_idx = find_an_empty_flow(tbl);
> if (unlikely(flow_idx == INVALID_ARRAY_INDEX))
> return INVALID_ARRAY_INDEX;
>
> + ret = rte_hash_add_key_data(tbl->flow_hash, src,
> + (void *)&tbl->flows[flow_idx]);
> + if (ret < 0)
> + return INVALID_ARRAY_INDEX;
> +
> dst = &(tbl->flows[flow_idx].key);
>
> ASSIGN_COMMON_TCP_KEY((&src->cmn_key), (&dst->cmn_key));
> @@ -124,9 +142,8 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
>
> struct tcp4_flow_key key;
> uint32_t item_idx;
> - uint32_t i, max_flow_num, remaining_flow_num;
> - uint8_t find;
> - uint32_t item_start_idx;
> + int ret;
> + struct gro_tcp4_flow *flow;
>
> /*
> * Don't process the packet whose TCP header length is greater
> @@ -173,22 +190,8 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
> is_atomic = (frag_off & RTE_IPV4_HDR_DF_FLAG) == RTE_IPV4_HDR_DF_FLAG;
> ip_id = is_atomic ? 0 : rte_be_to_cpu_16(ipv4_hdr->packet_id);
>
> - /* Search for a matched flow. */
> - max_flow_num = tbl->max_flow_num;
> - remaining_flow_num = tbl->flow_num;
> - find = 0;
> - for (i = 0; i < max_flow_num && remaining_flow_num; i++) {
> - if (tbl->flows[i].start_index != INVALID_ARRAY_INDEX) {
> - if (is_same_tcp4_flow(tbl->flows[i].key, key)) {
> - find = 1;
> - item_start_idx = tbl->flows[i].start_index;
> - break;
> - }
> - remaining_flow_num--;
> - }
> - }
> -
> - if (find == 1) {
> + ret = rte_hash_lookup_data(tbl->flow_hash, &key, (void **)&flow);
> + if (ret >= 0) {
> /*
> * Any packet with additional flags like PSH,FIN should be processed
> * and flushed immediately.
> @@ -197,9 +200,9 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt,
> */
> if (tcp_hdr->tcp_flags & (RTE_TCP_ACK_FLAG | RTE_TCP_PSH_FLAG | RTE_TCP_FIN_FLAG)) {
> if (tcp_hdr->tcp_flags != RTE_TCP_ACK_FLAG)
> - tbl->items[item_start_idx].start_time = 0;
> + tbl->items[flow->start_index].start_time = 0;
> return process_tcp_item(pkt, tcp_hdr, tcp_dl, tbl->items,
> - tbl->flows[i].start_index, &tbl->item_num,
> + flow->start_index, &tbl->item_num,
> tbl->max_item_num, ip_id, is_atomic, start_time);
> } else {
> return -1;
> @@ -256,6 +259,8 @@ gro_tcp4_tbl_timeout_flush(struct gro_tcp4_tbl *tbl,
> uint16_t k = 0;
> uint32_t i, j;
> uint32_t max_flow_num = tbl->max_flow_num;
> + struct gro_tcp4_flow *flow;
> + int ret;
>
> for (i = 0; i < max_flow_num; i++) {
> if (unlikely(tbl->flow_num == 0))
> @@ -273,9 +278,18 @@ gro_tcp4_tbl_timeout_flush(struct gro_tcp4_tbl *tbl,
> */
> j = delete_tcp_item(tbl->items, j,
> &tbl->item_num, INVALID_ARRAY_INDEX);
> - tbl->flows[i].start_index = j;
> - if (j == INVALID_ARRAY_INDEX)
> + if (j == INVALID_ARRAY_INDEX) {
> + flow = &tbl->flows[i];
> + ret = rte_hash_del_key(tbl->flow_hash, &flow->key);
> + RTE_ASSERT(ret >= 0);
> + if (ret >= 0) {
> + ret = rte_hash_free_key_with_position(
> + tbl->flow_hash, ret);
> + RTE_ASSERT(ret == 0);
> + }
> tbl->flow_num--;
> + }
> + tbl->flows[i].start_index = j;
>
> if (unlikely(k == nb_out))
> return k;
> diff --git a/lib/gro/gro_tcp4.h b/lib/gro/gro_tcp4.h
> index 245e5da486..babf4f7d01 100644
> --- a/lib/gro/gro_tcp4.h
> +++ b/lib/gro/gro_tcp4.h
> @@ -33,6 +33,8 @@ struct gro_tcp4_tbl {
> struct gro_tcp_item *items;
> /* flow array */
> struct gro_tcp4_flow *flows;
> + /* flow hash table */
> + struct rte_hash *flow_hash;
> /* current item number */
> uint32_t item_num;
> /* current flow num */
> diff --git a/lib/gro/meson.build b/lib/gro/meson.build
> index dbce05220d..96668dcd94 100644
> --- a/lib/gro/meson.build
> +++ b/lib/gro/meson.build
> @@ -10,4 +10,4 @@ sources = files(
> 'gro_vxlan_udp4.c',
> )
> headers = files('rte_gro.h')
> -deps += ['ethdev']
> +deps += ['ethdev', 'hash']
next prev parent reply other threads:[~2025-11-16 16:52 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-10 16:23 [PATCH] gro : improve GRO performance based on hash table Kumara Parameshwaran
2025-11-16 6:06 ` [PATCH v2] " Kumara Parameshwaran
2025-11-16 16:52 ` Stephen Hemminger [this message]
2025-12-27 17:36 ` Kumara Parameshwaran
2025-12-27 17:42 ` [PATCH v3] " Kumara Parameshwaran
2025-12-27 18:12 ` Stephen Hemminger
2026-03-31 3:04 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251116085237.61d9c340@phoenix \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
--cc=kumaraparamesh92@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.