LCOV - code coverage report
Current view: top level - lib/ethdev - ethdev_private.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 150 213 70.4 %
Date: 2025-12-01 19:08:10 Functions: 15 19 78.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 97 170 57.1 %

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

Generated by: LCOV version 1.14