LCOV - code coverage report
Current view: top level - plugins/unittest - ip_psh_cksum_test.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 6 103 5.8 %
Date: 2023-07-05 22:20:52 Functions: 7 12 58.3 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: Apache-2.0
       3             :  * Copyright(c) 2021 Cisco Systems, Inc.
       4             :  */
       5             : 
       6             : #include <vlib/vlib.h>
       7             : #include <vppinfra/time.h>
       8             : #include <vppinfra/cache.h>
       9             : #include <vppinfra/error.h>
      10             : #include <vnet/ethernet/ethernet.h>
      11             : #include <vnet/ip/ip.h>
      12             : #include <vnet/ip/ip_psh_cksum.h>
      13             : 
      14             : static_always_inline void
      15           0 : compute_ip_phc (void *p)
      16             : {
      17           0 :   if ((((u8 *) p)[0] & 0xf0) == 0x40)
      18           0 :     ip4_pseudo_header_cksum (p);
      19           0 :   else if ((((u8 *) p)[0] & 0xf0) == 0x60)
      20           0 :     ip6_pseudo_header_cksum (p);
      21           0 : }
      22             : 
      23             : void
      24           0 : compute_ip_phc_func (void **p, u32 n_packets)
      25             : {
      26           0 :   u32 n_left_from = n_packets;
      27             : 
      28           0 :   while (n_left_from >= 8)
      29             :     {
      30           0 :       clib_prefetch_load (p[4]);
      31           0 :       clib_prefetch_load (p[5]);
      32           0 :       clib_prefetch_load (p[6]);
      33           0 :       clib_prefetch_load (p[7]);
      34             : 
      35           0 :       compute_ip_phc (p[0]);
      36           0 :       compute_ip_phc (p[1]);
      37           0 :       compute_ip_phc (p[2]);
      38           0 :       compute_ip_phc (p[3]);
      39             : 
      40           0 :       n_left_from -= 4;
      41           0 :       p += 4;
      42             :     }
      43             : 
      44           0 :   while (n_left_from > 0)
      45             :     {
      46           0 :       compute_ip_phc (p[0]);
      47             : 
      48           0 :       n_left_from -= 1;
      49           0 :       p += 1;
      50             :     }
      51           0 : }
      52             : 
      53             : typedef struct _phc_test_data
      54             : {
      55             :   const char *name;
      56             :   const char *description;
      57             :   u8 *data;
      58             :   u32 data_size;
      59             :   struct _phc_test_data *next;
      60             : } phc_test_data_t;
      61             : 
      62             : typedef struct
      63             : {
      64             :   int verbose;
      65             : 
      66             :   char *phc_name;
      67             :   u32 warmup_rounds;
      68             :   u32 rounds;
      69             :   u32 n_buffers;
      70             :   u32 buffer_size;
      71             :   phc_test_data_t *phc_test_data;
      72             : } phc_test_main_t;
      73             : 
      74             : phc_test_main_t phc_test_main;
      75             : 
      76             : #define PHC_TEST_REGISTER_DATA(x, ...)                                        \
      77             :   __VA_ARGS__ phc_test_data_t __phc_test_data_##x;                            \
      78             :   static void __clib_constructor __phc_test_data_fn_##x (void)                \
      79             :   {                                                                           \
      80             :     phc_test_main_t *ptm = &phc_test_main;                                    \
      81             :     __phc_test_data_##x.next = ptm->phc_test_data;                            \
      82             :     ptm->phc_test_data = &__phc_test_data_##x;                                \
      83             :   }                                                                           \
      84             :   __VA_ARGS__ phc_test_data_t __phc_test_data_##x
      85             : 
      86             : // ipv4
      87             : u8 phc_ipv4_tcp_data[50] = {
      88             :   0x45, 0x00, 0x05, 0xdc, 0xdb, 0x42, 0x40, 0x00, 0x40, 0x06, 0xc4, 0x85, 0xc0,
      89             :   0xa8, 0x0a, 0x02, 0xc0, 0xa8, 0x0a, 0x01, 0xd8, 0xde, 0x14, 0x51, 0x34, 0x93,
      90             :   0xa8, 0x1b, 0x7b, 0xef, 0x2e, 0x7e, 0x80, 0x10, 0x00, 0xe5, 0xc7, 0x03, 0x00,
      91             :   0x00, 0x01, 0x01, 0x08, 0x0a, 0xce, 0xaa, 0x00, 0x2f, 0xf2, 0xc3
      92             : };
      93             : 
      94         559 : PHC_TEST_REGISTER_DATA (ipv4_tcp, static) = {
      95             :   .name = "ipv4-tcp",
      96             :   .description = "IPv4 TCP",
      97             :   .data = phc_ipv4_tcp_data,
      98             :   .data_size = sizeof (phc_ipv4_tcp_data),
      99             : };
     100             : 
     101             : // ip6
     102             : u8 phc_ipv6_udp_data[65] = {
     103             :   0x60, 0x0d, 0xf4, 0x97, 0x00, 0x40, 0x3a, 0x40, 0xfd, 0x01, 0x00, 0x00, 0x00,
     104             :   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfd, 0x01,
     105             :   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
     106             :   0x01, 0x80, 0x00, 0x10, 0x84, 0xb1, 0x25, 0x00, 0x01, 0x22, 0x57, 0xf0, 0x60,
     107             :   0x00, 0x00, 0x00, 0x00, 0xcb, 0x4a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
     108             : };
     109             : 
     110         559 : PHC_TEST_REGISTER_DATA (ipv6_udp, static) = {
     111             :   .name = "ipv6-udp",
     112             :   .description = "IPv6 UDP",
     113             :   .data = phc_ipv6_udp_data,
     114             :   .data_size = sizeof (phc_ipv6_udp_data),
     115             : };
     116             : 
     117             : static void
     118           0 : fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size,
     119             :               u32 n_buffers, u32 buffer_size)
     120             : {
     121             :   int i, j;
     122           0 :   u64 seed = clib_cpu_time_now ();
     123           0 :   for (i = 0; i < n_buffers; i++)
     124             :     {
     125           0 :       vlib_buffer_t *b = vlib_get_buffer (vm, buffer_indices[i]);
     126           0 :       clib_memcpy_fast (b->data, data, data_size);
     127           0 :       b->current_data = 0;
     128           0 :       for (j = data_size; j < buffer_size; j += 8)
     129           0 :         *(u64 *) (b->data + j) = 1 + random_u64 (&seed);
     130           0 :       b->current_length = buffer_size;
     131             :     }
     132           0 : }
     133             : 
     134             : static clib_error_t *
     135           0 : test_phc_perf (vlib_main_t *vm, phc_test_main_t *ptm)
     136             : {
     137           0 :   clib_error_t *err = 0;
     138           0 :   u32 buffer_size = vlib_buffer_get_default_data_size (vm);
     139           0 :   u32 n_buffers, n_alloc = 0, warmup_rounds, rounds;
     140           0 :   u32 *buffer_indices = 0;
     141             :   u64 t0[5], t1[5];
     142           0 :   phc_test_data_t *phc_test_data = ptm->phc_test_data;
     143           0 :   void **p = 0;
     144             :   int i, j;
     145             : 
     146           0 :   if (ptm->buffer_size > buffer_size)
     147           0 :     return clib_error_return (0, "buffer size must be <= %u", buffer_size);
     148             : 
     149           0 :   rounds = ptm->rounds ? ptm->rounds : 100;
     150           0 :   n_buffers = ptm->n_buffers ? ptm->n_buffers : 256;
     151           0 :   warmup_rounds = ptm->warmup_rounds ? ptm->warmup_rounds : 100;
     152           0 :   buffer_size = ptm->buffer_size ? ptm->buffer_size : buffer_size;
     153             : 
     154           0 :   vec_validate_aligned (p, n_buffers - 1, CLIB_CACHE_LINE_BYTES);
     155           0 :   vec_validate_aligned (buffer_indices, n_buffers - 1, CLIB_CACHE_LINE_BYTES);
     156           0 :   n_alloc = vlib_buffer_alloc (vm, buffer_indices, n_buffers);
     157           0 :   if (n_alloc != n_buffers)
     158             :     {
     159           0 :       err = clib_error_return (0, "buffer alloc failure");
     160           0 :       goto done;
     161             :     }
     162             : 
     163           0 :   vlib_cli_output (
     164             :     vm,
     165             :     "pseudo header checksum: buffer-size %u, n_buffers %u rounds %u "
     166             :     "warmup-rounds %u",
     167             :     buffer_size, n_buffers, rounds, warmup_rounds);
     168           0 :   vlib_cli_output (vm, "   cpu-freq %.2f GHz",
     169           0 :                    (f64) vm->clib_time.clocks_per_second * 1e-9);
     170             : 
     171           0 :   while (phc_test_data)
     172             :     {
     173           0 :       fill_buffers (vm, buffer_indices, phc_test_data->data,
     174             :                     phc_test_data->data_size, n_buffers, buffer_size);
     175             : 
     176           0 :       for (i = 0; i < n_buffers; i++)
     177             :         {
     178           0 :           vlib_buffer_t *b = vlib_get_buffer (vm, buffer_indices[i]);
     179           0 :           p[i] = vlib_buffer_get_current (b);
     180             :         }
     181             : 
     182           0 :       for (i = 0; i < 5; i++)
     183             :         {
     184           0 :           for (j = 0; j < warmup_rounds; j++)
     185             :             {
     186           0 :               compute_ip_phc_func (p, n_buffers);
     187             :             }
     188             : 
     189           0 :           t0[i] = clib_cpu_time_now ();
     190           0 :           for (j = 0; j < rounds; j++)
     191           0 :             compute_ip_phc_func (p, n_buffers);
     192           0 :           t1[i] = clib_cpu_time_now ();
     193             :         }
     194             : 
     195           0 :       vlib_cli_output (
     196             :         vm, "===========================================================");
     197           0 :       vlib_cli_output (vm, " Test: %s", phc_test_data->description);
     198           0 :       vlib_cli_output (
     199             :         vm, "===========================================================");
     200           0 :       for (i = 0; i < 5; i++)
     201             :         {
     202           0 :           f64 tpp1 = (f64) (t1[i] - t0[i]) / (n_buffers * rounds);
     203           0 :           f64 Mpps1 = vm->clib_time.clocks_per_second * 1e-6 / tpp1;
     204             : 
     205           0 :           vlib_cli_output (vm, "%-2u: %.03f ticks/packet, %.02f Mpps\n", i + 1,
     206             :                            tpp1, Mpps1);
     207             :         }
     208           0 :       phc_test_data = phc_test_data->next;
     209             :     }
     210             : 
     211           0 : done:
     212           0 :   if (n_alloc)
     213           0 :     vlib_buffer_free (vm, buffer_indices, n_alloc);
     214             : 
     215           0 :   vec_free (p);
     216           0 :   vec_free (buffer_indices);
     217           0 :   return err;
     218             : }
     219             : 
     220             : static clib_error_t *
     221           0 : test_phc_command_fn (vlib_main_t *vm, unformat_input_t *input,
     222             :                      vlib_cli_command_t *cmd)
     223             : {
     224           0 :   phc_test_main_t *ptm = &phc_test_main;
     225           0 :   clib_error_t *err = 0;
     226             : 
     227           0 :   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     228             :     {
     229           0 :       if (unformat (input, "verbose"))
     230           0 :         ptm->verbose = 1;
     231           0 :       else if (unformat (input, "detail"))
     232           0 :         ptm->verbose = 2;
     233           0 :       else if (unformat (input, "buffers %u", &ptm->n_buffers))
     234             :         ;
     235           0 :       else if (unformat (input, "buffer-size %u", &ptm->buffer_size))
     236             :         ;
     237           0 :       else if (unformat (input, "rounds %u", &ptm->rounds))
     238             :         ;
     239           0 :       else if (unformat (input, "warmup-rounds %u", &ptm->warmup_rounds))
     240             :         ;
     241             :       else
     242             :         {
     243           0 :           return clib_error_return (0, "unknown input '%U'",
     244             :                                     format_unformat_error, input);
     245             :         }
     246             :     }
     247             : 
     248           0 :   test_phc_perf (vm, ptm);
     249             : 
     250           0 :   return err;
     251             : }
     252             : 
     253       16239 : VLIB_CLI_COMMAND (test_phc_command, static) = {
     254             :   .path = "test phc",
     255             :   .short_help = "test phc [buffers <n>] [buffer-size <size>] [rounds <n>] "
     256             :                 "[warmup-rounds <n>]",
     257             :   .function = test_phc_command_fn,
     258             : };
     259             : 
     260             : static clib_error_t *
     261         559 : phc_test_init (vlib_main_t *vm)
     262             : {
     263         559 :   return (0);
     264             : }
     265             : 
     266        3919 : VLIB_INIT_FUNCTION (phc_test_init);

Generated by: LCOV version 1.14