From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 210FFA0562; Fri, 3 Apr 2020 18:07:35 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9DE3D1C1DF; Fri, 3 Apr 2020 18:07:34 +0200 (CEST) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by dpdk.org (Postfix) with ESMTP id EC5C61C1DE for ; Fri, 3 Apr 2020 18:07:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1585930052; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V1qgpNzTl4bDOAw+39q2KomqG9BKerp6CMX7tOHNrR0=; b=UOKD0gjzgOoLxja2li8tTubpEceF+VlPQm3p6r+HVf/sABx8O4ZVUK0ftR3TgTrF6ef75o LqjWkjHhk2HFkAkgRSj6fAJ1QWC4kg+he98e9ZT3AenbHNxoaasiML/dVLIaEtHqcUSw3w 5qdR4F6iyuuAsllipOhlb9V1lXRN100= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-160-8wf-4cdtOoKPcj9cpkmQOQ-1; Fri, 03 Apr 2020 12:07:30 -0400 X-MC-Unique: 8wf-4cdtOoKPcj9cpkmQOQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 123B0107ACC7; Fri, 3 Apr 2020 16:07:29 +0000 (UTC) Received: from dhcp-25.97.bos.redhat.com (ovpn-116-136.phx2.redhat.com [10.3.116.136]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 391D226579; Fri, 3 Apr 2020 16:07:28 +0000 (UTC) From: Aaron Conole To: Cc: , References: <20200403115026.8735-1-pbhagavatula@marvell.com> Date: Fri, 03 Apr 2020 12:07:26 -0400 In-Reply-To: <20200403115026.8735-1-pbhagavatula@marvell.com> (pbhagavatula@marvell.com's message of "Fri, 3 Apr 2020 17:20:26 +0530") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Subject: Re: [dpdk-dev] [PATCH] test: add reassembly perf test X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" writes: > From: Pavan Nikhilesh > > Add reassembly perf autotest for both ipv4 and ipv6 reassembly. > Each test is performed with vairable number of fragments per flow, > either ordered or unorderd fragments and interleaved flows. > > Signed-off-by: Pavan Nikhilesh > --- > app/test/meson.build | 2 + > app/test/test_reassembly_perf.c | 989 ++++++++++++++++++++++++++++++++ > 2 files changed, 991 insertions(+) > create mode 100644 app/test/test_reassembly_perf.c > > diff --git a/app/test/meson.build b/app/test/meson.build > index 351d29cb6..457226e66 100644 > --- a/app/test/meson.build > +++ b/app/test/meson.build > @@ -93,6 +93,7 @@ test_sources =3D files('commands.c', > =09'test_rawdev.c', > =09'test_rcu_qsbr.c', > =09'test_rcu_qsbr_perf.c', > +=09'test_reassembly_perf.c', > =09'test_reciprocal_division.c', > =09'test_reciprocal_division_perf.c', > =09'test_red.c', > @@ -272,6 +273,7 @@ perf_test_names =3D [ > 'rand_perf_autotest', > 'hash_readwrite_perf_autotest', > 'hash_readwrite_lf_perf_autotest', > + 'reassembly_perf_autotest', > ] > =20 > driver_test_names =3D [ > diff --git a/app/test/test_reassembly_perf.c b/app/test/test_reassembly_p= erf.c > new file mode 100644 > index 000000000..8ed7c624c > --- /dev/null > +++ b/app/test/test_reassembly_perf.c > @@ -0,0 +1,989 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Marvell, Inc > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "test.h" > + > +#define MAX_FLOWS 1024 * 1024 > +#define MAX_BKTS MAX_FLOWS > +#define MAX_ENTRIES_PER_BKT 16 > +#define MAX_FRAGMENTS RTE_LIBRTE_IP_FRAG_MAX_FRAG > +#define MIN_FRAGMENTS 2 > +#define MAX_PKTS MAX_FLOWS *MAX_FRAGMENTS > + > +#define MAX_PKT_LEN 2048 > +#define MAX_TTL_MS 5 * MS_PER_S > + > +/* use RFC863 Discard Protocol */ > +#define UDP_SRC_PORT 9 > +#define UDP_DST_PORT 9 > + > +/* use RFC5735 / RFC2544 reserved network test addresses */ > +#define IP_SRC_ADDR(x) (198U << 24) | (18 << 16) | (0 << 8) | x > +#define IP_DST_ADDR(x) (198U << 24) | (18 << 16) | (1 << 8) | x > + > +/* 2001:0200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180)= */ > +static uint8_t ip6_addr[16] =3D {32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,= 0, 0, 0}; > +#define IP6_VERSION 6 > + > +#define IP_DEFTTL 64 /* from RFC 1340. */ > + > +static struct rte_ip_frag_tbl *frag_tbl; > +static struct rte_mempool *pkt_pool; > +static struct rte_mbuf *mbufs[MAX_FLOWS][MAX_FRAGMENTS]; > +static uint8_t frag_per_flow[MAX_FLOWS]; > +static uint32_t flow_cnt; > + > +#define FILL_MODE_LINEAR 0 > +#define FILL_MODE_RANDOM 1 > +#define FILL_MODE_INTERLEAVED 2 > + > +static int > +reassembly_test_setup(void) > +{ > +=09uint64_t max_ttl_cyc =3D (MAX_TTL_MS * rte_get_timer_hz()) / 1E3; > + > +=09frag_tbl =3D rte_ip_frag_table_create(MAX_FLOWS, MAX_ENTRIES_PER_BKT, > +=09=09=09=09=09 MAX_FLOWS * MAX_ENTRIES_PER_BKT, > +=09=09=09=09=09 max_ttl_cyc, rte_socket_id()); > +=09if (frag_tbl =3D=3D NULL) > +=09=09return TEST_FAILED; > + > +=09pkt_pool =3D rte_pktmbuf_pool_create( > +=09=09"reassembly_perf_pool", MAX_FLOWS * MAX_FRAGMENTS, 0, 0, > +=09=09RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); > +=09if (pkt_pool =3D=3D NULL) { > +=09=09printf("[%s] Failed to create pkt pool\n", __func__); > +=09=09rte_ip_frag_table_destroy(frag_tbl); > +=09=09return TEST_FAILED; > +=09} > + > +=09return TEST_SUCCESS; > +} > + > +static void > +reassembly_test_teardown(void) > +{ > +=09if (frag_tbl !=3D NULL) > +=09=09rte_ip_frag_table_destroy(frag_tbl); > + > +=09if (pkt_pool !=3D NULL) > +=09=09rte_mempool_free(pkt_pool); > +} > + > +static void > +randomize_array_positions(void **array, uint8_t sz) > +{ > +=09void *tmp; > +=09int i, j; > + > +=09if (sz =3D=3D 2) { > +=09=09tmp =3D array[0]; > +=09=09array[0] =3D array[1]; > +=09=09array[1] =3D tmp; > +=09} else { > +=09=09for (i =3D sz - 1; i > 0; i--) { > +=09=09=09j =3D rte_rand_max(i + 1); > +=09=09=09tmp =3D array[i]; > +=09=09=09array[i] =3D array[j]; > +=09=09=09array[j] =3D tmp; > +=09=09} > +=09} > +} > + > +static void > +reassembly_print_banner(const char *proto_str) > +{ > +=09printf("+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D" > +=09 "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n= "); > +=09printf("| %-32s| %-3s : %-58d|\n", proto_str, "Flow Count", MAX_FLOWS= ); > +=09printf("+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+" > +=09 "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n")= ; > +=09printf("%-17s%-17s%-14s%-14s%-25s%-20s\n", "| Fragment Order", > +=09 "| Fragments/Flow", "| Outstanding", "| Cycles/Flow", > +=09 "| Cycles/Fragment insert", "| Cycles/Reassembly |"); > +=09printf("+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+" > +=09 "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n")= ; > +} > + > +static void > +ipv4_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t f= low_id, > +=09=09 uint8_t fill_mode) > +{ > +=09struct rte_ether_hdr *eth_hdr; > +=09struct rte_ipv4_hdr *ip_hdr; > +=09struct rte_udp_hdr *udp_hdr; > +=09uint16_t frag_len; > +=09uint8_t i; > + > +=09frag_len =3D MAX_PKT_LEN / nb_frags; > +=09if (frag_len % 8) > +=09=09frag_len =3D RTE_ALIGN_MUL_CEIL(frag_len, 8); > + > +=09for (i =3D 0; i < nb_frags; i++) { > +=09=09struct rte_mbuf *frag =3D mbuf[i]; > +=09=09uint16_t frag_offset =3D 0; > +=09=09uint32_t ip_cksum; > +=09=09uint16_t pkt_len; > +=09=09uint16_t *ptr16; > + > +=09=09frag_offset =3D i * (frag_len / 8); > + > +=09=09if (i =3D=3D nb_frags - 1) > +=09=09=09frag_len =3D MAX_PKT_LEN - (frag_len * (nb_frags - 1)); > +=09=09else > +=09=09=09frag_offset |=3D RTE_IPV4_HDR_MF_FLAG; > + > +=09=09rte_pktmbuf_reset_headroom(frag); > +=09=09eth_hdr =3D rte_pktmbuf_mtod(frag, struct rte_ether_hdr *); > +=09=09ip_hdr =3D rte_pktmbuf_mtod_offset(frag, struct rte_ipv4_hdr *, > +=09=09=09=09=09=09 sizeof(struct rte_ether_hdr)); > +=09=09udp_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09frag, struct rte_udp_hdr *, > +=09=09=09sizeof(struct rte_ether_hdr) + > +=09=09=09=09sizeof(struct rte_ipv4_hdr)); > + > +=09=09rte_ether_unformat_addr("02:00:00:00:00:01", ð_hdr->d_addr); > +=09=09rte_ether_unformat_addr("02:00:00:00:00:00", ð_hdr->s_addr); > +=09=09eth_hdr->ether_type =3D rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); > + > +=09=09pkt_len =3D frag_len; > +=09=09/* > +=09=09 * Initialize UDP header. > +=09=09 */ > +=09=09if (i =3D=3D 0) { > +=09=09=09udp_hdr->src_port =3D rte_cpu_to_be_16(UDP_SRC_PORT); > +=09=09=09udp_hdr->dst_port =3D rte_cpu_to_be_16(UDP_DST_PORT); > +=09=09=09udp_hdr->dgram_len =3D rte_cpu_to_be_16(pkt_len); > +=09=09=09udp_hdr->dgram_cksum =3D 0; /* No UDP checksum. */ > +=09=09} > + > +=09=09/* > +=09=09 * Initialize IP header. > +=09=09 */ > +=09=09pkt_len =3D (uint16_t)(pkt_len + sizeof(struct rte_ipv4_hdr)); > +=09=09ip_hdr->version_ihl =3D RTE_IPV4_VHL_DEF; > +=09=09ip_hdr->type_of_service =3D 0; > +=09=09ip_hdr->fragment_offset =3D rte_cpu_to_be_16(frag_offset); > +=09=09ip_hdr->time_to_live =3D IP_DEFTTL; > +=09=09ip_hdr->next_proto_id =3D IPPROTO_UDP; > +=09=09ip_hdr->packet_id =3D > +=09=09=09rte_cpu_to_be_16((flow_id + 1) % UINT16_MAX); > +=09=09ip_hdr->total_length =3D rte_cpu_to_be_16(pkt_len); > +=09=09ip_hdr->src_addr =3D rte_cpu_to_be_32(IP_SRC_ADDR(flow_id)); > +=09=09ip_hdr->dst_addr =3D rte_cpu_to_be_32(IP_DST_ADDR(flow_id)); > + > +=09=09/* > +=09=09 * Compute IP header checksum. > +=09=09 */ > +=09=09ptr16 =3D (unaligned_uint16_t *)ip_hdr; > +=09=09ip_cksum =3D 0; > +=09=09ip_cksum +=3D ptr16[0]; > +=09=09ip_cksum +=3D ptr16[1]; > +=09=09ip_cksum +=3D ptr16[2]; > +=09=09ip_cksum +=3D ptr16[3]; > +=09=09ip_cksum +=3D ptr16[4]; > +=09=09ip_cksum +=3D ptr16[6]; > +=09=09ip_cksum +=3D ptr16[7]; > +=09=09ip_cksum +=3D ptr16[8]; > +=09=09ip_cksum +=3D ptr16[9]; > + > +=09=09/* > +=09=09 * Reduce 32 bit checksum to 16 bits and complement it. > +=09=09 */ > +=09=09ip_cksum =3D ((ip_cksum & 0xFFFF0000) >> 16) + > +=09=09=09 (ip_cksum & 0x0000FFFF); > +=09=09if (ip_cksum > 65535) > +=09=09=09ip_cksum -=3D 65535; > +=09=09ip_cksum =3D (~ip_cksum) & 0x0000FFFF; > +=09=09if (ip_cksum =3D=3D 0) > +=09=09=09ip_cksum =3D 0xFFFF; > +=09=09ip_hdr->hdr_checksum =3D (uint16_t)ip_cksum; > + > +=09=09frag->data_len =3D sizeof(struct rte_ether_hdr) + pkt_len; > +=09=09frag->pkt_len =3D frag->data_len; > +=09=09frag->l2_len =3D sizeof(struct rte_ether_hdr); > +=09=09frag->l3_len =3D sizeof(struct rte_ipv4_hdr); > +=09} > + > +=09if (fill_mode =3D=3D FILL_MODE_RANDOM) > +=09=09randomize_array_positions((void **)mbuf, nb_frags); > +} > + > +static uint8_t > +get_rand_frags(uint8_t max_frag) > +{ > +=09uint8_t frags =3D rte_rand_max(max_frag + 1); > + > +=09return frags <=3D 1 ? MIN_FRAGMENTS : frags; > +} > + > +static int > +ipv4_rand_frag_pkt_setup(uint8_t fill_mode, uint8_t max_frag) > +{ > +=09uint8_t nb_frag; > +=09int i; > + > +=09for (i =3D 0; i < MAX_FLOWS; i++) { > +=09=09nb_frag =3D get_rand_frags(max_frag); > +=09=09if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) < > +=09=09 0) > +=09=09=09return TEST_FAILED; > +=09=09ipv4_frag_fill_data(mbufs[i], nb_frag, i, fill_mode); > +=09=09frag_per_flow[i] =3D nb_frag; > +=09} > +=09flow_cnt =3D i; > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv4_frag_pkt_setup(uint8_t fill_mode, uint8_t nb_frag) > +{ > +=09int i; > + > +=09for (i =3D 0; i < MAX_FLOWS; i++) { > +=09=09if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) < > +=09=09 0) > +=09=09=09return TEST_FAILED; > +=09=09ipv4_frag_fill_data(mbufs[i], nb_frag, i, fill_mode); > +=09=09frag_per_flow[i] =3D nb_frag; > +=09} > +=09flow_cnt =3D i; > + > +=09return TEST_SUCCESS; > +} > + > +static void > +ipv6_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t f= low_id, > +=09=09 uint8_t fill_mode) > +{ > +=09struct ipv6_extension_fragment *frag_hdr; > +=09struct rte_ether_hdr *eth_hdr; > +=09struct rte_ipv6_hdr *ip_hdr; > +=09struct rte_udp_hdr *udp_hdr; > +=09uint16_t frag_len; > +=09uint8_t i; > + > +=09frag_len =3D MAX_PKT_LEN / nb_frags; > +=09if (frag_len % 8) > +=09=09frag_len =3D RTE_ALIGN_MUL_CEIL(frag_len, 8); > + > +=09for (i =3D 0; i < nb_frags; i++) { > +=09=09struct rte_mbuf *frag =3D mbuf[i]; > +=09=09uint16_t frag_offset =3D 0; > +=09=09uint16_t pkt_len; > + > +=09=09frag_offset =3D i * (frag_len / 8); > +=09=09frag_offset <<=3D 3; > +=09=09if (i =3D=3D nb_frags - 1) { > +=09=09=09frag_len =3D MAX_PKT_LEN - (frag_len * (nb_frags - 1)); > +=09=09=09frag_offset =3D RTE_IPV6_SET_FRAG_DATA(frag_offset, 0); > +=09=09} else { > +=09=09=09frag_offset =3D RTE_IPV6_SET_FRAG_DATA(frag_offset, 1); > +=09=09} > + > +=09=09rte_pktmbuf_reset_headroom(frag); > +=09=09eth_hdr =3D rte_pktmbuf_mtod(frag, struct rte_ether_hdr *); > +=09=09ip_hdr =3D rte_pktmbuf_mtod_offset(frag, struct rte_ipv6_hdr *, > +=09=09=09=09=09=09 sizeof(struct rte_ether_hdr)); > +=09=09udp_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09frag, struct rte_udp_hdr *, > +=09=09=09sizeof(struct rte_ether_hdr) + > +=09=09=09=09sizeof(struct rte_ipv6_hdr) + > +=09=09=09=09RTE_IPV6_FRAG_HDR_SIZE); > +=09=09frag_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09frag, struct ipv6_extension_fragment *, > +=09=09=09sizeof(struct rte_ether_hdr) + > +=09=09=09=09sizeof(struct rte_ipv6_hdr)); > + > +=09=09rte_ether_unformat_addr("02:00:00:00:00:01", ð_hdr->d_addr); > +=09=09rte_ether_unformat_addr("02:00:00:00:00:00", ð_hdr->s_addr); > +=09=09eth_hdr->ether_type =3D rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); > + > +=09=09pkt_len =3D frag_len; > +=09=09/* > +=09=09 * Initialize UDP header. > +=09=09 */ > +=09=09if (i =3D=3D 0) { > +=09=09=09udp_hdr->src_port =3D rte_cpu_to_be_16(UDP_SRC_PORT); > +=09=09=09udp_hdr->dst_port =3D rte_cpu_to_be_16(UDP_DST_PORT); > +=09=09=09udp_hdr->dgram_len =3D rte_cpu_to_be_16(pkt_len); > +=09=09=09udp_hdr->dgram_cksum =3D 0; /* No UDP checksum. */ ^^^ This is expressly forbidden in ipv6 (see RFC2460). Is the fragment reassembly not caring about this? I didn't check if ipv6 fragmenting code actually generates a proper udp checksum, either. I don't think it should prevent us from adding this test case, but we should try to fix it in the library if it isn't already. > +=09=09} > + > +=09=09/* > +=09=09 * Initialize IP header. > +=09=09 */ > +=09=09pkt_len =3D (uint16_t)(pkt_len + sizeof(struct rte_ipv6_hdr) + > +=09=09=09=09 RTE_IPV6_FRAG_HDR_SIZE); > +=09=09ip_hdr->vtc_flow =3D rte_cpu_to_be_32(IP6_VERSION << 28); > +=09=09ip_hdr->payload_len =3D > +=09=09=09rte_cpu_to_be_16(pkt_len - sizeof(struct rte_ipv6_hdr)); > +=09=09ip_hdr->proto =3D IPPROTO_FRAGMENT; > +=09=09ip_hdr->hop_limits =3D IP_DEFTTL; > +=09=09memcpy(ip_hdr->src_addr, ip6_addr, sizeof(ip_hdr->src_addr)); > +=09=09memcpy(ip_hdr->dst_addr, ip6_addr, sizeof(ip_hdr->dst_addr)); > +=09=09ip_hdr->src_addr[7] =3D (flow_id >> 16) & 0xf; > +=09=09ip_hdr->src_addr[7] |=3D 0x10; > +=09=09ip_hdr->src_addr[8] =3D (flow_id >> 8) & 0xff; > +=09=09ip_hdr->src_addr[9] =3D flow_id & 0xff; > + > +=09=09ip_hdr->dst_addr[7] =3D (flow_id >> 16) & 0xf; > +=09=09ip_hdr->dst_addr[7] |=3D 0x20; > +=09=09ip_hdr->dst_addr[8] =3D (flow_id >> 8) & 0xff; > +=09=09ip_hdr->dst_addr[9] =3D flow_id & 0xff; > + > +=09=09frag_hdr->next_header =3D IPPROTO_UDP; > +=09=09frag_hdr->reserved =3D 0; > +=09=09frag_hdr->frag_data =3D rte_cpu_to_be_16(frag_offset); > +=09=09frag_hdr->id =3D rte_cpu_to_be_32(flow_id + 1); > + > +=09=09frag->data_len =3D sizeof(struct rte_ether_hdr) + pkt_len; > +=09=09frag->pkt_len =3D frag->data_len; > +=09=09frag->l2_len =3D sizeof(struct rte_ether_hdr); > +=09=09frag->l3_len =3D > +=09=09=09sizeof(struct rte_ipv6_hdr) + RTE_IPV6_FRAG_HDR_SIZE; > +=09} > + > +=09if (fill_mode =3D=3D FILL_MODE_RANDOM) > +=09=09randomize_array_positions((void **)mbuf, nb_frags); > +} > + > +static int > +ipv6_rand_frag_pkt_setup(uint8_t fill_mode, uint8_t max_frag) > +{ > +=09uint8_t nb_frag; > +=09int i; > + > +=09for (i =3D 0; i < MAX_FLOWS; i++) { > +=09=09nb_frag =3D get_rand_frags(max_frag); > +=09=09if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) < > +=09=09 0) > +=09=09=09return TEST_FAILED; > +=09=09ipv6_frag_fill_data(mbufs[i], nb_frag, i, fill_mode); > +=09=09frag_per_flow[i] =3D nb_frag; > +=09} > +=09flow_cnt =3D i; > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv6_frag_pkt_setup(uint8_t fill_mode, uint8_t nb_frag) > +{ > +=09int i; > + > +=09for (i =3D 0; i < MAX_FLOWS; i++) { > +=09=09if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) < > +=09=09 0) > +=09=09=09return TEST_FAILED; > +=09=09ipv6_frag_fill_data(mbufs[i], nb_frag, i, fill_mode); > +=09=09frag_per_flow[i] =3D nb_frag; > +=09} > +=09flow_cnt =3D i; > + > +=09return TEST_SUCCESS; > +} > + > +static void > +frag_pkt_teardown(void) > +{ > +=09uint32_t i; > + > +=09for (i =3D 0; i < flow_cnt; i++) > +=09=09rte_pktmbuf_free(mbufs[i][0]); > +} > + > +static void > +reassembly_print_stats(int8_t nb_frags, uint8_t fill_order, > +=09=09 uint32_t outstanding, uint64_t cyc_per_flow, > +=09=09 uint64_t cyc_per_frag_insert, > +=09=09 uint64_t cyc_per_reassembly) > +{ > +=09char frag_str[8], order_str[12]; > + > +=09if (nb_frags > 0) > +=09=09snprintf(frag_str, sizeof(frag_str), "%d", nb_frags); > +=09else > +=09=09snprintf(frag_str, sizeof(frag_str), "RANDOM"); > + > +=09switch (fill_order) { > +=09case FILL_MODE_LINEAR: > +=09=09snprintf(order_str, sizeof(order_str), "LINEAR"); > +=09=09break; > +=09case FILL_MODE_RANDOM: > +=09=09snprintf(order_str, sizeof(order_str), "RANDOM"); > +=09=09break; > +=09case FILL_MODE_INTERLEAVED: > +=09=09snprintf(order_str, sizeof(order_str), "INTERLEAVED"); > +=09=09break; > +=09default: > +=09=09break; > +=09} > + > +=09printf("| %-14s | %-14s | %-11d | %-11" PRIu64 " | %-22" PRIu64 > +=09 " | %-17" PRIu64 " |\n", > +=09 order_str, frag_str, outstanding, cyc_per_flow, > +=09 cyc_per_frag_insert, cyc_per_reassembly); > +=09printf("+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+" > +=09 "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+\n")= ; > +} > + > +static void > +join_array(struct rte_mbuf **dest_arr, struct rte_mbuf **src_arr, > +=09 uint8_t offset, uint8_t sz) > +{ > +=09int i, j; > + > +=09for (i =3D offset, j =3D 0; j < sz; i++, j++) > +=09=09dest_arr[i] =3D src_arr[j]; > +} > + > +static int > +ipv4_reassembly_perf(int8_t nb_frags, uint8_t fill_order) > +{ > +=09struct rte_ip_frag_death_row death_row; > +=09uint64_t total_reassembled_cyc =3D 0; > +=09uint64_t total_empty_cyc =3D 0; > +=09uint64_t tstamp, flow_tstamp; > +=09uint64_t frag_processed =3D 0; > +=09uint64_t total_cyc =3D 0; > +=09uint32_t i, j; > + > +=09for (i =3D 0; i < flow_cnt; i++) { > +=09=09struct rte_mbuf *buf_out =3D NULL; > +=09=09uint8_t reassembled =3D 0; > + > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D 0; j < frag_per_flow[i]; j++) { > +=09=09=09struct rte_mbuf *buf =3D mbufs[i][j]; > +=09=09=09struct rte_ipv4_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv4_hdr *, buf->l2_len); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out =3D rte_ipv4_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr); > + > +=09=09=09if (buf_out =3D=3D NULL) { > +=09=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09frag_processed++; > +=09=09=09=09continue; > +=09=09=09} else { > +=09=09=09=09/*Packet out*/ > +=09=09=09=09total_reassembled_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09reassembled =3D 1; > +=09=09=09} > +=09=09} > +=09=09total_cyc +=3D rte_rdtsc() - flow_tstamp; > +=09=09if (!reassembled || buf_out->nb_segs !=3D frag_per_flow[i]) > +=09=09=09return TEST_FAILED; > +=09=09memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS); > +=09=09mbufs[i][0] =3D buf_out; > +=09} > + > +=09reassembly_print_stats(nb_frags, fill_order, 0, total_cyc / flow_cnt, > +=09=09=09 total_empty_cyc / frag_processed, > +=09=09=09 total_reassembled_cyc / flow_cnt); > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv4_outstanding_reassembly_perf(int8_t nb_frags, uint8_t fill_order, > +=09=09=09=09 uint32_t outstanding) > +{ > +=09struct rte_ip_frag_death_row death_row; > +=09uint64_t total_reassembled_cyc =3D 0; > +=09uint64_t total_empty_cyc =3D 0; > +=09uint64_t tstamp, flow_tstamp; > +=09uint64_t frag_processed =3D 0; > +=09uint64_t total_cyc =3D 0; > +=09uint32_t i, j, k; > + > +=09k =3D outstanding; > +=09/* Insert outstanding fragments */ > +=09for (i =3D 0; k && (i < flow_cnt); i++) { > +=09=09struct rte_mbuf *buf_out =3D NULL; > + > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D frag_per_flow[i] - 1; j > 0; j--) { > +=09=09=09struct rte_mbuf *buf =3D mbufs[i][j]; > +=09=09=09struct rte_ipv4_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv4_hdr *, buf->l2_len); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out =3D rte_ipv4_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr); > +=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09frag_processed++; > +=09=09=09if (buf_out !=3D NULL) > +=09=09=09=09return TEST_FAILED; > + > +=09=09=09k--; > +=09=09} > +=09=09frag_per_flow[i] =3D 1; > +=09} > + > +=09for (i =3D 0; i < flow_cnt; i++) { > +=09=09struct rte_mbuf *buf_out =3D NULL; > +=09=09uint8_t reassembled =3D 0; > + > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D 0; j < frag_per_flow[i]; j++) { > +=09=09=09struct rte_mbuf *buf =3D mbufs[i][j]; > +=09=09=09struct rte_ipv4_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv4_hdr *, buf->l2_len); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out =3D rte_ipv4_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr); > + > +=09=09=09if (buf_out =3D=3D NULL) { > +=09=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09frag_processed++; > +=09=09=09=09continue; > +=09=09=09} else { > +=09=09=09=09/*Packet out*/ > +=09=09=09=09total_reassembled_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09reassembled =3D 1; > +=09=09=09} > +=09=09} > +=09=09total_cyc +=3D rte_rdtsc() - flow_tstamp; > +=09=09if (!reassembled) > +=09=09=09return TEST_FAILED; > +=09=09memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS); > +=09=09mbufs[i][0] =3D buf_out; > +=09} > + > +=09reassembly_print_stats(nb_frags, fill_order, outstanding, > +=09=09=09 total_cyc / flow_cnt, > +=09=09=09 total_empty_cyc / frag_processed, > +=09=09=09 total_reassembled_cyc / flow_cnt); > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv4_reassembly_interleaved_flows_perf(uint8_t nb_frags) > +{ > +=09struct rte_ip_frag_death_row death_row; > +=09uint64_t total_reassembled_cyc =3D 0; > +=09uint64_t total_empty_cyc =3D 0; > +=09uint64_t tstamp, flow_tstamp; > +=09uint64_t frag_processed =3D 0; > +=09uint64_t total_cyc =3D 0; > +=09uint32_t i, j; > + > +=09for (i =3D 0; i < flow_cnt; i +=3D 4) { > +=09=09struct rte_mbuf *buf_out[4] =3D {NULL}; > +=09=09uint8_t reassembled =3D 0; > +=09=09uint8_t nb_frags =3D 0; > +=09=09uint8_t prev =3D 0; > + > +=09=09for (j =3D 0; j < 4; j++) > +=09=09=09nb_frags +=3D frag_per_flow[i + j]; > + > +=09=09struct rte_mbuf *buf_arr[nb_frags]; > +=09=09for (j =3D 0; j < 4; j++) { > +=09=09=09join_array(buf_arr, mbufs[i + j], prev, > +=09=09=09=09 frag_per_flow[i + j]); > +=09=09=09prev +=3D frag_per_flow[i + j]; > +=09=09} > +=09=09randomize_array_positions((void **)buf_arr, nb_frags); > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D 0; j < nb_frags; j++) { > +=09=09=09struct rte_mbuf *buf =3D buf_arr[j]; > +=09=09=09struct rte_ipv4_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv4_hdr *, buf->l2_len); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out[reassembled] =3D rte_ipv4_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr); > + > +=09=09=09if (buf_out[reassembled] =3D=3D NULL) { > +=09=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09frag_processed++; > +=09=09=09=09continue; > +=09=09=09} else { > +=09=09=09=09/*Packet out*/ > +=09=09=09=09total_reassembled_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09reassembled++; > +=09=09=09} > +=09=09} > +=09=09total_cyc +=3D rte_rdtsc() - flow_tstamp; > +=09=09if (reassembled !=3D 4) > +=09=09=09return TEST_FAILED; > +=09=09for (j =3D 0; j < 4; j++) { > +=09=09=09memset(mbufs[i + j], 0, > +=09=09=09 sizeof(struct rte_mbuf *) * MAX_FRAGMENTS); > +=09=09=09mbufs[i + j][0] =3D buf_out[j]; > +=09=09} > +=09} > + > +=09reassembly_print_stats(nb_frags, FILL_MODE_INTERLEAVED, 0, > +=09=09=09 total_cyc / flow_cnt, > +=09=09=09 total_empty_cyc / frag_processed, > +=09=09=09 total_reassembled_cyc / flow_cnt); > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv6_reassembly_perf(int8_t nb_frags, uint8_t fill_order) > +{ > +=09struct rte_ip_frag_death_row death_row; > +=09uint64_t total_reassembled_cyc =3D 0; > +=09uint64_t total_empty_cyc =3D 0; > +=09uint64_t tstamp, flow_tstamp; > +=09uint64_t frag_processed =3D 0; > +=09uint64_t total_cyc =3D 0; > +=09uint32_t i, j; > + > +=09for (i =3D 0; i < flow_cnt; i++) { > +=09=09struct rte_mbuf *buf_out =3D NULL; > +=09=09uint8_t reassembled =3D 0; > + > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D 0; j < frag_per_flow[i]; j++) { > +=09=09=09struct rte_mbuf *buf =3D mbufs[i][j]; > +=09=09=09struct rte_ipv6_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv6_hdr *, buf->l2_len); > +=09=09=09struct ipv6_extension_fragment *frag_hdr =3D > +=09=09=09=09rte_pktmbuf_mtod_offset( > +=09=09=09=09=09buf, struct ipv6_extension_fragment *, > +=09=09=09=09=09buf->l2_len + > +=09=09=09=09=09=09sizeof(struct rte_ipv6_hdr)); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out =3D rte_ipv6_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr, > +=09=09=09=09frag_hdr); > + > +=09=09=09if (buf_out =3D=3D NULL) { > +=09=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09frag_processed++; > +=09=09=09=09continue; > +=09=09=09} else { > +=09=09=09=09/*Packet out*/ > +=09=09=09=09total_reassembled_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09reassembled =3D 1; > +=09=09=09} > +=09=09} > +=09=09total_cyc +=3D rte_rdtsc() - flow_tstamp; > +=09=09if (!reassembled || buf_out->nb_segs !=3D frag_per_flow[i]) > +=09=09=09return TEST_FAILED; > +=09=09memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS); > +=09=09mbufs[i][0] =3D buf_out; > +=09} > + > +=09reassembly_print_stats(nb_frags, fill_order, 0, total_cyc / flow_cnt, > +=09=09=09 total_empty_cyc / frag_processed, > +=09=09=09 total_reassembled_cyc / flow_cnt); > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv6_outstanding_reassembly_perf(int8_t nb_frags, uint8_t fill_order, > +=09=09=09=09 uint32_t outstanding) > +{ > +=09struct rte_ip_frag_death_row death_row; > +=09uint64_t total_reassembled_cyc =3D 0; > +=09uint64_t total_empty_cyc =3D 0; > +=09uint64_t tstamp, flow_tstamp; > +=09uint64_t frag_processed =3D 0; > +=09uint64_t total_cyc =3D 0; > +=09uint32_t i, j, k; > + > +=09k =3D outstanding; > +=09/* Insert outstanding fragments */ > +=09for (i =3D 0; k && (i < flow_cnt); i++) { > +=09=09struct rte_mbuf *buf_out =3D NULL; > + > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D frag_per_flow[i] - 1; j > 0; j--) { > +=09=09=09struct rte_mbuf *buf =3D mbufs[i][j]; > +=09=09=09struct rte_ipv6_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv6_hdr *, buf->l2_len); > +=09=09=09struct ipv6_extension_fragment *frag_hdr =3D > +=09=09=09=09rte_pktmbuf_mtod_offset( > +=09=09=09=09=09buf, struct ipv6_extension_fragment *, > +=09=09=09=09=09buf->l2_len + > +=09=09=09=09=09=09sizeof(struct rte_ipv6_hdr)); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out =3D rte_ipv6_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr, > +=09=09=09=09frag_hdr); > +=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09frag_processed++; > + > +=09=09=09if (buf_out !=3D NULL) > +=09=09=09=09return TEST_FAILED; > + > +=09=09=09k--; > +=09=09} > +=09=09frag_per_flow[i] =3D 1; > +=09} > + > +=09for (i =3D 0; i < flow_cnt; i++) { > +=09=09struct rte_mbuf *buf_out =3D NULL; > +=09=09uint8_t reassembled =3D 0; > + > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D 0; j < frag_per_flow[i]; j++) { > +=09=09=09struct rte_mbuf *buf =3D mbufs[i][j]; > +=09=09=09struct rte_ipv6_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv6_hdr *, buf->l2_len); > +=09=09=09struct ipv6_extension_fragment *frag_hdr =3D > +=09=09=09=09rte_pktmbuf_mtod_offset( > +=09=09=09=09=09buf, struct ipv6_extension_fragment *, > +=09=09=09=09=09buf->l2_len + > +=09=09=09=09=09=09sizeof(struct rte_ipv6_hdr)); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out =3D rte_ipv6_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr, > +=09=09=09=09frag_hdr); > + > +=09=09=09if (buf_out =3D=3D NULL) { > +=09=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09frag_processed++; > +=09=09=09=09continue; > +=09=09=09} else { > +=09=09=09=09/*Packet out*/ > +=09=09=09=09total_reassembled_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09reassembled =3D 1; > +=09=09=09} > +=09=09} > +=09=09total_cyc +=3D rte_rdtsc() - flow_tstamp; > +=09=09if (!reassembled) > +=09=09=09return TEST_FAILED; > +=09=09memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS); > +=09=09mbufs[i][0] =3D buf_out; > +=09} > + > +=09reassembly_print_stats(nb_frags, fill_order, outstanding, > +=09=09=09 total_cyc / flow_cnt, > +=09=09=09 total_empty_cyc / frag_processed, > +=09=09=09 total_reassembled_cyc / flow_cnt); > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv6_reassembly_interleaved_flows_perf(int8_t nb_frags) > +{ > +=09struct rte_ip_frag_death_row death_row; > +=09uint64_t total_reassembled_cyc =3D 0; > +=09uint64_t total_empty_cyc =3D 0; > +=09uint64_t tstamp, flow_tstamp; > +=09uint64_t frag_processed =3D 0; > +=09uint64_t total_cyc =3D 0; > +=09uint32_t i, j; > + > +=09for (i =3D 0; i < flow_cnt; i +=3D 4) { > +=09=09struct rte_mbuf *buf_out[4] =3D {NULL}; > +=09=09uint8_t reassembled =3D 0; > +=09=09uint8_t nb_frags =3D 0; > +=09=09uint8_t prev =3D 0; > + > +=09=09for (j =3D 0; j < 4; j++) > +=09=09=09nb_frags +=3D frag_per_flow[i + j]; > + > +=09=09struct rte_mbuf *buf_arr[nb_frags]; > +=09=09for (j =3D 0; j < 4; j++) { > +=09=09=09join_array(buf_arr, mbufs[i + j], prev, > +=09=09=09=09 frag_per_flow[i + j]); > +=09=09=09prev +=3D frag_per_flow[i + j]; > +=09=09} > +=09=09randomize_array_positions((void **)buf_arr, nb_frags); > +=09=09flow_tstamp =3D rte_rdtsc(); > +=09=09for (j =3D 0; j < nb_frags; j++) { > +=09=09=09struct rte_mbuf *buf =3D buf_arr[j]; > +=09=09=09struct rte_ipv6_hdr *ip_hdr =3D rte_pktmbuf_mtod_offset( > +=09=09=09=09buf, struct rte_ipv6_hdr *, buf->l2_len); > +=09=09=09struct ipv6_extension_fragment *frag_hdr =3D > +=09=09=09=09rte_pktmbuf_mtod_offset( > +=09=09=09=09=09buf, struct ipv6_extension_fragment *, > +=09=09=09=09=09buf->l2_len + > +=09=09=09=09=09=09sizeof(struct rte_ipv6_hdr)); > + > +=09=09=09tstamp =3D rte_rdtsc(); > +=09=09=09buf_out[reassembled] =3D rte_ipv6_frag_reassemble_packet( > +=09=09=09=09frag_tbl, &death_row, buf, flow_tstamp, ip_hdr, > +=09=09=09=09frag_hdr); > + > +=09=09=09if (buf_out[reassembled] =3D=3D NULL) { > +=09=09=09=09total_empty_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09frag_processed++; > +=09=09=09=09continue; > +=09=09=09} else { > +=09=09=09=09/*Packet out*/ > +=09=09=09=09total_reassembled_cyc +=3D rte_rdtsc() - tstamp; > +=09=09=09=09reassembled++; > +=09=09=09} > +=09=09} > +=09=09total_cyc +=3D rte_rdtsc() - flow_tstamp; > +=09=09if (reassembled !=3D 4) > +=09=09=09return TEST_FAILED; > +=09=09for (j =3D 0; j < 4; j++) { > +=09=09=09memset(mbufs[i + j], 0, > +=09=09=09 sizeof(struct rte_mbuf *) * MAX_FRAGMENTS); > +=09=09=09mbufs[i + j][0] =3D buf_out[j]; > +=09=09} > +=09} > + > +=09reassembly_print_stats(nb_frags, FILL_MODE_INTERLEAVED, 0, > +=09=09=09 total_cyc / flow_cnt, > +=09=09=09 total_empty_cyc / frag_processed, > +=09=09=09 total_reassembled_cyc / flow_cnt); > + > +=09return TEST_SUCCESS; > +} > + > +static int > +ipv4_reassembly_test(int8_t nb_frags, uint8_t fill_order, uint32_t outst= anding) > +{ > +=09int rc; > + > +=09if (nb_frags > 0) > +=09=09rc =3D ipv4_frag_pkt_setup(fill_order, nb_frags); > +=09else > +=09=09rc =3D ipv4_rand_frag_pkt_setup(fill_order, MAX_FRAGMENTS); > + > +=09if (rc) > +=09=09return rc; > + > +=09if (outstanding) > +=09=09rc =3D ipv4_outstanding_reassembly_perf(nb_frags, fill_order, > +=09=09=09=09=09=09 outstanding); > +=09else if (fill_order =3D=3D FILL_MODE_INTERLEAVED) > +=09=09rc =3D ipv4_reassembly_interleaved_flows_perf(nb_frags); > +=09else > +=09=09rc =3D ipv4_reassembly_perf(nb_frags, fill_order); > + > +=09frag_pkt_teardown(); > + > +=09return rc; > +} > + > +static int > +ipv6_reassembly_test(int8_t nb_frags, uint8_t fill_order, uint32_t outst= anding) > +{ > +=09int rc; > + > +=09if (nb_frags > 0) > +=09=09rc =3D ipv6_frag_pkt_setup(fill_order, nb_frags); > +=09else > +=09=09rc =3D ipv6_rand_frag_pkt_setup(fill_order, MAX_FRAGMENTS); > + > +=09if (rc) > +=09=09return rc; > + > +=09if (outstanding) > +=09=09rc =3D ipv6_outstanding_reassembly_perf(nb_frags, fill_order, > +=09=09=09=09=09=09 outstanding); > +=09else if (fill_order =3D=3D FILL_MODE_INTERLEAVED) > +=09=09rc =3D ipv6_reassembly_interleaved_flows_perf(nb_frags); > +=09else > +=09=09rc =3D ipv6_reassembly_perf(nb_frags, fill_order); > + > +=09frag_pkt_teardown(); > + > +=09return rc; > +} > + > +static int > +test_reassembly_perf(void) > +{ > +=09int8_t nb_fragments[] =3D {2, 3, MAX_FRAGMENTS, -1 /* Random */}; > +=09uint8_t order_type[] =3D {FILL_MODE_LINEAR, FILL_MODE_RANDOM}; > +=09uint32_t outstanding[] =3D {100, 500, 1000, 2000, 3000}; > +=09uint32_t i, j; > +=09int rc; > + > +=09rc =3D reassembly_test_setup(); > +=09if (rc) > +=09=09return rc; > + > +=09reassembly_print_banner("IPV4"); > +=09/* Test variable fragment count and ordering. */ > +=09for (i =3D 0; i < RTE_DIM(nb_fragments); i++) { > +=09=09for (j =3D 0; j < RTE_DIM(order_type); j++) { > +=09=09=09rc =3D ipv4_reassembly_test(nb_fragments[i], > +=09=09=09=09=09=09 order_type[j], 0); > +=09=09=09if (rc) > +=09=09=09=09return rc; > +=09=09} > +=09} > + > +=09/* Test outstanding fragments in the table. */ > +=09for (i =3D 0; i < RTE_DIM(outstanding); i++) { > +=09=09rc =3D ipv4_reassembly_test(2, 0, outstanding[i]); > +=09=09if (rc) > +=09=09=09return rc; > +=09} > +=09for (i =3D 0; i < RTE_DIM(outstanding); i++) { > +=09=09rc =3D ipv4_reassembly_test(MAX_FRAGMENTS, 0, outstanding[i]); > +=09=09if (rc) > +=09=09=09return rc; > +=09} > + > +=09/* Test interleaved flow reassembly perf */ > +=09for (i =3D 0; i < RTE_DIM(nb_fragments); i++) { > +=09=09rc =3D ipv4_reassembly_test(nb_fragments[i], > +=09=09=09=09=09 FILL_MODE_INTERLEAVED, 0); > +=09=09if (rc) > +=09=09=09return rc; > +=09} > +=09printf("\n"); > +=09reassembly_print_banner("IPV6"); > +=09/* Test variable fragment count and ordering. */ > +=09for (i =3D 0; i < RTE_DIM(nb_fragments); i++) { > +=09=09for (j =3D 0; j < RTE_DIM(order_type); j++) { > +=09=09=09rc =3D ipv6_reassembly_test(nb_fragments[i], > +=09=09=09=09=09=09 order_type[j], 0); > +=09=09=09if (rc) > +=09=09=09=09return rc; > +=09=09} > +=09} > + > +=09/* Test outstanding fragments in the table. */ > +=09for (i =3D 0; i < RTE_DIM(outstanding); i++) { > +=09=09rc =3D ipv6_reassembly_test(2, 0, outstanding[i]); > +=09=09if (rc) > +=09=09=09return rc; > +=09} > + > +=09for (i =3D 0; i < RTE_DIM(outstanding); i++) { > +=09=09rc =3D ipv6_reassembly_test(MAX_FRAGMENTS, 0, outstanding[i]); > +=09=09if (rc) > +=09=09=09return rc; > +=09} > + > +=09/* Test interleaved flow reassembly perf */ > +=09for (i =3D 0; i < RTE_DIM(nb_fragments); i++) { > +=09=09rc =3D ipv6_reassembly_test(nb_fragments[i], > +=09=09=09=09=09 FILL_MODE_INTERLEAVED, 0); > +=09=09if (rc) > +=09=09=09return rc; > +=09} > +=09reassembly_test_teardown(); > + > +=09return TEST_SUCCESS; > +} > + > +REGISTER_TEST_COMMAND(reassembly_perf_autotest, test_reassembly_perf); > \ No newline at end of file