LCOV - code coverage report
Current view: top level - app/test - test_reassembly_perf.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 1 386 0.3 %
Date: 2025-01-02 22:41:34 Functions: 1 21 4.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 222 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2023 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_byteorder.h>
       6                 :            : #include <rte_common.h>
       7                 :            : #include <rte_cycles.h>
       8                 :            : #include <rte_ether.h>
       9                 :            : #include <rte_hexdump.h>
      10                 :            : #include <rte_ip.h>
      11                 :            : #include <rte_ip_frag.h>
      12                 :            : #include <rte_mbuf.h>
      13                 :            : #include <rte_mbuf_pool_ops.h>
      14                 :            : #include <rte_os_shim.h>
      15                 :            : #include <rte_random.h>
      16                 :            : #include <rte_udp.h>
      17                 :            : 
      18                 :            : #include "test.h"
      19                 :            : 
      20                 :            : #define MAX_FLOWS           (1024 * 32)
      21                 :            : #define MAX_BKTS            MAX_FLOWS
      22                 :            : #define MAX_ENTRIES_PER_BKT 16
      23                 :            : #define MAX_FRAGMENTS       RTE_LIBRTE_IP_FRAG_MAX_FRAG
      24                 :            : #define MIN_FRAGMENTS       2
      25                 :            : #define MAX_PKTS            (MAX_FLOWS * MAX_FRAGMENTS)
      26                 :            : 
      27                 :            : #define MAX_PKT_LEN 2048
      28                 :            : #define MAX_TTL_MS  (5 * MS_PER_S)
      29                 :            : 
      30                 :            : /* use RFC863 Discard Protocol */
      31                 :            : #define UDP_SRC_PORT 9
      32                 :            : #define UDP_DST_PORT 9
      33                 :            : 
      34                 :            : /* use RFC5735 / RFC2544 reserved network test addresses */
      35                 :            : #define IP_SRC_ADDR(x) ((198U << 24) | (18 << 16) | (0 << 8) | (x))
      36                 :            : #define IP_DST_ADDR(x) ((198U << 24) | (18 << 16) | (1 << 15) | (x))
      37                 :            : 
      38                 :            : /* 2001:0200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180) */
      39                 :            : static struct rte_ipv6_addr ip6_addr = RTE_IPV6(0x2001, 0x0200, 0, 0, 0, 0, 0, 0);
      40                 :            : #define IP6_VERSION 6
      41                 :            : 
      42                 :            : #define IP_DEFTTL 64 /* from RFC 1340. */
      43                 :            : 
      44                 :            : static struct rte_ip_frag_tbl *frag_tbl;
      45                 :            : static struct rte_mempool *pkt_pool;
      46                 :            : static struct rte_mbuf *mbufs[MAX_FLOWS][MAX_FRAGMENTS];
      47                 :            : static uint8_t frag_per_flow[MAX_FLOWS];
      48                 :            : static uint32_t flow_cnt;
      49                 :            : 
      50                 :            : #define FILL_MODE_LINEAR      0
      51                 :            : #define FILL_MODE_RANDOM      1
      52                 :            : #define FILL_MODE_INTERLEAVED 2
      53                 :            : 
      54                 :            : static int
      55                 :          0 : reassembly_test_setup(void)
      56                 :            : {
      57                 :          0 :         uint64_t max_ttl_cyc = (MAX_TTL_MS * rte_get_timer_hz()) / 1E3;
      58                 :            : 
      59                 :          0 :         frag_tbl = rte_ip_frag_table_create(MAX_BKTS, MAX_ENTRIES_PER_BKT,
      60                 :            :                                             MAX_BKTS * MAX_ENTRIES_PER_BKT, max_ttl_cyc,
      61                 :          0 :                                             rte_socket_id());
      62         [ #  # ]:          0 :         if (frag_tbl == NULL)
      63                 :            :                 return TEST_FAILED;
      64                 :            : 
      65                 :          0 :         rte_mbuf_set_user_mempool_ops("ring_mp_mc");
      66                 :          0 :         pkt_pool = rte_pktmbuf_pool_create(
      67                 :            :                 "reassembly_perf_pool", MAX_FLOWS * MAX_FRAGMENTS, 0, 0,
      68                 :          0 :                 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
      69         [ #  # ]:          0 :         if (pkt_pool == NULL) {
      70                 :            :                 printf("[%s] Failed to create pkt pool\n", __func__);
      71                 :          0 :                 rte_ip_frag_table_destroy(frag_tbl);
      72                 :          0 :                 return TEST_FAILED;
      73                 :            :         }
      74                 :            : 
      75                 :            :         return TEST_SUCCESS;
      76                 :            : }
      77                 :            : 
      78                 :            : static void
      79                 :          0 : reassembly_test_teardown(void)
      80                 :            : {
      81         [ #  # ]:          0 :         if (frag_tbl != NULL)
      82                 :          0 :                 rte_ip_frag_table_destroy(frag_tbl);
      83                 :            : 
      84                 :          0 :         rte_mempool_free(pkt_pool);
      85                 :          0 : }
      86                 :            : 
      87                 :            : static void
      88                 :          0 : randomize_array_positions(void **array, uint8_t sz)
      89                 :            : {
      90                 :            :         void *tmp;
      91                 :            :         int i, j;
      92                 :            : 
      93         [ #  # ]:          0 :         if (sz == 2) {
      94                 :          0 :                 tmp = array[0];
      95                 :          0 :                 array[0] = array[1];
      96                 :          0 :                 array[1] = tmp;
      97                 :            :         } else {
      98         [ #  # ]:          0 :                 for (i = sz - 1; i > 0; i--) {
      99                 :          0 :                         j = rte_rand_max(i + 1);
     100                 :          0 :                         tmp = array[i];
     101                 :          0 :                         array[i] = array[j];
     102                 :          0 :                         array[j] = tmp;
     103                 :            :                 }
     104                 :            :         }
     105                 :          0 : }
     106                 :            : 
     107                 :            : static void
     108                 :          0 : reassembly_print_banner(const char *proto_str)
     109                 :            : {
     110                 :            :         printf("+=============================================================="
     111                 :            :                "============================================+\n");
     112                 :            :         printf("| %-32s| %-3s : %-58d|\n", proto_str, "Flow Count", MAX_FLOWS);
     113                 :            :         printf("+================+================+=============+=============+"
     114                 :            :                "========================+===================+\n");
     115                 :            :         printf("%-17s%-17s%-14s%-14s%-25s%-20s\n", "| Fragment Order",
     116                 :            :                "| Fragments/Flow", "| Outstanding", "| Cycles/Flow",
     117                 :            :                "| Cycles/Fragment insert", "| Cycles/Reassembly |");
     118                 :            :         printf("+================+================+=============+=============+"
     119                 :            :                "========================+===================+\n");
     120                 :          0 : }
     121                 :            : 
     122                 :            : static void
     123                 :          0 : ipv4_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t flow_id,
     124                 :            :                     uint8_t fill_mode)
     125                 :            : {
     126                 :            :         struct rte_ether_hdr *eth_hdr;
     127                 :            :         struct rte_ipv4_hdr *ip_hdr;
     128                 :            :         struct rte_udp_hdr *udp_hdr;
     129                 :            :         uint16_t frag_len;
     130                 :            :         uint8_t i;
     131                 :            : 
     132                 :          0 :         frag_len = MAX_PKT_LEN / nb_frags;
     133         [ #  # ]:          0 :         if (frag_len % 8)
     134                 :          0 :                 frag_len = RTE_ALIGN_MUL_CEIL(frag_len, 8);
     135                 :            : 
     136         [ #  # ]:          0 :         for (i = 0; i < nb_frags; i++) {
     137                 :          0 :                 struct rte_mbuf *frag = mbuf[i];
     138                 :            :                 uint16_t frag_offset = 0;
     139                 :            :                 uint16_t pkt_len;
     140                 :            : 
     141                 :          0 :                 frag_offset = i * (frag_len / 8);
     142                 :            : 
     143         [ #  # ]:          0 :                 if (i == nb_frags - 1)
     144                 :          0 :                         frag_len = MAX_PKT_LEN - (frag_len * (nb_frags - 1));
     145                 :            :                 else
     146                 :          0 :                         frag_offset |= RTE_IPV4_HDR_MF_FLAG;
     147                 :            : 
     148                 :            :                 rte_pktmbuf_reset_headroom(frag);
     149                 :          0 :                 eth_hdr = rte_pktmbuf_mtod(frag, struct rte_ether_hdr *);
     150                 :          0 :                 ip_hdr = rte_pktmbuf_mtod_offset(frag, struct rte_ipv4_hdr *,
     151                 :            :                                                  sizeof(struct rte_ether_hdr));
     152                 :          0 :                 udp_hdr = rte_pktmbuf_mtod_offset(
     153                 :            :                         frag, struct rte_udp_hdr *,
     154                 :            :                         sizeof(struct rte_ether_hdr) +
     155                 :            :                                 sizeof(struct rte_ipv4_hdr));
     156                 :            : 
     157                 :          0 :                 rte_ether_unformat_addr("02:00:00:00:00:01",
     158                 :            :                                         &eth_hdr->dst_addr);
     159                 :          0 :                 rte_ether_unformat_addr("02:00:00:00:00:00",
     160                 :            :                                         &eth_hdr->src_addr);
     161                 :          0 :                 eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);
     162                 :            : 
     163                 :            :                 pkt_len = frag_len;
     164                 :            :                 /*
     165                 :            :                  * Initialize UDP header.
     166                 :            :                  */
     167         [ #  # ]:          0 :                 if (i == 0) {
     168                 :          0 :                         udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
     169                 :          0 :                         udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
     170         [ #  # ]:          0 :                         udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len);
     171                 :          0 :                         udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
     172                 :            :                 }
     173                 :            : 
     174                 :            :                 /*
     175                 :            :                  * Initialize IP header.
     176                 :            :                  */
     177                 :          0 :                 pkt_len = (uint16_t)(pkt_len + sizeof(struct rte_ipv4_hdr));
     178                 :          0 :                 ip_hdr->version_ihl = RTE_IPV4_VHL_DEF;
     179                 :          0 :                 ip_hdr->type_of_service = 0;
     180         [ #  # ]:          0 :                 ip_hdr->fragment_offset = rte_cpu_to_be_16(frag_offset);
     181                 :          0 :                 ip_hdr->time_to_live = IP_DEFTTL;
     182                 :          0 :                 ip_hdr->next_proto_id = IPPROTO_UDP;
     183                 :          0 :                 ip_hdr->packet_id =
     184         [ #  # ]:          0 :                         rte_cpu_to_be_16((flow_id + 1) % UINT16_MAX);
     185         [ #  # ]:          0 :                 ip_hdr->total_length = rte_cpu_to_be_16(pkt_len);
     186                 :            :                 /* Using more than 32K flows will modify the 2nd octet of the IP. */
     187         [ #  # ]:          0 :                 ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR(flow_id));
     188         [ #  # ]:          0 :                 ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR(flow_id));
     189                 :            : 
     190                 :          0 :                 ip_hdr->hdr_checksum = (uint16_t)rte_ipv4_cksum_simple(ip_hdr);
     191                 :            : 
     192                 :          0 :                 frag->data_len = sizeof(struct rte_ether_hdr) + pkt_len;
     193                 :          0 :                 frag->pkt_len = frag->data_len;
     194                 :          0 :                 frag->l2_len = sizeof(struct rte_ether_hdr);
     195                 :          0 :                 frag->l3_len = sizeof(struct rte_ipv4_hdr);
     196                 :            :         }
     197                 :            : 
     198         [ #  # ]:          0 :         if (fill_mode == FILL_MODE_RANDOM)
     199                 :          0 :                 randomize_array_positions((void **)mbuf, nb_frags);
     200                 :          0 : }
     201                 :            : 
     202                 :            : static uint8_t
     203                 :            : get_rand_frags(uint8_t max_frag)
     204                 :            : {
     205                 :          0 :         uint8_t frags = rte_rand_max(max_frag + 1);
     206                 :            : 
     207                 :          0 :         return frags <= 1 ? MIN_FRAGMENTS : frags;
     208                 :            : }
     209                 :            : 
     210                 :            : static int
     211                 :          0 : ipv4_rand_frag_pkt_setup(uint8_t fill_mode, uint8_t max_frag)
     212                 :            : {
     213                 :            :         uint8_t nb_frag;
     214                 :            :         int i;
     215                 :            : 
     216         [ #  # ]:          0 :         for (i = 0; i < MAX_FLOWS; i++) {
     217                 :          0 :                 nb_frag = get_rand_frags(max_frag);
     218   [ #  #  #  # ]:          0 :                 if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
     219                 :            :                     0)
     220                 :            :                         return TEST_FAILED;
     221                 :          0 :                 ipv4_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
     222                 :          0 :                 frag_per_flow[i] = nb_frag;
     223                 :            :         }
     224                 :          0 :         flow_cnt = i;
     225                 :            : 
     226                 :          0 :         return TEST_SUCCESS;
     227                 :            : }
     228                 :            : 
     229                 :            : static int
     230                 :          0 : ipv4_frag_pkt_setup(uint8_t fill_mode, uint8_t nb_frag)
     231                 :            : {
     232                 :            :         int i;
     233                 :            : 
     234         [ #  # ]:          0 :         for (i = 0; i < MAX_FLOWS; i++) {
     235   [ #  #  #  # ]:          0 :                 if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
     236                 :            :                     0)
     237                 :            :                         return TEST_FAILED;
     238                 :          0 :                 ipv4_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
     239                 :          0 :                 frag_per_flow[i] = nb_frag;
     240                 :            :         }
     241                 :          0 :         flow_cnt = i;
     242                 :            : 
     243                 :          0 :         return TEST_SUCCESS;
     244                 :            : }
     245                 :            : 
     246                 :            : static void
     247                 :          0 : ipv6_frag_fill_data(struct rte_mbuf **mbuf, uint8_t nb_frags, uint32_t flow_id,
     248                 :            :                     uint8_t fill_mode)
     249                 :            : {
     250                 :            :         struct ipv6_extension_fragment *frag_hdr;
     251                 :            :         struct rte_ether_hdr *eth_hdr;
     252                 :            :         struct rte_ipv6_hdr *ip_hdr;
     253                 :            :         struct rte_udp_hdr *udp_hdr;
     254                 :            :         uint16_t frag_len;
     255                 :            :         uint8_t i;
     256                 :            : 
     257                 :          0 :         frag_len = MAX_PKT_LEN / nb_frags;
     258         [ #  # ]:          0 :         if (frag_len % 8)
     259                 :          0 :                 frag_len = RTE_ALIGN_MUL_CEIL(frag_len, 8);
     260                 :            : 
     261         [ #  # ]:          0 :         for (i = 0; i < nb_frags; i++) {
     262                 :          0 :                 struct rte_mbuf *frag = mbuf[i];
     263                 :            :                 uint16_t frag_offset = 0;
     264                 :            :                 uint16_t pkt_len;
     265                 :            : 
     266                 :          0 :                 frag_offset = i * (frag_len / 8);
     267                 :          0 :                 frag_offset <<= 3;
     268         [ #  # ]:          0 :                 if (i == nb_frags - 1) {
     269                 :          0 :                         frag_len = MAX_PKT_LEN - (frag_len * (nb_frags - 1));
     270                 :            :                         frag_offset = RTE_IPV6_SET_FRAG_DATA(frag_offset, 0);
     271                 :            :                 } else {
     272                 :          0 :                         frag_offset = RTE_IPV6_SET_FRAG_DATA(frag_offset, 1);
     273                 :            :                 }
     274                 :            : 
     275                 :            :                 rte_pktmbuf_reset_headroom(frag);
     276                 :          0 :                 eth_hdr = rte_pktmbuf_mtod(frag, struct rte_ether_hdr *);
     277                 :          0 :                 ip_hdr = rte_pktmbuf_mtod_offset(frag, struct rte_ipv6_hdr *,
     278                 :            :                                                  sizeof(struct rte_ether_hdr));
     279                 :          0 :                 udp_hdr = rte_pktmbuf_mtod_offset(
     280                 :            :                         frag, struct rte_udp_hdr *,
     281                 :            :                         sizeof(struct rte_ether_hdr) +
     282                 :            :                                 sizeof(struct rte_ipv6_hdr) +
     283                 :            :                                 RTE_IPV6_FRAG_HDR_SIZE);
     284                 :          0 :                 frag_hdr = rte_pktmbuf_mtod_offset(
     285                 :            :                         frag, struct ipv6_extension_fragment *,
     286                 :            :                         sizeof(struct rte_ether_hdr) +
     287                 :            :                                 sizeof(struct rte_ipv6_hdr));
     288                 :            : 
     289                 :          0 :                 rte_ether_unformat_addr("02:00:00:00:00:01",
     290                 :            :                                         &eth_hdr->dst_addr);
     291                 :          0 :                 rte_ether_unformat_addr("02:00:00:00:00:00",
     292                 :            :                                         &eth_hdr->src_addr);
     293                 :          0 :                 eth_hdr->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6);
     294                 :            : 
     295                 :            :                 pkt_len = frag_len;
     296                 :            :                 /*
     297                 :            :                  * Initialize UDP header.
     298                 :            :                  */
     299         [ #  # ]:          0 :                 if (i == 0) {
     300                 :          0 :                         udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
     301                 :          0 :                         udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
     302         [ #  # ]:          0 :                         udp_hdr->dgram_len = rte_cpu_to_be_16(pkt_len);
     303                 :          0 :                         udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
     304                 :            :                 }
     305                 :            : 
     306                 :            :                 /*
     307                 :            :                  * Initialize IP header.
     308                 :            :                  */
     309                 :          0 :                 pkt_len = (uint16_t)(pkt_len + sizeof(struct rte_ipv6_hdr) +
     310                 :            :                                      RTE_IPV6_FRAG_HDR_SIZE);
     311                 :          0 :                 ip_hdr->vtc_flow = rte_cpu_to_be_32(IP6_VERSION << 28);
     312                 :          0 :                 ip_hdr->payload_len =
     313         [ #  # ]:          0 :                         rte_cpu_to_be_16(pkt_len - sizeof(struct rte_ipv6_hdr));
     314                 :          0 :                 ip_hdr->proto = IPPROTO_FRAGMENT;
     315                 :          0 :                 ip_hdr->hop_limits = IP_DEFTTL;
     316                 :          0 :                 ip_hdr->src_addr = ip6_addr;
     317                 :          0 :                 ip_hdr->dst_addr = ip6_addr;
     318                 :          0 :                 ip_hdr->src_addr.a[7] = (flow_id >> 16) & 0xf;
     319                 :          0 :                 ip_hdr->src_addr.a[7] |= 0x10;
     320                 :          0 :                 ip_hdr->src_addr.a[8] = (flow_id >> 8) & 0xff;
     321                 :          0 :                 ip_hdr->src_addr.a[9] = flow_id & 0xff;
     322                 :            : 
     323                 :            :                 ip_hdr->dst_addr.a[7] = (flow_id >> 16) & 0xf;
     324                 :          0 :                 ip_hdr->dst_addr.a[7] |= 0x20;
     325                 :          0 :                 ip_hdr->dst_addr.a[8] = (flow_id >> 8) & 0xff;
     326                 :          0 :                 ip_hdr->dst_addr.a[9] = flow_id & 0xff;
     327                 :            : 
     328                 :          0 :                 frag_hdr->next_header = IPPROTO_UDP;
     329                 :          0 :                 frag_hdr->reserved = 0;
     330         [ #  # ]:          0 :                 frag_hdr->frag_data = rte_cpu_to_be_16(frag_offset);
     331         [ #  # ]:          0 :                 frag_hdr->id = rte_cpu_to_be_32(flow_id + 1);
     332                 :            : 
     333                 :          0 :                 frag->data_len = sizeof(struct rte_ether_hdr) + pkt_len;
     334                 :          0 :                 frag->pkt_len = frag->data_len;
     335                 :          0 :                 frag->l2_len = sizeof(struct rte_ether_hdr);
     336                 :          0 :                 frag->l3_len =
     337                 :            :                         sizeof(struct rte_ipv6_hdr) + RTE_IPV6_FRAG_HDR_SIZE;
     338                 :            :         }
     339                 :            : 
     340         [ #  # ]:          0 :         if (fill_mode == FILL_MODE_RANDOM)
     341                 :          0 :                 randomize_array_positions((void **)mbuf, nb_frags);
     342                 :          0 : }
     343                 :            : 
     344                 :            : static int
     345                 :          0 : ipv6_rand_frag_pkt_setup(uint8_t fill_mode, uint8_t max_frag)
     346                 :            : {
     347                 :            :         uint8_t nb_frag;
     348                 :            :         int i;
     349                 :            : 
     350         [ #  # ]:          0 :         for (i = 0; i < MAX_FLOWS; i++) {
     351                 :          0 :                 nb_frag = get_rand_frags(max_frag);
     352   [ #  #  #  # ]:          0 :                 if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
     353                 :            :                     0)
     354                 :            :                         return TEST_FAILED;
     355                 :          0 :                 ipv6_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
     356                 :          0 :                 frag_per_flow[i] = nb_frag;
     357                 :            :         }
     358                 :          0 :         flow_cnt = i;
     359                 :            : 
     360                 :          0 :         return TEST_SUCCESS;
     361                 :            : }
     362                 :            : 
     363                 :            : static int
     364                 :          0 : ipv6_frag_pkt_setup(uint8_t fill_mode, uint8_t nb_frag)
     365                 :            : {
     366                 :            :         int i;
     367                 :            : 
     368         [ #  # ]:          0 :         for (i = 0; i < MAX_FLOWS; i++) {
     369   [ #  #  #  # ]:          0 :                 if (rte_mempool_get_bulk(pkt_pool, (void **)mbufs[i], nb_frag) <
     370                 :            :                     0)
     371                 :            :                         return TEST_FAILED;
     372                 :          0 :                 ipv6_frag_fill_data(mbufs[i], nb_frag, i, fill_mode);
     373                 :          0 :                 frag_per_flow[i] = nb_frag;
     374                 :            :         }
     375                 :          0 :         flow_cnt = i;
     376                 :            : 
     377                 :          0 :         return TEST_SUCCESS;
     378                 :            : }
     379                 :            : 
     380                 :            : static void
     381                 :            : frag_pkt_teardown(void)
     382                 :            : {
     383                 :            :         uint32_t i;
     384                 :            : 
     385   [ #  #  #  # ]:          0 :         for (i = 0; i < flow_cnt; i++)
     386                 :          0 :                 rte_pktmbuf_free(mbufs[i][0]);
     387                 :            : }
     388                 :            : 
     389                 :            : static void
     390                 :          0 : reassembly_print_stats(int8_t nb_frags, uint8_t fill_order,
     391                 :            :                        uint32_t outstanding, uint64_t cyc_per_flow,
     392                 :            :                        uint64_t cyc_per_frag_insert,
     393                 :            :                        uint64_t cyc_per_reassembly)
     394                 :            : {
     395                 :            :         char frag_str[8], order_str[12];
     396                 :            : 
     397         [ #  # ]:          0 :         if (nb_frags > 0)
     398                 :          0 :                 snprintf(frag_str, sizeof(frag_str), "%d", nb_frags);
     399                 :            :         else
     400                 :            :                 snprintf(frag_str, sizeof(frag_str), "RANDOM");
     401                 :            : 
     402   [ #  #  #  # ]:          0 :         switch (fill_order) {
     403                 :            :         case FILL_MODE_LINEAR:
     404                 :            :                 snprintf(order_str, sizeof(order_str), "LINEAR");
     405                 :            :                 break;
     406                 :            :         case FILL_MODE_RANDOM:
     407                 :            :                 snprintf(order_str, sizeof(order_str), "RANDOM");
     408                 :            :                 break;
     409                 :            :         case FILL_MODE_INTERLEAVED:
     410                 :            :                 snprintf(order_str, sizeof(order_str), "INTERLEAVED");
     411                 :            :                 break;
     412                 :            :         default:
     413                 :            :                 break;
     414                 :            :         }
     415                 :            : 
     416                 :            :         printf("| %-14s | %-14s | %-11d | %-11" PRIu64 " | %-22" PRIu64
     417                 :            :                " | %-17" PRIu64 " |\n",
     418                 :            :                order_str, frag_str, outstanding, cyc_per_flow,
     419                 :            :                cyc_per_frag_insert, cyc_per_reassembly);
     420                 :            :         printf("+================+================+=============+=============+"
     421                 :            :                "========================+===================+\n");
     422                 :          0 : }
     423                 :            : 
     424                 :            : static void
     425                 :            : join_array(struct rte_mbuf **dest_arr, struct rte_mbuf **src_arr,
     426                 :            :            uint8_t offset, uint8_t sz)
     427                 :            : {
     428                 :            :         int i, j;
     429                 :            : 
     430   [ #  #  #  # ]:          0 :         for (i = offset, j = 0; j < sz; i++, j++)
     431                 :          0 :                 dest_arr[i] = src_arr[j];
     432                 :            : }
     433                 :            : 
     434                 :            : static int
     435                 :          0 : ipv4_reassembly_perf(int8_t nb_frags, uint8_t fill_order)
     436                 :            : {
     437                 :            :         struct rte_ip_frag_death_row death_row;
     438                 :            :         uint64_t total_reassembled_cyc = 0;
     439                 :            :         uint64_t total_empty_cyc = 0;
     440                 :            :         uint64_t tstamp, flow_tstamp;
     441                 :            :         uint64_t frag_processed = 0;
     442                 :            :         uint64_t total_cyc = 0;
     443                 :            :         uint32_t i, j;
     444                 :            : 
     445         [ #  # ]:          0 :         for (i = 0; i < flow_cnt; i++) {
     446                 :            :                 struct rte_mbuf *buf_out = NULL;
     447                 :            :                 uint8_t reassembled = 0;
     448                 :            : 
     449                 :            :                 flow_tstamp = rte_rdtsc_precise();
     450         [ #  # ]:          0 :                 for (j = 0; j < frag_per_flow[i]; j++) {
     451                 :          0 :                         struct rte_mbuf *buf = mbufs[i][j];
     452                 :          0 :                         struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     453                 :            :                                 buf, struct rte_ipv4_hdr *, buf->l2_len);
     454                 :            : 
     455                 :            :                         tstamp = rte_rdtsc_precise();
     456                 :          0 :                         buf_out = rte_ipv4_frag_reassemble_packet(
     457                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
     458                 :            : 
     459         [ #  # ]:          0 :                         if (buf_out == NULL) {
     460                 :          0 :                                 total_empty_cyc += rte_rdtsc_precise() - tstamp;
     461                 :          0 :                                 frag_processed++;
     462                 :          0 :                                 continue;
     463                 :            :                         } else {
     464                 :            :                                 /*Packet out*/
     465                 :          0 :                                 total_reassembled_cyc +=
     466                 :          0 :                                         rte_rdtsc_precise() - tstamp;
     467                 :            :                                 reassembled = 1;
     468                 :            :                         }
     469                 :            :                 }
     470                 :          0 :                 total_cyc += rte_rdtsc_precise() - flow_tstamp;
     471   [ #  #  #  # ]:          0 :                 if (!reassembled || buf_out->nb_segs != frag_per_flow[i])
     472                 :            :                         return TEST_FAILED;
     473                 :          0 :                 memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
     474                 :          0 :                 mbufs[i][0] = buf_out;
     475                 :            :         }
     476                 :            : 
     477                 :          0 :         reassembly_print_stats(nb_frags, fill_order, 0, total_cyc / flow_cnt,
     478                 :            :                                total_empty_cyc / frag_processed,
     479                 :            :                                total_reassembled_cyc / flow_cnt);
     480                 :            : 
     481                 :          0 :         return TEST_SUCCESS;
     482                 :            : }
     483                 :            : 
     484                 :            : static int
     485                 :          0 : ipv4_outstanding_reassembly_perf(int8_t nb_frags, uint8_t fill_order,
     486                 :            :                                  uint32_t outstanding)
     487                 :            : {
     488                 :            :         struct rte_ip_frag_death_row death_row;
     489                 :            :         uint64_t total_reassembled_cyc = 0;
     490                 :            :         uint64_t total_empty_cyc = 0;
     491                 :            :         uint64_t tstamp, flow_tstamp;
     492                 :            :         uint64_t frag_processed = 0;
     493                 :            :         uint64_t total_cyc = 0;
     494                 :            :         uint32_t i, j, k;
     495                 :            : 
     496                 :            :         k = outstanding;
     497                 :            :         /* Insert outstanding fragments */
     498   [ #  #  #  # ]:          0 :         for (i = 0; k && (i < flow_cnt); i++) {
     499                 :            :                 struct rte_mbuf *buf_out = NULL;
     500                 :            : 
     501                 :            :                 flow_tstamp = rte_rdtsc_precise();
     502         [ #  # ]:          0 :                 for (j = frag_per_flow[i] - 1; j > 0; j--) {
     503                 :          0 :                         struct rte_mbuf *buf = mbufs[i][j];
     504                 :          0 :                         struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     505                 :            :                                 buf, struct rte_ipv4_hdr *, buf->l2_len);
     506                 :            : 
     507                 :            :                         tstamp = rte_rdtsc_precise();
     508                 :          0 :                         buf_out = rte_ipv4_frag_reassemble_packet(
     509                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
     510                 :          0 :                         total_empty_cyc += rte_rdtsc_precise() - tstamp;
     511                 :          0 :                         frag_processed++;
     512         [ #  # ]:          0 :                         if (buf_out != NULL)
     513                 :            :                                 return TEST_FAILED;
     514                 :            : 
     515                 :          0 :                         k--;
     516                 :            :                 }
     517                 :          0 :                 frag_per_flow[i] = 1;
     518                 :            :         }
     519                 :            : 
     520         [ #  # ]:          0 :         for (i = 0; i < flow_cnt; i++) {
     521                 :            :                 struct rte_mbuf *buf_out = NULL;
     522                 :            :                 uint8_t reassembled = 0;
     523                 :            : 
     524                 :            :                 flow_tstamp = rte_rdtsc_precise();
     525         [ #  # ]:          0 :                 for (j = 0; j < frag_per_flow[i]; j++) {
     526                 :          0 :                         struct rte_mbuf *buf = mbufs[i][j];
     527                 :          0 :                         struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     528                 :            :                                 buf, struct rte_ipv4_hdr *, buf->l2_len);
     529                 :            : 
     530                 :            :                         tstamp = rte_rdtsc_precise();
     531                 :          0 :                         buf_out = rte_ipv4_frag_reassemble_packet(
     532                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
     533                 :            : 
     534         [ #  # ]:          0 :                         if (buf_out == NULL) {
     535                 :          0 :                                 total_empty_cyc += rte_rdtsc_precise() - tstamp;
     536                 :          0 :                                 frag_processed++;
     537                 :          0 :                                 continue;
     538                 :            :                         } else {
     539                 :            :                                 /*Packet out*/
     540                 :          0 :                                 total_reassembled_cyc +=
     541                 :          0 :                                         rte_rdtsc_precise() - tstamp;
     542                 :            :                                 reassembled = 1;
     543                 :            :                         }
     544                 :            :                 }
     545                 :          0 :                 total_cyc += rte_rdtsc_precise() - flow_tstamp;
     546         [ #  # ]:          0 :                 if (!reassembled)
     547                 :            :                         return TEST_FAILED;
     548                 :          0 :                 memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
     549                 :          0 :                 mbufs[i][0] = buf_out;
     550                 :            :         }
     551                 :            : 
     552                 :          0 :         reassembly_print_stats(nb_frags, fill_order, outstanding,
     553                 :            :                                total_cyc / flow_cnt,
     554                 :            :                                total_empty_cyc / frag_processed,
     555                 :            :                                total_reassembled_cyc / flow_cnt);
     556                 :            : 
     557                 :          0 :         return TEST_SUCCESS;
     558                 :            : }
     559                 :            : 
     560                 :            : static int
     561                 :          0 : ipv4_reassembly_interleaved_flows_perf(uint8_t nb_frags)
     562                 :            : {
     563                 :            :         struct rte_ip_frag_death_row death_row;
     564                 :            :         uint64_t total_reassembled_cyc = 0;
     565                 :            :         uint64_t total_empty_cyc = 0;
     566                 :            :         uint64_t tstamp, flow_tstamp;
     567                 :            :         uint64_t frag_processed = 0;
     568                 :            :         uint64_t total_cyc = 0;
     569                 :            :         uint32_t i, j;
     570                 :            : 
     571         [ #  # ]:          0 :         for (i = 0; i < flow_cnt; i += 4) {
     572                 :          0 :                 struct rte_mbuf *buf_out[4] = {NULL};
     573                 :            :                 uint8_t reassembled = 0;
     574                 :            :                 uint8_t nb_frags = 0;
     575                 :            :                 uint8_t prev = 0;
     576                 :            : 
     577         [ #  # ]:          0 :                 for (j = 0; j < 4; j++)
     578                 :          0 :                         nb_frags += frag_per_flow[i + j];
     579                 :            : 
     580                 :          0 :                 struct rte_mbuf *buf_arr[nb_frags];
     581         [ #  # ]:          0 :                 for (j = 0; j < 4; j++) {
     582                 :          0 :                         join_array(buf_arr, mbufs[i + j], prev,
     583                 :          0 :                                    frag_per_flow[i + j]);
     584                 :          0 :                         prev += frag_per_flow[i + j];
     585                 :            :                 }
     586                 :          0 :                 randomize_array_positions((void **)buf_arr, nb_frags);
     587                 :            :                 flow_tstamp = rte_rdtsc_precise();
     588         [ #  # ]:          0 :                 for (j = 0; j < nb_frags; j++) {
     589                 :          0 :                         struct rte_mbuf *buf = buf_arr[j];
     590                 :          0 :                         struct rte_ipv4_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     591                 :            :                                 buf, struct rte_ipv4_hdr *, buf->l2_len);
     592                 :            : 
     593                 :            :                         tstamp = rte_rdtsc_precise();
     594                 :          0 :                         buf_out[reassembled] = rte_ipv4_frag_reassemble_packet(
     595                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr);
     596                 :            : 
     597         [ #  # ]:          0 :                         if (buf_out[reassembled] == NULL) {
     598                 :          0 :                                 total_empty_cyc += rte_rdtsc_precise() - tstamp;
     599                 :          0 :                                 frag_processed++;
     600                 :          0 :                                 continue;
     601                 :            :                         } else {
     602                 :            :                                 /*Packet out*/
     603                 :          0 :                                 total_reassembled_cyc +=
     604                 :          0 :                                         rte_rdtsc_precise() - tstamp;
     605                 :          0 :                                 reassembled++;
     606                 :            :                         }
     607                 :            :                 }
     608                 :          0 :                 total_cyc += rte_rdtsc_precise() - flow_tstamp;
     609         [ #  # ]:          0 :                 if (reassembled != 4)
     610                 :          0 :                         return TEST_FAILED;
     611         [ #  # ]:          0 :                 for (j = 0; j < 4; j++) {
     612                 :          0 :                         memset(mbufs[i + j], 0,
     613                 :            :                                sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
     614                 :          0 :                         mbufs[i + j][0] = buf_out[j];
     615                 :            :                 }
     616                 :            :         }
     617                 :            : 
     618                 :          0 :         reassembly_print_stats(nb_frags, FILL_MODE_INTERLEAVED, 0,
     619                 :            :                                total_cyc / flow_cnt,
     620                 :            :                                total_empty_cyc / frag_processed,
     621                 :            :                                total_reassembled_cyc / flow_cnt);
     622                 :            : 
     623                 :          0 :         return TEST_SUCCESS;
     624                 :            : }
     625                 :            : 
     626                 :            : static int
     627                 :          0 : ipv6_reassembly_perf(int8_t nb_frags, uint8_t fill_order)
     628                 :            : {
     629                 :            :         struct rte_ip_frag_death_row death_row;
     630                 :            :         uint64_t total_reassembled_cyc = 0;
     631                 :            :         uint64_t total_empty_cyc = 0;
     632                 :            :         uint64_t tstamp, flow_tstamp;
     633                 :            :         uint64_t frag_processed = 0;
     634                 :            :         uint64_t total_cyc = 0;
     635                 :            :         uint32_t i, j;
     636                 :            : 
     637         [ #  # ]:          0 :         for (i = 0; i < flow_cnt; i++) {
     638                 :            :                 struct rte_mbuf *buf_out = NULL;
     639                 :            :                 uint8_t reassembled = 0;
     640                 :            : 
     641                 :            :                 flow_tstamp = rte_rdtsc_precise();
     642         [ #  # ]:          0 :                 for (j = 0; j < frag_per_flow[i]; j++) {
     643                 :          0 :                         struct rte_mbuf *buf = mbufs[i][j];
     644                 :          0 :                         struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     645                 :            :                                 buf, struct rte_ipv6_hdr *, buf->l2_len);
     646                 :          0 :                         struct ipv6_extension_fragment *frag_hdr =
     647                 :          0 :                                 rte_pktmbuf_mtod_offset(
     648                 :            :                                         buf, struct ipv6_extension_fragment *,
     649                 :            :                                         buf->l2_len +
     650                 :            :                                                 sizeof(struct rte_ipv6_hdr));
     651                 :            : 
     652                 :            :                         tstamp = rte_rdtsc_precise();
     653                 :          0 :                         buf_out = rte_ipv6_frag_reassemble_packet(
     654                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
     655                 :            :                                 frag_hdr);
     656                 :            : 
     657         [ #  # ]:          0 :                         if (buf_out == NULL) {
     658                 :          0 :                                 total_empty_cyc += rte_rdtsc_precise() - tstamp;
     659                 :          0 :                                 frag_processed++;
     660                 :          0 :                                 continue;
     661                 :            :                         } else {
     662                 :            :                                 /*Packet out*/
     663                 :          0 :                                 total_reassembled_cyc +=
     664                 :          0 :                                         rte_rdtsc_precise() - tstamp;
     665                 :            :                                 reassembled = 1;
     666                 :            :                         }
     667                 :            :                 }
     668                 :          0 :                 total_cyc += rte_rdtsc_precise() - flow_tstamp;
     669   [ #  #  #  # ]:          0 :                 if (!reassembled || buf_out->nb_segs != frag_per_flow[i])
     670                 :            :                         return TEST_FAILED;
     671                 :          0 :                 memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
     672                 :          0 :                 mbufs[i][0] = buf_out;
     673                 :            :         }
     674                 :            : 
     675                 :          0 :         reassembly_print_stats(nb_frags, fill_order, 0, total_cyc / flow_cnt,
     676                 :            :                                total_empty_cyc / frag_processed,
     677                 :            :                                total_reassembled_cyc / flow_cnt);
     678                 :            : 
     679                 :          0 :         return TEST_SUCCESS;
     680                 :            : }
     681                 :            : 
     682                 :            : static int
     683                 :          0 : ipv6_outstanding_reassembly_perf(int8_t nb_frags, uint8_t fill_order,
     684                 :            :                                  uint32_t outstanding)
     685                 :            : {
     686                 :            :         struct rte_ip_frag_death_row death_row;
     687                 :            :         uint64_t total_reassembled_cyc = 0;
     688                 :            :         uint64_t total_empty_cyc = 0;
     689                 :            :         uint64_t tstamp, flow_tstamp;
     690                 :            :         uint64_t frag_processed = 0;
     691                 :            :         uint64_t total_cyc = 0;
     692                 :            :         uint32_t i, j, k;
     693                 :            : 
     694                 :            :         k = outstanding;
     695                 :            :         /* Insert outstanding fragments */
     696   [ #  #  #  # ]:          0 :         for (i = 0; k && (i < flow_cnt); i++) {
     697                 :            :                 struct rte_mbuf *buf_out = NULL;
     698                 :            : 
     699                 :            :                 flow_tstamp = rte_rdtsc_precise();
     700         [ #  # ]:          0 :                 for (j = frag_per_flow[i] - 1; j > 0; j--) {
     701                 :          0 :                         struct rte_mbuf *buf = mbufs[i][j];
     702                 :          0 :                         struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     703                 :            :                                 buf, struct rte_ipv6_hdr *, buf->l2_len);
     704                 :          0 :                         struct ipv6_extension_fragment *frag_hdr =
     705                 :          0 :                                 rte_pktmbuf_mtod_offset(
     706                 :            :                                         buf, struct ipv6_extension_fragment *,
     707                 :            :                                         buf->l2_len +
     708                 :            :                                                 sizeof(struct rte_ipv6_hdr));
     709                 :            : 
     710                 :            :                         tstamp = rte_rdtsc_precise();
     711                 :          0 :                         buf_out = rte_ipv6_frag_reassemble_packet(
     712                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
     713                 :            :                                 frag_hdr);
     714                 :          0 :                         total_empty_cyc += rte_rdtsc_precise() - tstamp;
     715                 :          0 :                         frag_processed++;
     716                 :            : 
     717         [ #  # ]:          0 :                         if (buf_out != NULL)
     718                 :            :                                 return TEST_FAILED;
     719                 :            : 
     720                 :          0 :                         k--;
     721                 :            :                 }
     722                 :          0 :                 frag_per_flow[i] = 1;
     723                 :            :         }
     724                 :            : 
     725         [ #  # ]:          0 :         for (i = 0; i < flow_cnt; i++) {
     726                 :            :                 struct rte_mbuf *buf_out = NULL;
     727                 :            :                 uint8_t reassembled = 0;
     728                 :            : 
     729                 :            :                 flow_tstamp = rte_rdtsc_precise();
     730         [ #  # ]:          0 :                 for (j = 0; j < frag_per_flow[i]; j++) {
     731                 :          0 :                         struct rte_mbuf *buf = mbufs[i][j];
     732                 :          0 :                         struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     733                 :            :                                 buf, struct rte_ipv6_hdr *, buf->l2_len);
     734                 :          0 :                         struct ipv6_extension_fragment *frag_hdr =
     735                 :          0 :                                 rte_pktmbuf_mtod_offset(
     736                 :            :                                         buf, struct ipv6_extension_fragment *,
     737                 :            :                                         buf->l2_len +
     738                 :            :                                                 sizeof(struct rte_ipv6_hdr));
     739                 :            : 
     740                 :            :                         tstamp = rte_rdtsc_precise();
     741                 :          0 :                         buf_out = rte_ipv6_frag_reassemble_packet(
     742                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
     743                 :            :                                 frag_hdr);
     744                 :            : 
     745         [ #  # ]:          0 :                         if (buf_out == NULL) {
     746                 :          0 :                                 total_empty_cyc += rte_rdtsc_precise() - tstamp;
     747                 :          0 :                                 frag_processed++;
     748                 :          0 :                                 continue;
     749                 :            :                         } else {
     750                 :            :                                 /*Packet out*/
     751                 :          0 :                                 total_reassembled_cyc +=
     752                 :          0 :                                         rte_rdtsc_precise() - tstamp;
     753                 :            :                                 reassembled = 1;
     754                 :            :                         }
     755                 :            :                 }
     756                 :          0 :                 total_cyc += rte_rdtsc_precise() - flow_tstamp;
     757         [ #  # ]:          0 :                 if (!reassembled)
     758                 :            :                         return TEST_FAILED;
     759                 :          0 :                 memset(mbufs[i], 0, sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
     760                 :          0 :                 mbufs[i][0] = buf_out;
     761                 :            :         }
     762                 :            : 
     763                 :          0 :         reassembly_print_stats(nb_frags, fill_order, outstanding,
     764                 :            :                                total_cyc / flow_cnt,
     765                 :            :                                total_empty_cyc / frag_processed,
     766                 :            :                                total_reassembled_cyc / flow_cnt);
     767                 :            : 
     768                 :          0 :         return TEST_SUCCESS;
     769                 :            : }
     770                 :            : 
     771                 :            : static int
     772                 :          0 : ipv6_reassembly_interleaved_flows_perf(int8_t nb_frags)
     773                 :            : {
     774                 :            :         struct rte_ip_frag_death_row death_row;
     775                 :            :         uint64_t total_reassembled_cyc = 0;
     776                 :            :         uint64_t total_empty_cyc = 0;
     777                 :            :         uint64_t tstamp, flow_tstamp;
     778                 :            :         uint64_t frag_processed = 0;
     779                 :            :         uint64_t total_cyc = 0;
     780                 :            :         uint32_t i, j;
     781                 :            : 
     782         [ #  # ]:          0 :         for (i = 0; i < flow_cnt; i += 4) {
     783                 :          0 :                 struct rte_mbuf *buf_out[4] = {NULL};
     784                 :            :                 uint8_t reassembled = 0;
     785                 :            :                 uint8_t nb_frags = 0;
     786                 :            :                 uint8_t prev = 0;
     787                 :            : 
     788         [ #  # ]:          0 :                 for (j = 0; j < 4; j++)
     789                 :          0 :                         nb_frags += frag_per_flow[i + j];
     790                 :            : 
     791                 :          0 :                 struct rte_mbuf *buf_arr[nb_frags];
     792         [ #  # ]:          0 :                 for (j = 0; j < 4; j++) {
     793                 :          0 :                         join_array(buf_arr, mbufs[i + j], prev,
     794                 :          0 :                                    frag_per_flow[i + j]);
     795                 :          0 :                         prev += frag_per_flow[i + j];
     796                 :            :                 }
     797                 :          0 :                 randomize_array_positions((void **)buf_arr, nb_frags);
     798                 :            :                 flow_tstamp = rte_rdtsc_precise();
     799         [ #  # ]:          0 :                 for (j = 0; j < nb_frags; j++) {
     800                 :          0 :                         struct rte_mbuf *buf = buf_arr[j];
     801                 :          0 :                         struct rte_ipv6_hdr *ip_hdr = rte_pktmbuf_mtod_offset(
     802                 :            :                                 buf, struct rte_ipv6_hdr *, buf->l2_len);
     803                 :          0 :                         struct ipv6_extension_fragment *frag_hdr =
     804                 :          0 :                                 rte_pktmbuf_mtod_offset(
     805                 :            :                                         buf, struct ipv6_extension_fragment *,
     806                 :            :                                         buf->l2_len +
     807                 :            :                                                 sizeof(struct rte_ipv6_hdr));
     808                 :            : 
     809                 :            :                         tstamp = rte_rdtsc_precise();
     810                 :          0 :                         buf_out[reassembled] = rte_ipv6_frag_reassemble_packet(
     811                 :            :                                 frag_tbl, &death_row, buf, flow_tstamp, ip_hdr,
     812                 :            :                                 frag_hdr);
     813                 :            : 
     814         [ #  # ]:          0 :                         if (buf_out[reassembled] == NULL) {
     815                 :          0 :                                 total_empty_cyc += rte_rdtsc_precise() - tstamp;
     816                 :          0 :                                 frag_processed++;
     817                 :          0 :                                 continue;
     818                 :            :                         } else {
     819                 :            :                                 /*Packet out*/
     820                 :          0 :                                 total_reassembled_cyc +=
     821                 :          0 :                                         rte_rdtsc_precise() - tstamp;
     822                 :          0 :                                 reassembled++;
     823                 :            :                         }
     824                 :            :                 }
     825                 :          0 :                 total_cyc += rte_rdtsc_precise() - flow_tstamp;
     826         [ #  # ]:          0 :                 if (reassembled != 4)
     827                 :          0 :                         return TEST_FAILED;
     828         [ #  # ]:          0 :                 for (j = 0; j < 4; j++) {
     829                 :          0 :                         memset(mbufs[i + j], 0,
     830                 :            :                                sizeof(struct rte_mbuf *) * MAX_FRAGMENTS);
     831                 :          0 :                         mbufs[i + j][0] = buf_out[j];
     832                 :            :                 }
     833                 :            :         }
     834                 :            : 
     835                 :          0 :         reassembly_print_stats(nb_frags, FILL_MODE_INTERLEAVED, 0,
     836                 :            :                                total_cyc / flow_cnt,
     837                 :            :                                total_empty_cyc / frag_processed,
     838                 :            :                                total_reassembled_cyc / flow_cnt);
     839                 :            : 
     840                 :          0 :         return TEST_SUCCESS;
     841                 :            : }
     842                 :            : 
     843                 :            : static int
     844                 :          0 : ipv4_reassembly_test(int8_t nb_frags, uint8_t fill_order, uint32_t outstanding)
     845                 :            : {
     846                 :            :         int rc;
     847                 :            : 
     848         [ #  # ]:          0 :         if (nb_frags > 0)
     849                 :          0 :                 rc = ipv4_frag_pkt_setup(fill_order, nb_frags);
     850                 :            :         else
     851                 :          0 :                 rc = ipv4_rand_frag_pkt_setup(fill_order, MAX_FRAGMENTS);
     852                 :            : 
     853         [ #  # ]:          0 :         if (rc)
     854                 :            :                 return rc;
     855                 :            : 
     856         [ #  # ]:          0 :         if (outstanding)
     857                 :          0 :                 rc = ipv4_outstanding_reassembly_perf(nb_frags, fill_order,
     858                 :            :                                                       outstanding);
     859         [ #  # ]:          0 :         else if (fill_order == FILL_MODE_INTERLEAVED)
     860                 :          0 :                 rc = ipv4_reassembly_interleaved_flows_perf(nb_frags);
     861                 :            :         else
     862                 :          0 :                 rc = ipv4_reassembly_perf(nb_frags, fill_order);
     863                 :            : 
     864                 :            :         frag_pkt_teardown();
     865                 :            : 
     866                 :            :         return rc;
     867                 :            : }
     868                 :            : 
     869                 :            : static int
     870                 :          0 : ipv6_reassembly_test(int8_t nb_frags, uint8_t fill_order, uint32_t outstanding)
     871                 :            : {
     872                 :            :         int rc;
     873                 :            : 
     874         [ #  # ]:          0 :         if (nb_frags > 0)
     875                 :          0 :                 rc = ipv6_frag_pkt_setup(fill_order, nb_frags);
     876                 :            :         else
     877                 :          0 :                 rc = ipv6_rand_frag_pkt_setup(fill_order, MAX_FRAGMENTS);
     878                 :            : 
     879         [ #  # ]:          0 :         if (rc)
     880                 :            :                 return rc;
     881                 :            : 
     882         [ #  # ]:          0 :         if (outstanding)
     883                 :          0 :                 rc = ipv6_outstanding_reassembly_perf(nb_frags, fill_order,
     884                 :            :                                                       outstanding);
     885         [ #  # ]:          0 :         else if (fill_order == FILL_MODE_INTERLEAVED)
     886                 :          0 :                 rc = ipv6_reassembly_interleaved_flows_perf(nb_frags);
     887                 :            :         else
     888                 :          0 :                 rc = ipv6_reassembly_perf(nb_frags, fill_order);
     889                 :            : 
     890                 :            :         frag_pkt_teardown();
     891                 :            : 
     892                 :            :         return rc;
     893                 :            : }
     894                 :            : 
     895                 :            : static int
     896                 :          0 : test_reassembly_perf(void)
     897                 :            : {
     898                 :          0 :         int8_t nb_fragments[] = {2, 3, MAX_FRAGMENTS, -1 /* Random */};
     899                 :          0 :         uint8_t order_type[] = {FILL_MODE_LINEAR, FILL_MODE_RANDOM};
     900                 :          0 :         uint32_t outstanding[] = {100, 500, 1000, 2000, 3000};
     901                 :            :         uint32_t i, j;
     902                 :            :         int rc;
     903                 :            : 
     904                 :          0 :         rc = reassembly_test_setup();
     905         [ #  # ]:          0 :         if (rc)
     906                 :            :                 return rc;
     907                 :            : 
     908                 :          0 :         reassembly_print_banner("IPV4");
     909                 :            :         /* Test variable fragment count and ordering. */
     910         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nb_fragments); i++) {
     911         [ #  # ]:          0 :                 for (j = 0; j < RTE_DIM(order_type); j++) {
     912                 :          0 :                         rc = ipv4_reassembly_test(nb_fragments[i],
     913                 :          0 :                                                   order_type[j], 0);
     914         [ #  # ]:          0 :                         if (rc)
     915                 :          0 :                                 return rc;
     916                 :            :                 }
     917                 :            :         }
     918                 :            : 
     919                 :            :         /* Test outstanding fragments in the table. */
     920         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(outstanding); i++) {
     921                 :          0 :                 rc = ipv4_reassembly_test(2, 0, outstanding[i]);
     922         [ #  # ]:          0 :                 if (rc)
     923                 :          0 :                         return rc;
     924                 :            :         }
     925         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(outstanding); i++) {
     926                 :          0 :                 rc = ipv4_reassembly_test(MAX_FRAGMENTS, 0, outstanding[i]);
     927         [ #  # ]:          0 :                 if (rc)
     928                 :          0 :                         return rc;
     929                 :            :         }
     930                 :            : 
     931                 :            :         /* Test interleaved flow reassembly perf */
     932         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nb_fragments); i++) {
     933                 :          0 :                 rc = ipv4_reassembly_test(nb_fragments[i],
     934                 :            :                                           FILL_MODE_INTERLEAVED, 0);
     935         [ #  # ]:          0 :                 if (rc)
     936                 :          0 :                         return rc;
     937                 :            :         }
     938                 :            :         printf("\n");
     939                 :          0 :         reassembly_print_banner("IPV6");
     940                 :            :         /* Test variable fragment count and ordering. */
     941         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nb_fragments); i++) {
     942         [ #  # ]:          0 :                 for (j = 0; j < RTE_DIM(order_type); j++) {
     943                 :          0 :                         rc = ipv6_reassembly_test(nb_fragments[i],
     944                 :          0 :                                                   order_type[j], 0);
     945         [ #  # ]:          0 :                         if (rc)
     946                 :          0 :                                 return rc;
     947                 :            :                 }
     948                 :            :         }
     949                 :            : 
     950                 :            :         /* Test outstanding fragments in the table. */
     951         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(outstanding); i++) {
     952                 :          0 :                 rc = ipv6_reassembly_test(2, 0, outstanding[i]);
     953         [ #  # ]:          0 :                 if (rc)
     954                 :          0 :                         return rc;
     955                 :            :         }
     956                 :            : 
     957         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(outstanding); i++) {
     958                 :          0 :                 rc = ipv6_reassembly_test(MAX_FRAGMENTS, 0, outstanding[i]);
     959         [ #  # ]:          0 :                 if (rc)
     960                 :          0 :                         return rc;
     961                 :            :         }
     962                 :            : 
     963                 :            :         /* Test interleaved flow reassembly perf */
     964         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(nb_fragments); i++) {
     965                 :          0 :                 rc = ipv6_reassembly_test(nb_fragments[i],
     966                 :            :                                           FILL_MODE_INTERLEAVED, 0);
     967         [ #  # ]:          0 :                 if (rc)
     968                 :          0 :                         return rc;
     969                 :            :         }
     970                 :          0 :         reassembly_test_teardown();
     971                 :            : 
     972                 :          0 :         return TEST_SUCCESS;
     973                 :            : }
     974                 :            : 
     975                 :        251 : REGISTER_PERF_TEST(reassembly_perf_autotest, test_reassembly_perf);

Generated by: LCOV version 1.14