LCOV - code coverage report
Current view: top level - lib/ethdev - ethdev_private.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 140 197 71.1 %
Date: 2024-12-01 18:57:19 Functions: 14 18 77.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 86 150 57.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2018 Gaƫtan Rivet
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_debug.h>
       6                 :            : 
       7                 :            : #include "rte_ethdev.h"
       8                 :            : #include "rte_ethdev_trace_fp.h"
       9                 :            : #include "ethdev_driver.h"
      10                 :            : #include "ethdev_private.h"
      11                 :            : 
      12                 :            : static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
      13                 :            : 
      14                 :            : static const struct rte_memzone *eth_dev_shared_mz;
      15                 :            : struct eth_dev_shared *eth_dev_shared_data;
      16                 :            : 
      17                 :            : /* spinlock for eth device callbacks */
      18                 :            : rte_spinlock_t eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
      19                 :            : 
      20                 :            : uint16_t
      21                 :          0 : eth_dev_to_id(const struct rte_eth_dev *dev)
      22                 :            : {
      23         [ #  # ]:          0 :         if (dev == NULL)
      24                 :            :                 return RTE_MAX_ETHPORTS;
      25                 :          0 :         return dev - rte_eth_devices;
      26                 :            : }
      27                 :            : 
      28                 :            : struct rte_eth_dev *
      29                 :          0 : eth_find_device(const struct rte_eth_dev *start, rte_eth_cmp_t cmp,
      30                 :            :                 const void *data)
      31                 :            : {
      32                 :            :         struct rte_eth_dev *edev;
      33                 :            :         ptrdiff_t idx;
      34                 :            : 
      35                 :            :         /* Avoid Undefined Behaviour */
      36   [ #  #  #  # ]:          0 :         if (start != NULL &&
      37         [ #  # ]:          0 :             (start < &rte_eth_devices[0] ||
      38                 :            :              start > &rte_eth_devices[RTE_MAX_ETHPORTS]))
      39                 :            :                 return NULL;
      40         [ #  # ]:          0 :         if (start != NULL)
      41                 :          0 :                 idx = eth_dev_to_id(start) + 1;
      42                 :            :         else
      43                 :            :                 idx = 0;
      44         [ #  # ]:          0 :         for (; idx < RTE_MAX_ETHPORTS; idx++) {
      45                 :          0 :                 edev = &rte_eth_devices[idx];
      46         [ #  # ]:          0 :                 if (cmp(edev, data) == 0)
      47                 :          0 :                         return edev;
      48                 :            :         }
      49                 :            :         return NULL;
      50                 :            : }
      51                 :            : 
      52                 :            : /* Put new value into list. */
      53                 :            : static int
      54                 :            : rte_eth_devargs_enlist(uint16_t *list, uint16_t *len_list,
      55                 :            :                        const uint16_t max_list, uint16_t val)
      56                 :            : {
      57                 :            :         uint16_t i;
      58                 :            : 
      59   [ +  +  +  + ]:        200 :         for (i = 0; i < *len_list; i++) {
      60   [ +  -  +  - ]:         66 :                 if (list[i] == val)
      61                 :            :                         return 0;
      62                 :            :         }
      63   [ +  -  +  - ]:        134 :         if (*len_list >= max_list)
      64                 :            :                 return -1;
      65                 :        134 :         list[(*len_list)++] = val;
      66                 :            :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :            : /* Parse and enlist a range expression of "min-max" or a single value. */
      70                 :            : static char *
      71                 :        106 : rte_eth_devargs_process_range(char *str, uint16_t *list, uint16_t *len_list,
      72                 :            :         const uint16_t max_list)
      73                 :            : {
      74                 :            :         uint16_t lo, hi, val;
      75                 :        106 :         int result, n = 0;
      76                 :            :         char *pos = str;
      77                 :            : 
      78                 :        106 :         result = sscanf(str, "%hu%n-%hu%n", &lo, &n, &hi, &n);
      79         [ +  + ]:        106 :         if (result == 1) {
      80                 :         78 :                 if (rte_eth_devargs_enlist(list, len_list, max_list, lo) != 0)
      81                 :            :                         return NULL;
      82         [ +  + ]:         28 :         } else if (result == 2) {
      83         [ +  - ]:         26 :                 if (lo > hi)
      84                 :            :                         return NULL;
      85         [ +  + ]:         82 :                 for (val = lo; val <= hi; val++) {
      86                 :            :                         if (rte_eth_devargs_enlist(list, len_list, max_list,
      87                 :            :                                                    val) != 0)
      88                 :            :                                 return NULL;
      89                 :            :                 }
      90                 :            :         } else
      91                 :            :                 return NULL;
      92                 :        104 :         return pos + n;
      93                 :            : }
      94                 :            : 
      95                 :            : /*
      96                 :            :  * Parse list of values separated by ",".
      97                 :            :  * Each value could be a range [min-max] or single number.
      98                 :            :  * Examples:
      99                 :            :  *  2               - single
     100                 :            :  *  [1,2,3]         - single list
     101                 :            :  *  [1,3-5,7,9-11]  - list with singles and ranges
     102                 :            :  */
     103                 :            : static char *
     104                 :         90 : rte_eth_devargs_process_list(char *str, uint16_t *list, uint16_t *len_list,
     105                 :            :         const uint16_t max_list)
     106                 :            : {
     107                 :            :         char *pos = str;
     108                 :            : 
     109         [ +  + ]:         90 :         if (*pos == '[')
     110                 :         46 :                 pos++;
     111                 :            :         while (1) {
     112                 :        106 :                 pos = rte_eth_devargs_process_range(pos, list, len_list,
     113                 :            :                                                     max_list);
     114         [ +  + ]:        106 :                 if (pos == NULL)
     115                 :            :                         return NULL;
     116         [ +  + ]:        104 :                 if (*pos != ',') /* end of list */
     117                 :            :                         break;
     118                 :         16 :                 pos++;
     119                 :            :         }
     120   [ +  +  +  + ]:         88 :         if (*str == '[' && *pos != ']')
     121                 :            :                 return NULL;
     122         [ +  + ]:         87 :         if (*pos == ']')
     123                 :         44 :                 pos++;
     124                 :            :         return pos;
     125                 :            : }
     126                 :            : 
     127                 :            : /*
     128                 :            :  * Parse representor ports from a single value or lists.
     129                 :            :  *
     130                 :            :  * Representor format:
     131                 :            :  *   #: range or single number of VF representor - legacy
     132                 :            :  *   [[c#]pf#]vf#: VF port representor/s
     133                 :            :  *   [[c#]pf#]sf#: SF port representor/s
     134                 :            :  *   [c#]pf#:      PF port representor/s
     135                 :            :  *
     136                 :            :  * Examples of #:
     137                 :            :  *  2               - single
     138                 :            :  *  [1,2,3]         - single list
     139                 :            :  *  [1,3-5,7,9-11]  - list with singles and ranges
     140                 :            :  */
     141                 :            : int
     142                 :         73 : rte_eth_devargs_parse_representor_ports(char *str, void *data)
     143                 :            : {
     144                 :            :         struct rte_eth_devargs *eth_da = data;
     145                 :            : 
     146         [ +  + ]:         73 :         if (str[0] == 'c') {
     147                 :          9 :                 str += 1;
     148                 :          9 :                 str = rte_eth_devargs_process_list(str, eth_da->mh_controllers,
     149                 :            :                                 &eth_da->nb_mh_controllers,
     150                 :            :                                 RTE_DIM(eth_da->mh_controllers));
     151         [ -  + ]:          9 :                 if (str == NULL)
     152                 :          0 :                         goto done;
     153                 :            :         }
     154   [ +  +  +  - ]:         73 :         if (str[0] == 'p' && str[1] == 'f') {
     155                 :         26 :                 eth_da->type = RTE_ETH_REPRESENTOR_PF;
     156                 :         26 :                 str += 2;
     157                 :         26 :                 str = rte_eth_devargs_process_list(str, eth_da->ports,
     158                 :            :                                 &eth_da->nb_ports, RTE_DIM(eth_da->ports));
     159   [ +  +  +  + ]:         26 :                 if (str == NULL || str[0] == '\0')
     160                 :         12 :                         goto done;
     161         [ +  + ]:         47 :         } else if (eth_da->nb_mh_controllers > 0) {
     162                 :            :                 /* 'c' must followed by 'pf'. */
     163                 :            :                 str = NULL;
     164                 :          5 :                 goto done;
     165                 :            :         }
     166   [ +  +  +  - ]:         56 :         if (str[0] == 'v' && str[1] == 'f') {
     167                 :         38 :                 eth_da->type = RTE_ETH_REPRESENTOR_VF;
     168                 :         38 :                 str += 2;
     169   [ +  +  +  - ]:         18 :         } else if (str[0] == 's' && str[1] == 'f') {
     170                 :          3 :                 eth_da->type = RTE_ETH_REPRESENTOR_SF;
     171                 :          3 :                 str += 2;
     172                 :            :         } else {
     173                 :            :                 /* 'pf' must followed by 'vf' or 'sf'. */
     174         [ +  + ]:         15 :                 if (eth_da->type == RTE_ETH_REPRESENTOR_PF) {
     175                 :            :                         str = NULL;
     176                 :          1 :                         goto done;
     177                 :            :                 }
     178                 :         14 :                 eth_da->type = RTE_ETH_REPRESENTOR_VF;
     179                 :            :         }
     180                 :         55 :         str = rte_eth_devargs_process_list(str, eth_da->representor_ports,
     181                 :            :                 &eth_da->nb_representor_ports,
     182                 :            :                 RTE_DIM(eth_da->representor_ports));
     183                 :         67 : done:
     184         [ +  + ]:         67 :         if (str == NULL)
     185                 :          9 :                 RTE_ETHDEV_LOG_LINE(ERR, "wrong representor format: %s", str);
     186         [ +  + ]:         73 :         return str == NULL ? -1 : 0;
     187                 :            : }
     188                 :            : 
     189                 :            : struct dummy_queue {
     190                 :            :         bool rx_warn_once;
     191                 :            :         bool tx_warn_once;
     192                 :            : };
     193                 :            : static struct dummy_queue *dummy_queues_array[RTE_MAX_ETHPORTS][RTE_MAX_QUEUES_PER_PORT];
     194                 :            : static struct dummy_queue per_port_queues[RTE_MAX_ETHPORTS];
     195                 :        251 : RTE_INIT(dummy_queue_init)
     196                 :            : {
     197                 :            :         uint16_t port_id;
     198                 :            : 
     199         [ +  + ]:       8283 :         for (port_id = 0; port_id < RTE_DIM(per_port_queues); port_id++) {
     200                 :            :                 unsigned int q;
     201                 :            : 
     202         [ +  + ]:    8232800 :                 for (q = 0; q < RTE_DIM(dummy_queues_array[port_id]); q++)
     203                 :    8224768 :                         dummy_queues_array[port_id][q] = &per_port_queues[port_id];
     204                 :            :         }
     205                 :        251 : }
     206                 :            : 
     207                 :            : static uint16_t
     208                 :          0 : dummy_eth_rx_burst(void *rxq,
     209                 :            :                 __rte_unused struct rte_mbuf **rx_pkts,
     210                 :            :                 __rte_unused uint16_t nb_pkts)
     211                 :            : {
     212                 :            :         struct dummy_queue *queue = rxq;
     213                 :            :         uintptr_t port_id;
     214                 :            : 
     215                 :          0 :         port_id = queue - per_port_queues;
     216   [ #  #  #  # ]:          0 :         if (port_id < RTE_DIM(per_port_queues) && !queue->rx_warn_once) {
     217                 :          0 :                 RTE_ETHDEV_LOG_LINE(ERR, "lcore %u called rx_pkt_burst for not ready port %"PRIuPTR,
     218                 :            :                         rte_lcore_id(), port_id);
     219                 :          0 :                 rte_dump_stack();
     220                 :          0 :                 queue->rx_warn_once = true;
     221                 :            :         }
     222                 :          0 :         rte_errno = ENOTSUP;
     223                 :          0 :         return 0;
     224                 :            : }
     225                 :            : 
     226                 :            : static uint16_t
     227                 :          0 : dummy_eth_tx_burst(void *txq,
     228                 :            :                 __rte_unused struct rte_mbuf **tx_pkts,
     229                 :            :                 __rte_unused uint16_t nb_pkts)
     230                 :            : {
     231                 :            :         struct dummy_queue *queue = txq;
     232                 :            :         uintptr_t port_id;
     233                 :            : 
     234                 :          0 :         port_id = queue - per_port_queues;
     235   [ #  #  #  # ]:          0 :         if (port_id < RTE_DIM(per_port_queues) && !queue->tx_warn_once) {
     236                 :          0 :                 RTE_ETHDEV_LOG_LINE(ERR, "lcore %u called tx_pkt_burst for not ready port %"PRIuPTR,
     237                 :            :                         rte_lcore_id(), port_id);
     238                 :          0 :                 rte_dump_stack();
     239                 :          0 :                 queue->tx_warn_once = true;
     240                 :            :         }
     241                 :          0 :         rte_errno = ENOTSUP;
     242                 :          0 :         return 0;
     243                 :            : }
     244                 :            : 
     245                 :            : void
     246                 :       8060 : eth_dev_fp_ops_reset(struct rte_eth_fp_ops *fpo)
     247                 :            : {
     248                 :            :         static RTE_ATOMIC(void *) dummy_data[RTE_MAX_QUEUES_PER_PORT];
     249                 :       8060 :         uintptr_t port_id = fpo - rte_eth_fp_ops;
     250                 :            : 
     251                 :       8060 :         per_port_queues[port_id].rx_warn_once = false;
     252                 :       8060 :         per_port_queues[port_id].tx_warn_once = false;
     253                 :       8060 :         *fpo = (struct rte_eth_fp_ops) {
     254                 :            :                 .rx_pkt_burst = dummy_eth_rx_burst,
     255                 :            :                 .tx_pkt_burst = dummy_eth_tx_burst,
     256                 :            :                 .rxq = {
     257                 :       8060 :                         .data = (void **)&dummy_queues_array[port_id],
     258                 :            :                         .clbk = dummy_data,
     259                 :            :                 },
     260                 :            :                 .txq = {
     261                 :            :                         .data = (void **)&dummy_queues_array[port_id],
     262                 :            :                         .clbk = dummy_data,
     263                 :            :                 },
     264                 :            :         };
     265                 :       8060 : }
     266                 :            : 
     267                 :            : void
     268                 :         10 : eth_dev_fp_ops_setup(struct rte_eth_fp_ops *fpo,
     269                 :            :                 const struct rte_eth_dev *dev)
     270                 :            : {
     271                 :         10 :         fpo->rx_pkt_burst = dev->rx_pkt_burst;
     272                 :         10 :         fpo->tx_pkt_burst = dev->tx_pkt_burst;
     273                 :         10 :         fpo->tx_pkt_prepare = dev->tx_pkt_prepare;
     274                 :         10 :         fpo->rx_queue_count = dev->rx_queue_count;
     275                 :         10 :         fpo->rx_descriptor_status = dev->rx_descriptor_status;
     276                 :         10 :         fpo->tx_queue_count = dev->tx_queue_count;
     277                 :         10 :         fpo->tx_descriptor_status = dev->tx_descriptor_status;
     278                 :         10 :         fpo->recycle_tx_mbufs_reuse = dev->recycle_tx_mbufs_reuse;
     279                 :         10 :         fpo->recycle_rx_descriptors_refill = dev->recycle_rx_descriptors_refill;
     280                 :            : 
     281                 :         10 :         fpo->rxq.data = dev->data->rx_queues;
     282                 :         10 :         fpo->rxq.clbk = (void * __rte_atomic *)(uintptr_t)dev->post_rx_burst_cbs;
     283                 :            : 
     284                 :         10 :         fpo->txq.data = dev->data->tx_queues;
     285                 :         10 :         fpo->txq.clbk = (void * __rte_atomic *)(uintptr_t)dev->pre_tx_burst_cbs;
     286                 :         10 : }
     287                 :            : 
     288                 :            : uint16_t
     289                 :          1 : rte_eth_call_rx_callbacks(uint16_t port_id, uint16_t queue_id,
     290                 :            :         struct rte_mbuf **rx_pkts, uint16_t nb_rx, uint16_t nb_pkts,
     291                 :            :         void *opaque)
     292                 :            : {
     293                 :            :         const struct rte_eth_rxtx_callback *cb = opaque;
     294                 :            : 
     295         [ +  + ]:          2 :         while (cb != NULL) {
     296                 :          1 :                 nb_rx = cb->fn.rx(port_id, queue_id, rx_pkts, nb_rx,
     297                 :          1 :                                 nb_pkts, cb->param);
     298                 :          1 :                 cb = cb->next;
     299                 :            :         }
     300                 :            : 
     301                 :            :         if (unlikely(nb_rx))
     302                 :            :                 rte_eth_trace_call_rx_callbacks_nonempty(port_id, queue_id, (void **)rx_pkts,
     303                 :            :                                                 nb_rx, nb_pkts);
     304                 :            :         else
     305                 :            :                 rte_eth_trace_call_rx_callbacks_empty(port_id, queue_id, (void **)rx_pkts,
     306                 :            :                                                 nb_pkts);
     307                 :            : 
     308                 :          1 :         return nb_rx;
     309                 :            : }
     310                 :            : 
     311                 :            : uint16_t
     312                 :          1 : rte_eth_call_tx_callbacks(uint16_t port_id, uint16_t queue_id,
     313                 :            :         struct rte_mbuf **tx_pkts, uint16_t nb_pkts, void *opaque)
     314                 :            : {
     315                 :            :         const struct rte_eth_rxtx_callback *cb = opaque;
     316                 :            : 
     317         [ +  + ]:          2 :         while (cb != NULL) {
     318                 :          1 :                 nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts, nb_pkts,
     319                 :          1 :                                 cb->param);
     320                 :          1 :                 cb = cb->next;
     321                 :            :         }
     322                 :            : 
     323                 :            :         rte_eth_trace_call_tx_callbacks(port_id, queue_id, (void **)tx_pkts,
     324                 :            :                                         nb_pkts);
     325                 :            : 
     326                 :          1 :         return nb_pkts;
     327                 :            : }
     328                 :            : 
     329                 :            : void *
     330                 :         56 : eth_dev_shared_data_prepare(void)
     331                 :            : {
     332                 :            :         const struct rte_memzone *mz;
     333                 :            : 
     334         [ +  - ]:         56 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
     335                 :            :                 const unsigned int flags = 0;
     336                 :            : 
     337         [ +  + ]:         56 :                 if (eth_dev_shared_mz != NULL)
     338                 :         45 :                         goto out;
     339                 :            : 
     340                 :            :                 /* Allocate port data and ownership shared memory. */
     341                 :         11 :                 mz = rte_memzone_reserve(MZ_RTE_ETH_DEV_DATA,
     342                 :            :                                 sizeof(*eth_dev_shared_data),
     343                 :         11 :                                 rte_socket_id(), flags);
     344         [ -  + ]:         11 :                 if (mz == NULL) {
     345                 :          0 :                         RTE_ETHDEV_LOG_LINE(ERR, "Cannot allocate ethdev shared data");
     346                 :          0 :                         goto out;
     347                 :            :                 }
     348                 :            : 
     349                 :         11 :                 eth_dev_shared_mz = mz;
     350                 :         11 :                 eth_dev_shared_data = mz->addr;
     351                 :         11 :                 eth_dev_shared_data->allocated_owners = 0;
     352                 :         11 :                 eth_dev_shared_data->next_owner_id =
     353                 :            :                         RTE_ETH_DEV_NO_OWNER + 1;
     354                 :         11 :                 eth_dev_shared_data->allocated_ports = 0;
     355                 :         11 :                 memset(eth_dev_shared_data->data, 0,
     356                 :            :                        sizeof(eth_dev_shared_data->data));
     357                 :            :         } else {
     358                 :          0 :                 mz = rte_memzone_lookup(MZ_RTE_ETH_DEV_DATA);
     359         [ #  # ]:          0 :                 if (mz == NULL) {
     360                 :            :                         /* Clean remaining any traces of a previous shared mem */
     361                 :          0 :                         eth_dev_shared_mz = NULL;
     362                 :          0 :                         eth_dev_shared_data = NULL;
     363                 :          0 :                         RTE_ETHDEV_LOG_LINE(ERR, "Cannot lookup ethdev shared data");
     364                 :          0 :                         goto out;
     365                 :            :                 }
     366   [ #  #  #  # ]:          0 :                 if (mz == eth_dev_shared_mz && mz->addr == eth_dev_shared_data)
     367                 :          0 :                         goto out;
     368                 :            : 
     369                 :            :                 /* Shared mem changed in primary process, refresh pointers */
     370                 :          0 :                 eth_dev_shared_mz = mz;
     371                 :          0 :                 eth_dev_shared_data = mz->addr;
     372                 :            :         }
     373                 :         56 : out:
     374                 :         56 :         return eth_dev_shared_data;
     375                 :            : }
     376                 :            : 
     377                 :            : void
     378                 :         18 : eth_dev_shared_data_release(void)
     379                 :            : {
     380                 :            :         RTE_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
     381                 :            : 
     382         [ +  + ]:         18 :         if (eth_dev_shared_data->allocated_ports != 0)
     383                 :            :                 return;
     384         [ +  - ]:         10 :         if (eth_dev_shared_data->allocated_owners != 0)
     385                 :            :                 return;
     386                 :            : 
     387                 :         10 :         rte_memzone_free(eth_dev_shared_mz);
     388                 :         10 :         eth_dev_shared_mz = NULL;
     389                 :         10 :         eth_dev_shared_data = NULL;
     390                 :            : }
     391                 :            : 
     392                 :            : void
     393                 :         45 : eth_dev_rxq_release(struct rte_eth_dev *dev, uint16_t qid)
     394                 :            : {
     395                 :         45 :         void **rxq = dev->data->rx_queues;
     396                 :            : 
     397         [ +  - ]:         45 :         if (rxq[qid] == NULL)
     398                 :            :                 return;
     399                 :            : 
     400         [ -  + ]:         45 :         if (dev->dev_ops->rx_queue_release != NULL)
     401                 :          0 :                 (*dev->dev_ops->rx_queue_release)(dev, qid);
     402                 :         45 :         rxq[qid] = NULL;
     403                 :            : }
     404                 :            : 
     405                 :            : void
     406                 :         45 : eth_dev_txq_release(struct rte_eth_dev *dev, uint16_t qid)
     407                 :            : {
     408                 :         45 :         void **txq = dev->data->tx_queues;
     409                 :            : 
     410         [ +  - ]:         45 :         if (txq[qid] == NULL)
     411                 :            :                 return;
     412                 :            : 
     413         [ -  + ]:         45 :         if (dev->dev_ops->tx_queue_release != NULL)
     414                 :          0 :                 (*dev->dev_ops->tx_queue_release)(dev, qid);
     415                 :         45 :         txq[qid] = NULL;
     416                 :            : }
     417                 :            : 
     418                 :            : int
     419                 :         15 : eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
     420                 :            : {
     421                 :         15 :         uint16_t old_nb_queues = dev->data->nb_rx_queues;
     422                 :            :         unsigned int i;
     423                 :            : 
     424   [ +  +  +  - ]:         15 :         if (dev->data->rx_queues == NULL && nb_queues != 0) { /* first time configuration */
     425                 :          2 :                 dev->data->rx_queues = rte_zmalloc("ethdev->rx_queues",
     426                 :            :                                 sizeof(dev->data->rx_queues[0]) *
     427                 :            :                                 RTE_MAX_QUEUES_PER_PORT,
     428                 :            :                                 RTE_CACHE_LINE_SIZE);
     429         [ -  + ]:          2 :                 if (dev->data->rx_queues == NULL) {
     430                 :          0 :                         dev->data->nb_rx_queues = 0;
     431                 :          0 :                         return -(ENOMEM);
     432                 :            :                 }
     433   [ +  -  +  - ]:         13 :         } else if (dev->data->rx_queues != NULL && nb_queues != 0) { /* re-configure */
     434         [ +  + ]:         18 :                 for (i = nb_queues; i < old_nb_queues; i++)
     435                 :          5 :                         eth_dev_rxq_release(dev, i);
     436                 :            : 
     437   [ #  #  #  # ]:          0 :         } else if (dev->data->rx_queues != NULL && nb_queues == 0) {
     438         [ #  # ]:          0 :                 for (i = nb_queues; i < old_nb_queues; i++)
     439                 :          0 :                         eth_dev_rxq_release(dev, i);
     440                 :            : 
     441                 :          0 :                 rte_free(dev->data->rx_queues);
     442                 :          0 :                 dev->data->rx_queues = NULL;
     443                 :            :         }
     444                 :         15 :         dev->data->nb_rx_queues = nb_queues;
     445                 :         15 :         return 0;
     446                 :            : }
     447                 :            : 
     448                 :            : int
     449                 :         15 : eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
     450                 :            : {
     451                 :         15 :         uint16_t old_nb_queues = dev->data->nb_tx_queues;
     452                 :            :         unsigned int i;
     453                 :            : 
     454   [ +  +  +  - ]:         15 :         if (dev->data->tx_queues == NULL && nb_queues != 0) { /* first time configuration */
     455                 :          2 :                 dev->data->tx_queues = rte_zmalloc("ethdev->tx_queues",
     456                 :            :                                 sizeof(dev->data->tx_queues[0]) *
     457                 :            :                                 RTE_MAX_QUEUES_PER_PORT,
     458                 :            :                                 RTE_CACHE_LINE_SIZE);
     459         [ -  + ]:          2 :                 if (dev->data->tx_queues == NULL) {
     460                 :          0 :                         dev->data->nb_tx_queues = 0;
     461                 :          0 :                         return -(ENOMEM);
     462                 :            :                 }
     463   [ +  -  +  - ]:         13 :         } else if (dev->data->tx_queues != NULL && nb_queues != 0) { /* re-configure */
     464         [ +  + ]:         18 :                 for (i = nb_queues; i < old_nb_queues; i++)
     465                 :          5 :                         eth_dev_txq_release(dev, i);
     466                 :            : 
     467   [ #  #  #  # ]:          0 :         } else if (dev->data->tx_queues != NULL && nb_queues == 0) {
     468         [ #  # ]:          0 :                 for (i = nb_queues; i < old_nb_queues; i++)
     469                 :          0 :                         eth_dev_txq_release(dev, i);
     470                 :            : 
     471                 :          0 :                 rte_free(dev->data->tx_queues);
     472                 :          0 :                 dev->data->tx_queues = NULL;
     473                 :            :         }
     474                 :         15 :         dev->data->nb_tx_queues = nb_queues;
     475                 :         15 :         return 0;
     476                 :            : }

Generated by: LCOV version 1.14