LCOV - code coverage report
Current view: top level - app/test - test_link_bonding_rssconf.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 1 191 0.5 %
Date: 2025-01-02 22:41:34 Functions: 1 20 5.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 174 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2015 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <string.h>
       6                 :            : #include <stdarg.h>
       7                 :            : #include <stdio.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include <stdint.h>
      10                 :            : #include <inttypes.h>
      11                 :            : #include <errno.h>
      12                 :            : #include <rte_cycles.h>
      13                 :            : #include <sys/queue.h>
      14                 :            : 
      15                 :            : #include <rte_byteorder.h>
      16                 :            : #include <rte_common.h>
      17                 :            : #include <rte_debug.h>
      18                 :            : #include <rte_ethdev.h>
      19                 :            : #include <rte_log.h>
      20                 :            : #include <rte_lcore.h>
      21                 :            : #include <rte_memory.h>
      22                 :            : #include <rte_bus_vdev.h>
      23                 :            : 
      24                 :            : #include <rte_string_fns.h>
      25                 :            : #include <rte_errno.h>
      26                 :            : #include <rte_eth_bond.h>
      27                 :            : 
      28                 :            : #include "test.h"
      29                 :            : 
      30                 :            : #define MEMBER_COUNT (4)
      31                 :            : 
      32                 :            : #define RXTX_RING_SIZE                  1024
      33                 :            : #define RXTX_QUEUE_COUNT                4
      34                 :            : 
      35                 :            : #define BONDING_DEV_NAME         ("net_bonding_rss")
      36                 :            : 
      37                 :            : #define MEMBER_DEV_NAME_FMT      ("net_null%d")
      38                 :            : #define MEMBER_RXTX_QUEUE_FMT      ("rssconf_member%d_q%d")
      39                 :            : 
      40                 :            : #define NUM_MBUFS 8191
      41                 :            : #define MBUF_SIZE (1600 + RTE_PKTMBUF_HEADROOM)
      42                 :            : #define MBUF_CACHE_SIZE 250
      43                 :            : #define BURST_SIZE 32
      44                 :            : 
      45                 :            : #define INVALID_SOCKET_ID       (-1)
      46                 :            : #define INVALID_PORT_ID         (0xFF)
      47                 :            : #define INVALID_BONDING_MODE    (-1)
      48                 :            : 
      49                 :            : struct member_conf {
      50                 :            :         uint16_t port_id;
      51                 :            :         struct rte_eth_dev_info dev_info;
      52                 :            : 
      53                 :            :         struct rte_eth_rss_conf rss_conf;
      54                 :            :         uint8_t rss_key[40];
      55                 :            :         struct rte_eth_rss_reta_entry64 reta_conf[512 / RTE_ETH_RETA_GROUP_SIZE];
      56                 :            : 
      57                 :            :         uint8_t is_member;
      58                 :            :         struct rte_ring *rxtx_queue[RXTX_QUEUE_COUNT];
      59                 :            : };
      60                 :            : 
      61                 :            : struct link_bonding_rssconf_unittest_params {
      62                 :            :         uint8_t bond_port_id;
      63                 :            :         struct rte_eth_dev_info bond_dev_info;
      64                 :            :         struct rte_eth_rss_reta_entry64 bond_reta_conf[512 / RTE_ETH_RETA_GROUP_SIZE];
      65                 :            :         struct member_conf member_ports[MEMBER_COUNT];
      66                 :            : 
      67                 :            :         struct rte_mempool *mbuf_pool;
      68                 :            : };
      69                 :            : 
      70                 :            : static struct link_bonding_rssconf_unittest_params test_params  = {
      71                 :            :         .bond_port_id = INVALID_PORT_ID,
      72                 :            :         .member_ports = {
      73                 :            :                 [0 ... MEMBER_COUNT - 1] = { .port_id = INVALID_PORT_ID, .is_member = 0}
      74                 :            :         },
      75                 :            :         .mbuf_pool = NULL,
      76                 :            : };
      77                 :            : 
      78                 :            : /**
      79                 :            :  * Default port configuration with RSS turned off
      80                 :            :  */
      81                 :            : static struct rte_eth_conf default_pmd_conf = {
      82                 :            :         .rxmode = {
      83                 :            :                 .mq_mode = RTE_ETH_MQ_RX_NONE,
      84                 :            :         },
      85                 :            :         .txmode = {
      86                 :            :                 .mq_mode = RTE_ETH_MQ_TX_NONE,
      87                 :            :         },
      88                 :            :         .lpbk_mode = 0,
      89                 :            : };
      90                 :            : 
      91                 :            : static struct rte_eth_conf rss_pmd_conf = {
      92                 :            :         .rxmode = {
      93                 :            :                 .mq_mode = RTE_ETH_MQ_RX_RSS,
      94                 :            :         },
      95                 :            :         .txmode = {
      96                 :            :                 .mq_mode = RTE_ETH_MQ_TX_NONE,
      97                 :            :         },
      98                 :            :         .rx_adv_conf = {
      99                 :            :                 .rss_conf = {
     100                 :            :                         .rss_key = NULL,
     101                 :            :                         .rss_hf = RTE_ETH_RSS_IPV6,
     102                 :            :                 },
     103                 :            :         },
     104                 :            :         .lpbk_mode = 0,
     105                 :            : };
     106                 :            : 
     107                 :            : #define FOR_EACH(_i, _item, _array, _size) \
     108                 :            :         for (_i = 0, _item = &_array[0]; _i < _size && (_item = &_array[_i]); _i++)
     109                 :            : 
     110                 :            : /* Macro for iterating over every port that can be used as a member
     111                 :            :  * in this test.
     112                 :            :  * _i variable used as an index in test_params->member_ports
     113                 :            :  * _member pointer to &test_params->member_ports[_idx]
     114                 :            :  */
     115                 :            : #define FOR_EACH_PORT(_i, _port) \
     116                 :            :         FOR_EACH(_i, _port, test_params.member_ports, \
     117                 :            :                 RTE_DIM(test_params.member_ports))
     118                 :            : 
     119                 :            : static int
     120                 :          0 : configure_ethdev(uint16_t port_id, struct rte_eth_conf *eth_conf,
     121                 :            :                  uint8_t start)
     122                 :            : {
     123                 :            :         int rxq, txq;
     124                 :            : 
     125         [ #  # ]:          0 :         TEST_ASSERT(rte_eth_dev_configure(port_id, RXTX_QUEUE_COUNT,
     126                 :            :                         RXTX_QUEUE_COUNT, eth_conf) == 0, "Failed to configure device %u",
     127                 :            :                         port_id);
     128                 :            : 
     129                 :          0 :         int ret = rte_eth_dev_set_mtu(port_id, 1550);
     130         [ #  # ]:          0 :         RTE_TEST_ASSERT(ret == 0 || ret == -ENOTSUP,
     131                 :            :                         "rte_eth_dev_set_mtu for port %d failed", port_id);
     132                 :            : 
     133         [ #  # ]:          0 :         for (rxq = 0; rxq < RXTX_QUEUE_COUNT; rxq++) {
     134         [ #  # ]:          0 :                 TEST_ASSERT(rte_eth_rx_queue_setup(port_id, rxq, RXTX_RING_SIZE,
     135                 :            :                                 rte_eth_dev_socket_id(port_id), NULL,
     136                 :            :                                 test_params.mbuf_pool) == 0, "Failed to setup rx queue.");
     137                 :            :         }
     138                 :            : 
     139         [ #  # ]:          0 :         for (txq = 0; txq < RXTX_QUEUE_COUNT; txq++) {
     140         [ #  # ]:          0 :                 TEST_ASSERT(rte_eth_tx_queue_setup(port_id, txq, RXTX_RING_SIZE,
     141                 :            :                                 rte_eth_dev_socket_id(port_id), NULL) == 0,
     142                 :            :                                 "Failed to setup tx queue.");
     143                 :            :         }
     144                 :            : 
     145         [ #  # ]:          0 :         if (start) {
     146         [ #  # ]:          0 :                 TEST_ASSERT(rte_eth_dev_start(port_id) == 0,
     147                 :            :                 "Failed to start device (%d).", port_id);
     148                 :            :         }
     149                 :            : 
     150                 :            :         return 0;
     151                 :            : }
     152                 :            : 
     153                 :            : /**
     154                 :            :  * Remove all members from bonding
     155                 :            :  */
     156                 :            : static int
     157                 :          0 : remove_members(void)
     158                 :            : {
     159                 :            :         unsigned n;
     160                 :            :         struct member_conf *port;
     161                 :            : 
     162         [ #  # ]:          0 :         FOR_EACH_PORT(n, port) {
     163                 :            :                 port = &test_params.member_ports[n];
     164         [ #  # ]:          0 :                 if (port->is_member) {
     165         [ #  # ]:          0 :                         TEST_ASSERT_SUCCESS(rte_eth_bond_member_remove(
     166                 :            :                                         test_params.bond_port_id, port->port_id),
     167                 :            :                                         "Cannot remove member %d from bonding", port->port_id);
     168                 :          0 :                         port->is_member = 0;
     169                 :            :                 }
     170                 :            :         }
     171                 :            : 
     172                 :            :         return 0;
     173                 :            : }
     174                 :            : 
     175                 :            : static int
     176                 :          0 : remove_members_and_stop_bonding_device(void)
     177                 :            : {
     178         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(remove_members(), "Removing members");
     179         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_stop(test_params.bond_port_id),
     180                 :            :                         "Failed to stop port %u", test_params.bond_port_id);
     181                 :            :         return TEST_SUCCESS;
     182                 :            : }
     183                 :            : 
     184                 :            : /**
     185                 :            :  * Add all members to bonding
     186                 :            :  */
     187                 :            : static int
     188                 :          0 : bond_members(void)
     189                 :            : {
     190                 :            :         unsigned n;
     191                 :            :         struct member_conf *port;
     192                 :            : 
     193         [ #  # ]:          0 :         FOR_EACH_PORT(n, port) {
     194                 :            :                 port = &test_params.member_ports[n];
     195         [ #  # ]:          0 :                 if (!port->is_member) {
     196         [ #  # ]:          0 :                         TEST_ASSERT_SUCCESS(rte_eth_bond_member_add(test_params.bond_port_id,
     197                 :            :                                         port->port_id), "Cannot attach member %d to the bonding",
     198                 :            :                                         port->port_id);
     199                 :          0 :                         port->is_member = 1;
     200                 :            :                 }
     201                 :            :         }
     202                 :            : 
     203                 :            :         return 0;
     204                 :            : }
     205                 :            : 
     206                 :            : /**
     207                 :            :  * Set all RETA values in port_id to value
     208                 :            :  */
     209                 :            : static int
     210                 :          0 : reta_set(uint16_t port_id, uint8_t value, int reta_size)
     211                 :            : {
     212                 :            :         struct rte_eth_rss_reta_entry64 reta_conf[512/RTE_ETH_RETA_GROUP_SIZE];
     213                 :            :         int i, j;
     214                 :            : 
     215         [ #  # ]:          0 :         for (i = 0; i < reta_size / RTE_ETH_RETA_GROUP_SIZE; i++) {
     216                 :            :                 /* select all fields to set */
     217                 :          0 :                 reta_conf[i].mask = ~0LL;
     218         [ #  # ]:          0 :                 for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++)
     219                 :          0 :                         reta_conf[i].reta[j] = value;
     220                 :            :         }
     221                 :            : 
     222                 :          0 :         return rte_eth_dev_rss_reta_update(port_id, reta_conf, reta_size);
     223                 :            : }
     224                 :            : 
     225                 :            : /**
     226                 :            :  * Check if members RETA is synchronized with bonding port. Returns 1 if member
     227                 :            :  * port is synced with bonding port.
     228                 :            :  */
     229                 :            : static int
     230                 :            : reta_check_synced(struct member_conf *port)
     231                 :            : {
     232                 :            :         unsigned i;
     233                 :            : 
     234   [ #  #  #  #  :          0 :         for (i = 0; i < test_params.bond_dev_info.reta_size;
                   #  # ]
     235                 :          0 :                         i++) {
     236                 :            : 
     237                 :          0 :                 int index = i / RTE_ETH_RETA_GROUP_SIZE;
     238                 :          0 :                 int shift = i % RTE_ETH_RETA_GROUP_SIZE;
     239                 :            : 
     240                 :          0 :                 if (port->reta_conf[index].reta[shift] !=
     241   [ #  #  #  #  :          0 :                                 test_params.bond_reta_conf[index].reta[shift])
                   #  # ]
     242                 :            :                         return 0;
     243                 :            : 
     244                 :            :         }
     245                 :            : 
     246                 :            :         return 1;
     247                 :            : }
     248                 :            : 
     249                 :            : /**
     250                 :            :  * Fetch bonding ports RETA
     251                 :            :  */
     252                 :            : static int
     253                 :          0 : bond_reta_fetch(void) {
     254                 :            :         unsigned j;
     255                 :            : 
     256         [ #  # ]:          0 :         for (j = 0; j < test_params.bond_dev_info.reta_size / RTE_ETH_RETA_GROUP_SIZE;
     257                 :          0 :                         j++)
     258                 :          0 :                 test_params.bond_reta_conf[j].mask = ~0LL;
     259                 :            : 
     260         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_rss_reta_query(test_params.bond_port_id,
     261                 :            :                         test_params.bond_reta_conf, test_params.bond_dev_info.reta_size),
     262                 :            :                         "Cannot take bonding ports RSS configuration");
     263                 :            :         return 0;
     264                 :            : }
     265                 :            : 
     266                 :            : /**
     267                 :            :  * Fetch members RETA
     268                 :            :  */
     269                 :            : static int
     270                 :          0 : member_reta_fetch(struct member_conf *port) {
     271                 :            :         unsigned j;
     272                 :            : 
     273         [ #  # ]:          0 :         for (j = 0; j < port->dev_info.reta_size / RTE_ETH_RETA_GROUP_SIZE; j++)
     274                 :          0 :                 port->reta_conf[j].mask = ~0LL;
     275                 :            : 
     276         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_rss_reta_query(port->port_id,
     277                 :            :                         port->reta_conf, port->dev_info.reta_size),
     278                 :            :                         "Cannot take bonding ports RSS configuration");
     279                 :            :         return 0;
     280                 :            : }
     281                 :            : 
     282                 :            : /**
     283                 :            :  * Remove and add member to check if members configuration is synced with
     284                 :            :  * the bonding ports values after adding new member.
     285                 :            :  */
     286                 :            : static int
     287                 :          0 : member_remove_and_add(void)
     288                 :            : {
     289                 :            :         struct member_conf *port = &(test_params.member_ports[0]);
     290                 :            : 
     291                 :            :         /* 1. Remove first member from bonding */
     292         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_bond_member_remove(test_params.bond_port_id,
     293                 :            :                         port->port_id), "Cannot remove member #d from bonding");
     294                 :            : 
     295                 :            :         /* 2. Change removed (ex-)member and bonding configuration to different
     296                 :            :          *    values
     297                 :            :          */
     298                 :          0 :         reta_set(test_params.bond_port_id, 1, test_params.bond_dev_info.reta_size);
     299                 :          0 :         bond_reta_fetch();
     300                 :            : 
     301                 :          0 :         reta_set(port->port_id, 2, port->dev_info.reta_size);
     302                 :          0 :         member_reta_fetch(port);
     303                 :            : 
     304         [ #  # ]:          0 :         TEST_ASSERT(reta_check_synced(port) == 0,
     305                 :            :                         "Removed member didn't should be synchronized with bonding port");
     306                 :            : 
     307                 :            :         /* 3. Add (ex-)member and check if configuration changed*/
     308         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_bond_member_add(test_params.bond_port_id,
     309                 :            :                         port->port_id), "Cannot add member");
     310                 :            : 
     311                 :          0 :         bond_reta_fetch();
     312                 :          0 :         member_reta_fetch(port);
     313                 :            : 
     314                 :            :         return reta_check_synced(port);
     315                 :            : }
     316                 :            : 
     317                 :            : /**
     318                 :            :  * Test configuration propagation over members.
     319                 :            :  */
     320                 :            : static int
     321                 :          0 : test_propagate(void)
     322                 :            : {
     323                 :            :         unsigned i;
     324                 :            :         uint8_t n;
     325                 :            :         struct member_conf *port;
     326                 :            :         uint8_t bond_rss_key[40];
     327                 :          0 :         struct rte_eth_rss_conf bond_rss_conf = {0};
     328                 :            : 
     329                 :            :         int retval = 0;
     330                 :            :         uint64_t rss_hf = 0;
     331                 :            :         uint64_t default_rss_hf = 0;
     332                 :            : 
     333                 :          0 :         retval = rte_eth_dev_info_get(test_params.bond_port_id,
     334                 :            :                                                 &test_params.bond_dev_info);
     335         [ #  # ]:          0 :         TEST_ASSERT((retval == 0),
     336                 :            :                         "Error during getting device (port %u) info: %s\n",
     337                 :            :                         test_params.bond_port_id, strerror(-retval));
     338                 :            : 
     339                 :            :         /*
     340                 :            :          *  Test hash function propagation
     341                 :            :          */
     342         [ #  # ]:          0 :         for (i = 0; i < sizeof(test_params.bond_dev_info.flow_type_rss_offloads)*8;
     343                 :          0 :                         i++) {
     344                 :            : 
     345                 :          0 :                 rss_hf = test_params.bond_dev_info.flow_type_rss_offloads & (1<<i);
     346         [ #  # ]:          0 :                 if (rss_hf) {
     347                 :          0 :                         bond_rss_conf.rss_key = NULL;
     348                 :          0 :                         bond_rss_conf.rss_hf = rss_hf;
     349                 :            : 
     350                 :          0 :                         retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id,
     351                 :            :                                         &bond_rss_conf);
     352         [ #  # ]:          0 :                         TEST_ASSERT_SUCCESS(retval, "Cannot set members hash function");
     353                 :            : 
     354         [ #  # ]:          0 :                         FOR_EACH_PORT(n, port) {
     355                 :            :                                 port = &test_params.member_ports[n];
     356                 :            : 
     357                 :          0 :                                 retval = rte_eth_dev_rss_hash_conf_get(port->port_id,
     358                 :            :                                                 &port->rss_conf);
     359         [ #  # ]:          0 :                                 TEST_ASSERT_SUCCESS(retval,
     360                 :            :                                                 "Cannot take members RSS configuration");
     361                 :            : 
     362         [ #  # ]:          0 :                                 TEST_ASSERT(port->rss_conf.rss_hf == rss_hf,
     363                 :            :                                                 "Hash function not propagated for member %d",
     364                 :            :                                                 port->port_id);
     365                 :            :                         }
     366                 :            : 
     367                 :            :                         default_rss_hf = rss_hf;
     368                 :            :                 }
     369                 :            : 
     370                 :            :         }
     371                 :            : 
     372                 :            :         /*
     373                 :            :          *  Test key propagation
     374                 :            :          */
     375         [ #  # ]:          0 :         for (i = 1; i < 10; i++) {
     376                 :            : 
     377                 :            :                 /* Set all keys to zero */
     378         [ #  # ]:          0 :                 FOR_EACH_PORT(n, port) {
     379                 :            :                         port = &test_params.member_ports[n];
     380                 :          0 :                         memset(port->rss_conf.rss_key, 0, 40);
     381                 :          0 :                         retval = rte_eth_dev_rss_hash_update(port->port_id,
     382                 :            :                                         &port->rss_conf);
     383         [ #  # ]:          0 :                         TEST_ASSERT_SUCCESS(retval, "Cannot set members RSS keys");
     384                 :            :                 }
     385                 :            : 
     386                 :          0 :                 memset(bond_rss_key, i, sizeof(bond_rss_key));
     387                 :          0 :                 bond_rss_conf.rss_hf = default_rss_hf,
     388                 :          0 :                 bond_rss_conf.rss_key = bond_rss_key;
     389                 :          0 :                 bond_rss_conf.rss_key_len = 40;
     390                 :            : 
     391                 :          0 :                 retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id,
     392                 :            :                                 &bond_rss_conf);
     393         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Cannot set bonding port RSS keys");
     394                 :            : 
     395         [ #  # ]:          0 :                 FOR_EACH_PORT(n, port) {
     396                 :            :                         port = &test_params.member_ports[n];
     397                 :            : 
     398                 :          0 :                         retval = rte_eth_dev_rss_hash_conf_get(port->port_id,
     399                 :            :                                         &(port->rss_conf));
     400                 :            : 
     401         [ #  # ]:          0 :                         TEST_ASSERT_SUCCESS(retval,
     402                 :            :                                         "Cannot take members RSS configuration");
     403                 :            : 
     404                 :            :                         /* compare keys */
     405                 :          0 :                         retval = memcmp(port->rss_conf.rss_key, bond_rss_key,
     406                 :            :                                         sizeof(bond_rss_key));
     407         [ #  # ]:          0 :                         TEST_ASSERT(retval == 0, "Key value not propagated for member %d",
     408                 :            :                                         port->port_id);
     409                 :            :                 }
     410                 :            :         }
     411                 :            : 
     412                 :            :         /*
     413                 :            :          *  Test RETA propagation
     414                 :            :          */
     415         [ #  # ]:          0 :         for (i = 0; i < RXTX_QUEUE_COUNT; i++) {
     416                 :            : 
     417                 :            :                 /* Set all keys to zero */
     418         [ #  # ]:          0 :                 FOR_EACH_PORT(n, port) {
     419                 :            :                         port = &test_params.member_ports[n];
     420                 :          0 :                         retval = reta_set(port->port_id, (i + 1) % RXTX_QUEUE_COUNT,
     421                 :          0 :                                         port->dev_info.reta_size);
     422         [ #  # ]:          0 :                         TEST_ASSERT_SUCCESS(retval, "Cannot set members RETA");
     423                 :            :                 }
     424                 :            : 
     425         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(reta_set(test_params.bond_port_id,
     426                 :            :                                 i % RXTX_QUEUE_COUNT, test_params.bond_dev_info.reta_size),
     427                 :            :                                 "Cannot set bonding port RETA");
     428                 :            : 
     429                 :          0 :                 bond_reta_fetch();
     430                 :            : 
     431         [ #  # ]:          0 :                 FOR_EACH_PORT(n, port) {
     432                 :            :                         port = &test_params.member_ports[n];
     433                 :            : 
     434                 :          0 :                         member_reta_fetch(port);
     435         [ #  # ]:          0 :                         TEST_ASSERT(reta_check_synced(port) == 1, "RETAs inconsistent");
     436                 :            :                 }
     437                 :            :         }
     438                 :            : 
     439                 :            :         return TEST_SUCCESS;
     440                 :            : }
     441                 :            : 
     442                 :            : /**
     443                 :            :  * Test propagation logic, when RX_RSS mq_mode is turned on for bonding port
     444                 :            :  */
     445                 :            : static int
     446                 :          0 : test_rss(void)
     447                 :            : {
     448                 :            :         /**
     449                 :            :          * Configure bonding port in RSS mq mode
     450                 :            :          */
     451                 :            :         int ret;
     452                 :            : 
     453         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id,
     454                 :            :                         &rss_pmd_conf, 0), "Failed to configure bonding device\n");
     455                 :            : 
     456                 :          0 :         ret = rte_eth_dev_info_get(test_params.bond_port_id,
     457                 :            :                                         &test_params.bond_dev_info);
     458         [ #  # ]:          0 :         TEST_ASSERT((ret == 0),
     459                 :            :                         "Error during getting device (port %u) info: %s\n",
     460                 :            :                         test_params.bond_port_id, strerror(-ret));
     461                 :            : 
     462         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(bond_members(), "Bonding members failed");
     463                 :            : 
     464         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id),
     465                 :            :                         "Failed to start bonding port (%d).", test_params.bond_port_id);
     466                 :            : 
     467         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(test_propagate(), "Propagation test failed");
     468                 :            : 
     469         [ #  # ]:          0 :         TEST_ASSERT(member_remove_and_add() == 1, "remove and add members success.");
     470                 :            : 
     471                 :          0 :         remove_members_and_stop_bonding_device();
     472                 :            : 
     473                 :          0 :         return TEST_SUCCESS;
     474                 :            : }
     475                 :            : 
     476                 :            : 
     477                 :            : /**
     478                 :            :  * Test RSS configuration over bonding and members.
     479                 :            :  */
     480                 :            : static int
     481                 :          0 : test_rss_config_lazy(void)
     482                 :            : {
     483                 :          0 :         struct rte_eth_rss_conf bond_rss_conf = {0};
     484                 :            :         struct member_conf *port;
     485                 :            :         uint8_t rss_key[40];
     486                 :            :         uint64_t rss_hf;
     487                 :            :         int retval;
     488                 :            :         uint16_t i;
     489                 :            :         uint8_t n;
     490                 :            : 
     491                 :          0 :         retval = rte_eth_dev_info_get(test_params.bond_port_id,
     492                 :            :                                       &test_params.bond_dev_info);
     493         [ #  # ]:          0 :         TEST_ASSERT((retval == 0), "Error during getting device (port %u) info: %s\n",
     494                 :            :                     test_params.bond_port_id, strerror(-retval));
     495                 :            : 
     496                 :          0 :         rss_hf = test_params.bond_dev_info.flow_type_rss_offloads;
     497         [ #  # ]:          0 :         if (rss_hf != 0) {
     498                 :          0 :                 bond_rss_conf.rss_key = NULL;
     499                 :          0 :                 bond_rss_conf.rss_hf = rss_hf;
     500                 :          0 :                 retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id,
     501                 :            :                                                      &bond_rss_conf);
     502         [ #  # ]:          0 :                 TEST_ASSERT(retval != 0, "Succeeded in setting bonding port hash function");
     503                 :            :         }
     504                 :            : 
     505                 :            :         /* Set all keys to zero for all members */
     506         [ #  # ]:          0 :         FOR_EACH_PORT(n, port) {
     507                 :            :                 port = &test_params.member_ports[n];
     508                 :          0 :                 retval = rte_eth_dev_rss_hash_conf_get(port->port_id,
     509                 :            :                                                        &port->rss_conf);
     510         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Cannot get members RSS configuration");
     511                 :          0 :                 memset(port->rss_key, 0, sizeof(port->rss_key));
     512                 :          0 :                 port->rss_conf.rss_key = port->rss_key;
     513                 :          0 :                 port->rss_conf.rss_key_len = sizeof(port->rss_key);
     514                 :          0 :                 retval = rte_eth_dev_rss_hash_update(port->port_id,
     515                 :            :                                                      &port->rss_conf);
     516         [ #  # ]:          0 :                 TEST_ASSERT(retval != 0, "Succeeded in setting members RSS keys");
     517                 :            :         }
     518                 :            : 
     519                 :            :         /* Set RSS keys for bonding port */
     520                 :            :         memset(rss_key, 1, sizeof(rss_key));
     521                 :          0 :         bond_rss_conf.rss_hf = rss_hf;
     522                 :          0 :         bond_rss_conf.rss_key = rss_key;
     523                 :          0 :         bond_rss_conf.rss_key_len = sizeof(rss_key);
     524                 :            : 
     525                 :          0 :         retval = rte_eth_dev_rss_hash_update(test_params.bond_port_id,
     526                 :            :                                              &bond_rss_conf);
     527         [ #  # ]:          0 :         TEST_ASSERT(retval != 0, "Succeeded in setting bonding port RSS keys");
     528                 :            : 
     529                 :            :         /*  Test RETA propagation */
     530         [ #  # ]:          0 :         for (i = 0; i < RXTX_QUEUE_COUNT; i++) {
     531         [ #  # ]:          0 :                 FOR_EACH_PORT(n, port) {
     532                 :            :                         port = &test_params.member_ports[n];
     533                 :          0 :                         retval = reta_set(port->port_id, (i + 1) % RXTX_QUEUE_COUNT,
     534                 :          0 :                                           port->dev_info.reta_size);
     535         [ #  # ]:          0 :                         TEST_ASSERT(retval != 0, "Succeeded in setting members RETA");
     536                 :            :                 }
     537                 :            : 
     538                 :          0 :                 retval = reta_set(test_params.bond_port_id, i % RXTX_QUEUE_COUNT,
     539                 :          0 :                                   test_params.bond_dev_info.reta_size);
     540         [ #  # ]:          0 :                 TEST_ASSERT(retval != 0, "Succeeded in setting bonding port RETA");
     541                 :            :         }
     542                 :            : 
     543                 :            :         return TEST_SUCCESS;
     544                 :            : }
     545                 :            : 
     546                 :            : /**
     547                 :            :  * Test RSS function logic, when RX_RSS mq_mode is turned off for bonding port
     548                 :            :  */
     549                 :            : static int
     550                 :          0 : test_rss_lazy(void)
     551                 :            : {
     552                 :            :         int ret;
     553                 :            : 
     554         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id,
     555                 :            :                         &default_pmd_conf, 0), "Failed to configure bonding device\n");
     556                 :            : 
     557                 :          0 :         ret = rte_eth_dev_info_get(test_params.bond_port_id,
     558                 :            :                                                 &test_params.bond_dev_info);
     559         [ #  # ]:          0 :         TEST_ASSERT((ret == 0),
     560                 :            :                         "Error during getting device (port %u) info: %s\n",
     561                 :            :                         test_params.bond_port_id, strerror(-ret));
     562                 :            : 
     563         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(bond_members(), "Bonding members failed");
     564                 :            : 
     565         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(rte_eth_dev_start(test_params.bond_port_id),
     566                 :            :                         "Failed to start bonding port (%d).", test_params.bond_port_id);
     567                 :            : 
     568         [ #  # ]:          0 :         TEST_ASSERT_SUCCESS(test_rss_config_lazy(), "Succeeded in setting RSS hash when RX_RSS mq_mode is turned off");
     569                 :            : 
     570                 :          0 :         remove_members_and_stop_bonding_device();
     571                 :            : 
     572                 :          0 :         return TEST_SUCCESS;
     573                 :            : }
     574                 :            : 
     575                 :            : static int
     576                 :          0 : test_setup(void)
     577                 :            : {
     578                 :            :         unsigned n;
     579                 :            :         int retval;
     580                 :            :         int port_id;
     581                 :            :         char name[256];
     582                 :            :         struct member_conf *port;
     583                 :          0 :         struct rte_ether_addr mac_addr = { .addr_bytes = {0} };
     584                 :            : 
     585         [ #  # ]:          0 :         if (test_params.mbuf_pool == NULL) {
     586                 :            : 
     587                 :          0 :                 test_params.mbuf_pool = rte_pktmbuf_pool_create(
     588                 :            :                         "RSS_MBUF_POOL", NUM_MBUFS * MEMBER_COUNT,
     589                 :          0 :                         MBUF_CACHE_SIZE, 0, MBUF_SIZE, rte_socket_id());
     590                 :            : 
     591         [ #  # ]:          0 :                 TEST_ASSERT(test_params.mbuf_pool != NULL,
     592                 :            :                                 "rte_pktmbuf_pool_create failed\n");
     593                 :            :         }
     594                 :            : 
     595                 :            :         /* Create / initialize ring eth devs. */
     596         [ #  # ]:          0 :         FOR_EACH_PORT(n, port) {
     597                 :            :                 port = &test_params.member_ports[n];
     598                 :            : 
     599                 :          0 :                 port_id = rte_eth_dev_count_avail();
     600                 :            :                 snprintf(name, sizeof(name), MEMBER_DEV_NAME_FMT, port_id);
     601                 :            : 
     602                 :          0 :                 retval = rte_vdev_init(name, "size=64,copy=0");
     603         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to create null device '%s'\n",
     604                 :            :                                 name);
     605                 :            : 
     606                 :          0 :                 port->port_id = port_id;
     607                 :            : 
     608                 :          0 :                 port->rss_conf.rss_key = port->rss_key;
     609                 :          0 :                 port->rss_conf.rss_key_len = 40;
     610                 :            : 
     611                 :          0 :                 retval = configure_ethdev(port->port_id, &default_pmd_conf, 0);
     612         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(retval, "Failed to configure virtual ethdev %s\n",
     613                 :            :                                 name);
     614                 :            : 
     615                 :            :                 /* assign a non-zero MAC */
     616                 :          0 :                 mac_addr.addr_bytes[5] = 0x10 + port->port_id;
     617                 :          0 :                 rte_eth_dev_default_mac_addr_set(port->port_id, &mac_addr);
     618                 :            : 
     619                 :          0 :                 retval = rte_eth_dev_info_get(port->port_id, &port->dev_info);
     620         [ #  # ]:          0 :                 TEST_ASSERT((retval == 0),
     621                 :            :                                 "Error during getting device (port %u) info: %s\n",
     622                 :            :                                 test_params.bond_port_id, strerror(-retval));
     623                 :            :         }
     624                 :            : 
     625         [ #  # ]:          0 :         if (test_params.bond_port_id == INVALID_PORT_ID) {
     626                 :          0 :                 retval = rte_eth_bond_create(BONDING_DEV_NAME, 0, rte_socket_id());
     627                 :            : 
     628         [ #  # ]:          0 :                 TEST_ASSERT(retval >= 0, "Failed to create bonding ethdev %s",
     629                 :            :                                 BONDING_DEV_NAME);
     630                 :            : 
     631                 :          0 :                 test_params.bond_port_id = retval;
     632                 :            : 
     633         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(configure_ethdev(test_params.bond_port_id,
     634                 :            :                                 &default_pmd_conf, 0), "Failed to configure bonding device\n");
     635                 :            : 
     636                 :          0 :                 retval = rte_eth_dev_info_get(test_params.bond_port_id,
     637                 :            :                                                 &test_params.bond_dev_info);
     638         [ #  # ]:          0 :                 TEST_ASSERT((retval == 0),
     639                 :            :                                 "Error during getting device (port %u) info: %s\n",
     640                 :            :                                 test_params.bond_port_id, strerror(-retval));
     641                 :            :         }
     642                 :            : 
     643                 :            :         return TEST_SUCCESS;
     644                 :            : }
     645                 :            : 
     646                 :            : static void
     647                 :          0 : testsuite_teardown(void)
     648                 :            : {
     649                 :            :         struct member_conf *port;
     650                 :            :         uint8_t i;
     651                 :            : 
     652                 :            :         /* Only stop ports.
     653                 :            :          * Any cleanup/reset state is done when particular test is
     654                 :            :          * started. */
     655                 :            : 
     656                 :          0 :         rte_eth_dev_stop(test_params.bond_port_id);
     657                 :            : 
     658         [ #  # ]:          0 :         FOR_EACH_PORT(i, port)
     659                 :          0 :                 rte_eth_dev_stop(port->port_id);
     660                 :          0 : }
     661                 :            : 
     662                 :            : static int
     663                 :            : check_environment(void)
     664                 :            : {
     665                 :            :         return TEST_SUCCESS;
     666                 :            : }
     667                 :            : 
     668                 :            : static int
     669                 :          0 : test_rssconf_executor(int (*test_func)(void))
     670                 :            : {
     671                 :            :         int test_result;
     672                 :            : 
     673                 :            :         /* Check if environment is clean. Fail to launch a test if there was
     674                 :            :          * a critical error before that prevented to reset environment. */
     675                 :            :         TEST_ASSERT_SUCCESS(check_environment(),
     676                 :            :                 "Refusing to launch test in dirty environment.");
     677                 :            : 
     678         [ #  # ]:          0 :         RTE_VERIFY(test_func != NULL);
     679                 :          0 :         test_result = (*test_func)();
     680                 :            : 
     681                 :            :         /* If test succeed check if environment wast left in good condition. */
     682         [ #  # ]:          0 :         if (test_result == TEST_SUCCESS)
     683                 :            :                 test_result = check_environment();
     684                 :            : 
     685                 :            :         /* Reset environment in case test failed to do that. */
     686                 :            :         if (test_result != TEST_SUCCESS) {
     687         [ #  # ]:          0 :                 TEST_ASSERT_SUCCESS(remove_members_and_stop_bonding_device(),
     688                 :            :                         "Failed to stop bonding device");
     689                 :            :         }
     690                 :            : 
     691                 :            :         return test_result;
     692                 :            : }
     693                 :            : 
     694                 :            : static int
     695                 :          0 : test_setup_wrapper(void)
     696                 :            : {
     697                 :          0 :         return test_rssconf_executor(&test_setup);
     698                 :            : }
     699                 :            : 
     700                 :            : static int
     701                 :          0 : test_rss_wrapper(void)
     702                 :            : {
     703                 :          0 :         return test_rssconf_executor(&test_rss);
     704                 :            : }
     705                 :            : 
     706                 :            : static int
     707                 :          0 : test_rss_lazy_wrapper(void)
     708                 :            : {
     709                 :          0 :         return test_rssconf_executor(&test_rss_lazy);
     710                 :            : }
     711                 :            : 
     712                 :            : static struct unit_test_suite link_bonding_rssconf_test_suite  = {
     713                 :            :         .suite_name = "RSS Dynamic Configuration for Bonding Unit Test Suite",
     714                 :            :         .teardown = testsuite_teardown,
     715                 :            :         .unit_test_cases = {
     716                 :            :                 TEST_CASE_NAMED("test_setup", test_setup_wrapper),
     717                 :            :                 TEST_CASE_NAMED("test_rss", test_rss_wrapper),
     718                 :            :                 TEST_CASE_NAMED("test_rss_lazy", test_rss_lazy_wrapper),
     719                 :            : 
     720                 :            :                 TEST_CASES_END()
     721                 :            :         }
     722                 :            : };
     723                 :            : 
     724                 :            : static int
     725                 :          0 : test_link_bonding_rssconf(void)
     726                 :            : {
     727                 :          0 :         return unit_test_suite_runner(&link_bonding_rssconf_test_suite);
     728                 :            : }
     729                 :            : 
     730                 :        251 : REGISTER_DRIVER_TEST(link_bonding_rssconf_autotest, test_link_bonding_rssconf);

Generated by: LCOV version 1.14