LCOV - code coverage report
Current view: top level - lib/port - rte_port_ring.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 78 241 32.4 %
Date: 2024-01-22 15:35:40 Functions: 11 33 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 36 158 22.8 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2010-2014 Intel Corporation
       3                 :            :  */
       4                 :            : #include <string.h>
       5                 :            : #include <stdint.h>
       6                 :            : 
       7                 :            : #include <rte_mbuf.h>
       8                 :            : #include <rte_ring.h>
       9                 :            : #include <rte_malloc.h>
      10                 :            : 
      11                 :            : #include "rte_port_ring.h"
      12                 :            : 
      13                 :            : #include "port_log.h"
      14                 :            : 
      15                 :            : /*
      16                 :            :  * Port RING Reader
      17                 :            :  */
      18                 :            : #ifdef RTE_PORT_STATS_COLLECT
      19                 :            : 
      20                 :            : #define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val) \
      21                 :            :         port->stats.n_pkts_in += val
      22                 :            : #define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val) \
      23                 :            :         port->stats.n_pkts_drop += val
      24                 :            : 
      25                 :            : #else
      26                 :            : 
      27                 :            : #define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val)
      28                 :            : #define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val)
      29                 :            : 
      30                 :            : #endif
      31                 :            : 
      32                 :            : struct rte_port_ring_reader {
      33                 :            :         struct rte_port_in_stats stats;
      34                 :            : 
      35                 :            :         struct rte_ring *ring;
      36                 :            : };
      37                 :            : 
      38                 :            : static void *
      39                 :         49 : rte_port_ring_reader_create_internal(void *params, int socket_id,
      40                 :            :         uint32_t is_multi)
      41                 :            : {
      42                 :            :         struct rte_port_ring_reader_params *conf =
      43                 :            :                         params;
      44                 :            :         struct rte_port_ring_reader *port;
      45                 :            : 
      46                 :            :         /* Check input parameters */
      47         [ +  + ]:         49 :         if ((conf == NULL) ||
      48   [ +  -  +  - ]:         48 :                 (conf->ring == NULL) ||
      49   [ +  -  -  + ]:         48 :                 (rte_ring_is_cons_single(conf->ring) && is_multi) ||
      50         [ #  # ]:          0 :                 (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
      51                 :          1 :                 PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
      52                 :          1 :                 return NULL;
      53                 :            :         }
      54                 :            : 
      55                 :            :         /* Memory allocation */
      56                 :         48 :         port = rte_zmalloc_socket("PORT", sizeof(*port),
      57                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
      58         [ -  + ]:         48 :         if (port == NULL) {
      59                 :          0 :                 PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
      60                 :          0 :                 return NULL;
      61                 :            :         }
      62                 :            : 
      63                 :            :         /* Initialization */
      64                 :         48 :         port->ring = conf->ring;
      65                 :            : 
      66                 :         48 :         return port;
      67                 :            : }
      68                 :            : 
      69                 :            : static void *
      70                 :         49 : rte_port_ring_reader_create(void *params, int socket_id)
      71                 :            : {
      72                 :         49 :         return rte_port_ring_reader_create_internal(params, socket_id, 0);
      73                 :            : }
      74                 :            : 
      75                 :            : static void *
      76                 :          0 : rte_port_ring_multi_reader_create(void *params, int socket_id)
      77                 :            : {
      78                 :          0 :         return rte_port_ring_reader_create_internal(params, socket_id, 1);
      79                 :            : }
      80                 :            : 
      81                 :            : static int
      82                 :         86 : rte_port_ring_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
      83                 :            : {
      84                 :            :         struct rte_port_ring_reader *p = port;
      85                 :            :         uint32_t nb_rx;
      86                 :            : 
      87                 :         86 :         nb_rx = rte_ring_sc_dequeue_burst(p->ring, (void **) pkts,
      88                 :            :                         n_pkts, NULL);
      89                 :            :         RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
      90                 :            : 
      91                 :         86 :         return nb_rx;
      92                 :            : }
      93                 :            : 
      94                 :            : static int
      95                 :          0 : rte_port_ring_multi_reader_rx(void *port, struct rte_mbuf **pkts,
      96                 :            :         uint32_t n_pkts)
      97                 :            : {
      98                 :            :         struct rte_port_ring_reader *p = port;
      99                 :            :         uint32_t nb_rx;
     100                 :            : 
     101                 :          0 :         nb_rx = rte_ring_mc_dequeue_burst(p->ring, (void **) pkts,
     102                 :            :                         n_pkts, NULL);
     103                 :            :         RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
     104                 :            : 
     105                 :          0 :         return nb_rx;
     106                 :            : }
     107                 :            : 
     108                 :            : static int
     109                 :         48 : rte_port_ring_reader_free(void *port)
     110                 :            : {
     111         [ +  + ]:         48 :         if (port == NULL) {
     112                 :          1 :                 PORT_LOG(ERR, "%s: port is NULL", __func__);
     113                 :          1 :                 return -EINVAL;
     114                 :            :         }
     115                 :            : 
     116                 :         47 :         rte_free(port);
     117                 :            : 
     118                 :         47 :         return 0;
     119                 :            : }
     120                 :            : 
     121                 :            : static int
     122                 :          0 : rte_port_ring_reader_stats_read(void *port,
     123                 :            :                 struct rte_port_in_stats *stats, int clear)
     124                 :            : {
     125                 :            :         struct rte_port_ring_reader *p =
     126                 :            :                 port;
     127                 :            : 
     128         [ #  # ]:          0 :         if (stats != NULL)
     129                 :          0 :                 memcpy(stats, &p->stats, sizeof(p->stats));
     130                 :            : 
     131         [ #  # ]:          0 :         if (clear)
     132                 :          0 :                 memset(&p->stats, 0, sizeof(p->stats));
     133                 :            : 
     134                 :          0 :         return 0;
     135                 :            : }
     136                 :            : 
     137                 :            : /*
     138                 :            :  * Port RING Writer
     139                 :            :  */
     140                 :            : #ifdef RTE_PORT_STATS_COLLECT
     141                 :            : 
     142                 :            : #define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val) \
     143                 :            :         port->stats.n_pkts_in += val
     144                 :            : #define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val) \
     145                 :            :         port->stats.n_pkts_drop += val
     146                 :            : 
     147                 :            : #else
     148                 :            : 
     149                 :            : #define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val)
     150                 :            : #define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val)
     151                 :            : 
     152                 :            : #endif
     153                 :            : 
     154                 :            : struct rte_port_ring_writer {
     155                 :            :         struct rte_port_out_stats stats;
     156                 :            : 
     157                 :            :         struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
     158                 :            :         struct rte_ring *ring;
     159                 :            :         uint32_t tx_burst_sz;
     160                 :            :         uint32_t tx_buf_count;
     161                 :            :         uint64_t bsz_mask;
     162                 :            :         uint32_t is_multi;
     163                 :            : };
     164                 :            : 
     165                 :            : static void *
     166                 :         47 : rte_port_ring_writer_create_internal(void *params, int socket_id,
     167                 :            :         uint32_t is_multi)
     168                 :            : {
     169                 :            :         struct rte_port_ring_writer_params *conf =
     170                 :            :                         params;
     171                 :            :         struct rte_port_ring_writer *port;
     172                 :            : 
     173                 :            :         /* Check input parameters */
     174         [ +  + ]:         47 :         if ((conf == NULL) ||
     175   [ +  +  +  - ]:         46 :                 (conf->ring == NULL) ||
     176   [ +  -  -  + ]:         45 :                 (rte_ring_is_prod_single(conf->ring) && is_multi) ||
     177         [ #  # ]:          0 :                 (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
     178         [ +  + ]:         45 :                 (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
     179                 :          3 :                 PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
     180                 :          3 :                 return NULL;
     181                 :            :         }
     182                 :            : 
     183                 :            :         /* Memory allocation */
     184                 :         44 :         port = rte_zmalloc_socket("PORT", sizeof(*port),
     185                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     186         [ -  + ]:         44 :         if (port == NULL) {
     187                 :          0 :                 PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
     188                 :          0 :                 return NULL;
     189                 :            :         }
     190                 :            : 
     191                 :            :         /* Initialization */
     192                 :         44 :         port->ring = conf->ring;
     193                 :         44 :         port->tx_burst_sz = conf->tx_burst_sz;
     194                 :         44 :         port->tx_buf_count = 0;
     195                 :         44 :         port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
     196                 :         44 :         port->is_multi = is_multi;
     197                 :            : 
     198                 :         44 :         return port;
     199                 :            : }
     200                 :            : 
     201                 :            : static void *
     202                 :         47 : rte_port_ring_writer_create(void *params, int socket_id)
     203                 :            : {
     204                 :         47 :         return rte_port_ring_writer_create_internal(params, socket_id, 0);
     205                 :            : }
     206                 :            : 
     207                 :            : static void *
     208                 :          0 : rte_port_ring_multi_writer_create(void *params, int socket_id)
     209                 :            : {
     210                 :          0 :         return rte_port_ring_writer_create_internal(params, socket_id, 1);
     211                 :            : }
     212                 :            : 
     213                 :            : static inline void
     214                 :         53 : send_burst(struct rte_port_ring_writer *p)
     215                 :            : {
     216                 :            :         uint32_t nb_tx;
     217                 :            : 
     218                 :         53 :         nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
     219                 :            :                         p->tx_buf_count, NULL);
     220                 :            : 
     221                 :            :         RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
     222         [ -  + ]:         53 :         for ( ; nb_tx < p->tx_buf_count; nb_tx++)
     223                 :          0 :                 rte_pktmbuf_free(p->tx_buf[nb_tx]);
     224                 :            : 
     225                 :         53 :         p->tx_buf_count = 0;
     226                 :         53 : }
     227                 :            : 
     228                 :            : static inline void
     229                 :          0 : send_burst_mp(struct rte_port_ring_writer *p)
     230                 :            : {
     231                 :            :         uint32_t nb_tx;
     232                 :            : 
     233                 :          0 :         nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
     234                 :            :                         p->tx_buf_count, NULL);
     235                 :            : 
     236                 :            :         RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
     237         [ #  # ]:          0 :         for ( ; nb_tx < p->tx_buf_count; nb_tx++)
     238                 :          0 :                 rte_pktmbuf_free(p->tx_buf[nb_tx]);
     239                 :            : 
     240                 :          0 :         p->tx_buf_count = 0;
     241                 :          0 : }
     242                 :            : 
     243                 :            : static int
     244                 :       1209 : rte_port_ring_writer_tx(void *port, struct rte_mbuf *pkt)
     245                 :            : {
     246                 :            :         struct rte_port_ring_writer *p = port;
     247                 :            : 
     248                 :       1209 :         p->tx_buf[p->tx_buf_count++] = pkt;
     249                 :            :         RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
     250         [ +  + ]:       1209 :         if (p->tx_buf_count >= p->tx_burst_sz)
     251                 :          1 :                 send_burst(p);
     252                 :            : 
     253                 :       1209 :         return 0;
     254                 :            : }
     255                 :            : 
     256                 :            : static int
     257                 :          0 : rte_port_ring_multi_writer_tx(void *port, struct rte_mbuf *pkt)
     258                 :            : {
     259                 :            :         struct rte_port_ring_writer *p = port;
     260                 :            : 
     261                 :          0 :         p->tx_buf[p->tx_buf_count++] = pkt;
     262                 :            :         RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
     263         [ #  # ]:          0 :         if (p->tx_buf_count >= p->tx_burst_sz)
     264                 :          0 :                 send_burst_mp(p);
     265                 :            : 
     266                 :          0 :         return 0;
     267                 :            : }
     268                 :            : 
     269                 :            : static __rte_always_inline int
     270                 :            : rte_port_ring_writer_tx_bulk_internal(void *port,
     271                 :            :                 struct rte_mbuf **pkts,
     272                 :            :                 uint64_t pkts_mask,
     273                 :            :                 uint32_t is_multi)
     274                 :            : {
     275                 :            :         struct rte_port_ring_writer *p =
     276                 :            :                 port;
     277                 :            : 
     278                 :         15 :         uint64_t bsz_mask = p->bsz_mask;
     279                 :         15 :         uint32_t tx_buf_count = p->tx_buf_count;
     280                 :         15 :         uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
     281                 :            :                         ((pkts_mask & bsz_mask) ^ bsz_mask);
     282                 :            : 
     283                 :         15 :         if (expr == 0) {
     284                 :          1 :                 uint64_t n_pkts = rte_popcount64(pkts_mask);
     285                 :            :                 uint32_t n_pkts_ok;
     286                 :            : 
     287   [ -  -  -  + ]:          1 :                 if (tx_buf_count) {
     288                 :            :                         if (is_multi)
     289                 :          0 :                                 send_burst_mp(p);
     290                 :            :                         else
     291                 :          0 :                                 send_burst(p);
     292                 :            :                 }
     293                 :            : 
     294                 :            :                 RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
     295                 :            :                 if (is_multi)
     296                 :          0 :                         n_pkts_ok = rte_ring_mp_enqueue_burst(p->ring,
     297                 :            :                                         (void **)pkts, n_pkts, NULL);
     298                 :            :                 else
     299                 :          1 :                         n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring,
     300                 :            :                                         (void **)pkts, n_pkts, NULL);
     301                 :            : 
     302                 :            :                 RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
     303   [ -  -  -  + ]:          1 :                 for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
     304                 :          0 :                         struct rte_mbuf *pkt = pkts[n_pkts_ok];
     305                 :            : 
     306                 :          0 :                         rte_pktmbuf_free(pkt);
     307                 :            :                 }
     308                 :            :         } else {
     309   [ -  -  +  + ]:         96 :                 for ( ; pkts_mask; ) {
     310                 :         82 :                         uint32_t pkt_index = rte_ctz64(pkts_mask);
     311                 :         82 :                         uint64_t pkt_mask = 1LLU << pkt_index;
     312                 :         82 :                         struct rte_mbuf *pkt = pkts[pkt_index];
     313                 :            : 
     314                 :         82 :                         p->tx_buf[tx_buf_count++] = pkt;
     315                 :            :                         RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
     316                 :         82 :                         pkts_mask &= ~pkt_mask;
     317                 :            :                 }
     318                 :            : 
     319                 :         14 :                 p->tx_buf_count = tx_buf_count;
     320   [ -  -  +  + ]:         14 :                 if (tx_buf_count >= p->tx_burst_sz) {
     321                 :            :                         if (is_multi)
     322                 :          0 :                                 send_burst_mp(p);
     323                 :            :                         else
     324                 :          1 :                                 send_burst(p);
     325                 :            :                 }
     326                 :            :         }
     327                 :            : 
     328                 :            :         return 0;
     329                 :            : }
     330                 :            : 
     331                 :            : static int
     332         [ +  + ]:         15 : rte_port_ring_writer_tx_bulk(void *port,
     333                 :            :                 struct rte_mbuf **pkts,
     334                 :            :                 uint64_t pkts_mask)
     335                 :            : {
     336                 :         15 :         return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 0);
     337                 :            : }
     338                 :            : 
     339                 :            : static int
     340         [ #  # ]:          0 : rte_port_ring_multi_writer_tx_bulk(void *port,
     341                 :            :                 struct rte_mbuf **pkts,
     342                 :            :                 uint64_t pkts_mask)
     343                 :            : {
     344                 :          0 :         return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 1);
     345                 :            : }
     346                 :            : 
     347                 :            : static int
     348                 :        125 : rte_port_ring_writer_flush(void *port)
     349                 :            : {
     350                 :            :         struct rte_port_ring_writer *p = port;
     351                 :            : 
     352   [ -  +  +  + ]:        168 :         if (p->tx_buf_count > 0)
     353                 :         51 :                 send_burst(p);
     354                 :            : 
     355                 :        125 :         return 0;
     356                 :            : }
     357                 :            : 
     358                 :            : static int
     359                 :          0 : rte_port_ring_multi_writer_flush(void *port)
     360                 :            : {
     361                 :            :         struct rte_port_ring_writer *p = port;
     362                 :            : 
     363   [ #  #  #  # ]:          0 :         if (p->tx_buf_count > 0)
     364                 :          0 :                 send_burst_mp(p);
     365                 :            : 
     366                 :          0 :         return 0;
     367                 :            : }
     368                 :            : 
     369                 :            : static int
     370                 :         44 : rte_port_ring_writer_free(void *port)
     371                 :            : {
     372                 :            :         struct rte_port_ring_writer *p = port;
     373                 :            : 
     374         [ +  + ]:         44 :         if (port == NULL) {
     375                 :          1 :                 PORT_LOG(ERR, "%s: Port is NULL", __func__);
     376                 :          1 :                 return -EINVAL;
     377                 :            :         }
     378                 :            : 
     379         [ -  + ]:         43 :         if (p->is_multi)
     380                 :            :                 rte_port_ring_multi_writer_flush(port);
     381                 :            :         else
     382                 :            :                 rte_port_ring_writer_flush(port);
     383                 :            : 
     384                 :         43 :         rte_free(port);
     385                 :            : 
     386                 :         43 :         return 0;
     387                 :            : }
     388                 :            : 
     389                 :            : static int
     390                 :          0 : rte_port_ring_writer_stats_read(void *port,
     391                 :            :                 struct rte_port_out_stats *stats, int clear)
     392                 :            : {
     393                 :            :         struct rte_port_ring_writer *p =
     394                 :            :                 port;
     395                 :            : 
     396         [ #  # ]:          0 :         if (stats != NULL)
     397                 :          0 :                 memcpy(stats, &p->stats, sizeof(p->stats));
     398                 :            : 
     399         [ #  # ]:          0 :         if (clear)
     400                 :          0 :                 memset(&p->stats, 0, sizeof(p->stats));
     401                 :            : 
     402                 :          0 :         return 0;
     403                 :            : }
     404                 :            : 
     405                 :            : /*
     406                 :            :  * Port RING Writer Nodrop
     407                 :            :  */
     408                 :            : #ifdef RTE_PORT_STATS_COLLECT
     409                 :            : 
     410                 :            : #define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
     411                 :            :         port->stats.n_pkts_in += val
     412                 :            : #define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
     413                 :            :         port->stats.n_pkts_drop += val
     414                 :            : 
     415                 :            : #else
     416                 :            : 
     417                 :            : #define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
     418                 :            : #define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
     419                 :            : 
     420                 :            : #endif
     421                 :            : 
     422                 :            : struct rte_port_ring_writer_nodrop {
     423                 :            :         struct rte_port_out_stats stats;
     424                 :            : 
     425                 :            :         struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
     426                 :            :         struct rte_ring *ring;
     427                 :            :         uint32_t tx_burst_sz;
     428                 :            :         uint32_t tx_buf_count;
     429                 :            :         uint64_t bsz_mask;
     430                 :            :         uint64_t n_retries;
     431                 :            :         uint32_t is_multi;
     432                 :            : };
     433                 :            : 
     434                 :            : static void *
     435                 :          0 : rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
     436                 :            :         uint32_t is_multi)
     437                 :            : {
     438                 :            :         struct rte_port_ring_writer_nodrop_params *conf =
     439                 :            :                         params;
     440                 :            :         struct rte_port_ring_writer_nodrop *port;
     441                 :            : 
     442                 :            :         /* Check input parameters */
     443         [ #  # ]:          0 :         if ((conf == NULL) ||
     444   [ #  #  #  # ]:          0 :                 (conf->ring == NULL) ||
     445   [ #  #  #  # ]:          0 :                 (rte_ring_is_prod_single(conf->ring) && is_multi) ||
     446         [ #  # ]:          0 :                 (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
     447         [ #  # ]:          0 :                 (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
     448                 :          0 :                 PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
     449                 :          0 :                 return NULL;
     450                 :            :         }
     451                 :            : 
     452                 :            :         /* Memory allocation */
     453                 :          0 :         port = rte_zmalloc_socket("PORT", sizeof(*port),
     454                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     455         [ #  # ]:          0 :         if (port == NULL) {
     456                 :          0 :                 PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
     457                 :          0 :                 return NULL;
     458                 :            :         }
     459                 :            : 
     460                 :            :         /* Initialization */
     461                 :          0 :         port->ring = conf->ring;
     462                 :          0 :         port->tx_burst_sz = conf->tx_burst_sz;
     463                 :          0 :         port->tx_buf_count = 0;
     464                 :          0 :         port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
     465                 :          0 :         port->is_multi = is_multi;
     466                 :            : 
     467                 :            :         /*
     468                 :            :          * When n_retries is 0 it means that we should wait for every packet to
     469                 :            :          * send no matter how many retries should it take. To limit number of
     470                 :            :          * branches in fast path, we use UINT64_MAX instead of branching.
     471                 :            :          */
     472         [ #  # ]:          0 :         port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
     473                 :            : 
     474                 :          0 :         return port;
     475                 :            : }
     476                 :            : 
     477                 :            : static void *
     478                 :          0 : rte_port_ring_writer_nodrop_create(void *params, int socket_id)
     479                 :            : {
     480                 :          0 :         return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 0);
     481                 :            : }
     482                 :            : 
     483                 :            : static void *
     484                 :          0 : rte_port_ring_multi_writer_nodrop_create(void *params, int socket_id)
     485                 :            : {
     486                 :          0 :         return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 1);
     487                 :            : }
     488                 :            : 
     489                 :            : static inline void
     490                 :          0 : send_burst_nodrop(struct rte_port_ring_writer_nodrop *p)
     491                 :            : {
     492                 :            :         uint32_t nb_tx = 0, i;
     493                 :            : 
     494                 :          0 :         nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
     495                 :            :                                 p->tx_buf_count, NULL);
     496                 :            : 
     497                 :            :         /* We sent all the packets in a first try */
     498         [ #  # ]:          0 :         if (nb_tx >= p->tx_buf_count) {
     499                 :          0 :                 p->tx_buf_count = 0;
     500                 :          0 :                 return;
     501                 :            :         }
     502                 :            : 
     503         [ #  # ]:          0 :         for (i = 0; i < p->n_retries; i++) {
     504                 :          0 :                 nb_tx += rte_ring_sp_enqueue_burst(p->ring,
     505                 :          0 :                                 (void **) (p->tx_buf + nb_tx),
     506                 :          0 :                                 p->tx_buf_count - nb_tx, NULL);
     507                 :            : 
     508                 :            :                 /* We sent all the packets in more than one try */
     509         [ #  # ]:          0 :                 if (nb_tx >= p->tx_buf_count) {
     510                 :          0 :                         p->tx_buf_count = 0;
     511                 :          0 :                         return;
     512                 :            :                 }
     513                 :            :         }
     514                 :            : 
     515                 :            :         /* We didn't send the packets in maximum allowed attempts */
     516                 :            :         RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
     517         [ #  # ]:          0 :         for ( ; nb_tx < p->tx_buf_count; nb_tx++)
     518                 :          0 :                 rte_pktmbuf_free(p->tx_buf[nb_tx]);
     519                 :            : 
     520                 :          0 :         p->tx_buf_count = 0;
     521                 :            : }
     522                 :            : 
     523                 :            : static inline void
     524                 :          0 : send_burst_mp_nodrop(struct rte_port_ring_writer_nodrop *p)
     525                 :            : {
     526                 :            :         uint32_t nb_tx = 0, i;
     527                 :            : 
     528                 :          0 :         nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
     529                 :            :                                 p->tx_buf_count, NULL);
     530                 :            : 
     531                 :            :         /* We sent all the packets in a first try */
     532         [ #  # ]:          0 :         if (nb_tx >= p->tx_buf_count) {
     533                 :          0 :                 p->tx_buf_count = 0;
     534                 :          0 :                 return;
     535                 :            :         }
     536                 :            : 
     537         [ #  # ]:          0 :         for (i = 0; i < p->n_retries; i++) {
     538                 :          0 :                 nb_tx += rte_ring_mp_enqueue_burst(p->ring,
     539                 :          0 :                                 (void **) (p->tx_buf + nb_tx),
     540                 :          0 :                                 p->tx_buf_count - nb_tx, NULL);
     541                 :            : 
     542                 :            :                 /* We sent all the packets in more than one try */
     543         [ #  # ]:          0 :                 if (nb_tx >= p->tx_buf_count) {
     544                 :          0 :                         p->tx_buf_count = 0;
     545                 :          0 :                         return;
     546                 :            :                 }
     547                 :            :         }
     548                 :            : 
     549                 :            :         /* We didn't send the packets in maximum allowed attempts */
     550                 :            :         RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
     551         [ #  # ]:          0 :         for ( ; nb_tx < p->tx_buf_count; nb_tx++)
     552                 :          0 :                 rte_pktmbuf_free(p->tx_buf[nb_tx]);
     553                 :            : 
     554                 :          0 :         p->tx_buf_count = 0;
     555                 :            : }
     556                 :            : 
     557                 :            : static int
     558                 :          0 : rte_port_ring_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
     559                 :            : {
     560                 :            :         struct rte_port_ring_writer_nodrop *p =
     561                 :            :                         port;
     562                 :            : 
     563                 :          0 :         p->tx_buf[p->tx_buf_count++] = pkt;
     564                 :            :         RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
     565         [ #  # ]:          0 :         if (p->tx_buf_count >= p->tx_burst_sz)
     566                 :          0 :                 send_burst_nodrop(p);
     567                 :            : 
     568                 :          0 :         return 0;
     569                 :            : }
     570                 :            : 
     571                 :            : static int
     572                 :          0 : rte_port_ring_multi_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
     573                 :            : {
     574                 :            :         struct rte_port_ring_writer_nodrop *p =
     575                 :            :                         port;
     576                 :            : 
     577                 :          0 :         p->tx_buf[p->tx_buf_count++] = pkt;
     578                 :            :         RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
     579         [ #  # ]:          0 :         if (p->tx_buf_count >= p->tx_burst_sz)
     580                 :          0 :                 send_burst_mp_nodrop(p);
     581                 :            : 
     582                 :          0 :         return 0;
     583                 :            : }
     584                 :            : 
     585                 :            : static __rte_always_inline int
     586                 :            : rte_port_ring_writer_nodrop_tx_bulk_internal(void *port,
     587                 :            :                 struct rte_mbuf **pkts,
     588                 :            :                 uint64_t pkts_mask,
     589                 :            :                 uint32_t is_multi)
     590                 :            : {
     591                 :            :         struct rte_port_ring_writer_nodrop *p =
     592                 :            :                 port;
     593                 :            : 
     594                 :          0 :         uint64_t bsz_mask = p->bsz_mask;
     595                 :          0 :         uint32_t tx_buf_count = p->tx_buf_count;
     596                 :          0 :         uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
     597                 :            :                         ((pkts_mask & bsz_mask) ^ bsz_mask);
     598                 :            : 
     599                 :          0 :         if (expr == 0) {
     600                 :          0 :                 uint64_t n_pkts = rte_popcount64(pkts_mask);
     601                 :            :                 uint32_t n_pkts_ok;
     602                 :            : 
     603   [ #  #  #  # ]:          0 :                 if (tx_buf_count) {
     604                 :            :                         if (is_multi)
     605                 :          0 :                                 send_burst_mp_nodrop(p);
     606                 :            :                         else
     607                 :          0 :                                 send_burst_nodrop(p);
     608                 :            :                 }
     609                 :            : 
     610                 :            :                 RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
     611                 :            :                 if (is_multi)
     612                 :            :                         n_pkts_ok =
     613                 :          0 :                                 rte_ring_mp_enqueue_burst(p->ring,
     614                 :            :                                                 (void **)pkts, n_pkts, NULL);
     615                 :            :                 else
     616                 :            :                         n_pkts_ok =
     617                 :          0 :                                 rte_ring_sp_enqueue_burst(p->ring,
     618                 :            :                                                 (void **)pkts, n_pkts, NULL);
     619                 :            : 
     620   [ #  #  #  # ]:          0 :                 if (n_pkts_ok >= n_pkts)
     621                 :            :                         return 0;
     622                 :            : 
     623                 :            :                 /*
     624                 :            :                  * If we didn't manage to send all packets in single burst, move
     625                 :            :                  * remaining packets to the buffer and call send burst.
     626                 :            :                  */
     627   [ #  #  #  # ]:          0 :                 for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
     628                 :          0 :                         struct rte_mbuf *pkt = pkts[n_pkts_ok];
     629                 :            : 
     630                 :          0 :                         p->tx_buf[p->tx_buf_count++] = pkt;
     631                 :            :                 }
     632                 :            :                 if (is_multi)
     633                 :          0 :                         send_burst_mp_nodrop(p);
     634                 :            :                 else
     635                 :          0 :                         send_burst_nodrop(p);
     636                 :            :         } else {
     637   [ #  #  #  # ]:          0 :                 for ( ; pkts_mask; ) {
     638                 :          0 :                         uint32_t pkt_index = rte_ctz64(pkts_mask);
     639                 :          0 :                         uint64_t pkt_mask = 1LLU << pkt_index;
     640                 :          0 :                         struct rte_mbuf *pkt = pkts[pkt_index];
     641                 :            : 
     642                 :          0 :                         p->tx_buf[tx_buf_count++] = pkt;
     643                 :            :                         RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
     644                 :          0 :                         pkts_mask &= ~pkt_mask;
     645                 :            :                 }
     646                 :            : 
     647                 :          0 :                 p->tx_buf_count = tx_buf_count;
     648   [ #  #  #  # ]:          0 :                 if (tx_buf_count >= p->tx_burst_sz) {
     649                 :            :                         if (is_multi)
     650                 :          0 :                                 send_burst_mp_nodrop(p);
     651                 :            :                         else
     652                 :          0 :                                 send_burst_nodrop(p);
     653                 :            :                 }
     654                 :            :         }
     655                 :            : 
     656                 :            :         return 0;
     657                 :            : }
     658                 :            : 
     659                 :            : static int
     660         [ #  # ]:          0 : rte_port_ring_writer_nodrop_tx_bulk(void *port,
     661                 :            :                 struct rte_mbuf **pkts,
     662                 :            :                 uint64_t pkts_mask)
     663                 :            : {
     664                 :            :         return
     665                 :          0 :                 rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 0);
     666                 :            : }
     667                 :            : 
     668                 :            : static int
     669         [ #  # ]:          0 : rte_port_ring_multi_writer_nodrop_tx_bulk(void *port,
     670                 :            :                 struct rte_mbuf **pkts,
     671                 :            :                 uint64_t pkts_mask)
     672                 :            : {
     673                 :            :         return
     674                 :          0 :                 rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 1);
     675                 :            : }
     676                 :            : 
     677                 :            : static int
     678                 :          0 : rte_port_ring_writer_nodrop_flush(void *port)
     679                 :            : {
     680                 :            :         struct rte_port_ring_writer_nodrop *p =
     681                 :            :                         port;
     682                 :            : 
     683   [ #  #  #  # ]:          0 :         if (p->tx_buf_count > 0)
     684                 :          0 :                 send_burst_nodrop(p);
     685                 :            : 
     686                 :          0 :         return 0;
     687                 :            : }
     688                 :            : 
     689                 :            : static int
     690                 :          0 : rte_port_ring_multi_writer_nodrop_flush(void *port)
     691                 :            : {
     692                 :            :         struct rte_port_ring_writer_nodrop *p =
     693                 :            :                         port;
     694                 :            : 
     695   [ #  #  #  # ]:          0 :         if (p->tx_buf_count > 0)
     696                 :          0 :                 send_burst_mp_nodrop(p);
     697                 :            : 
     698                 :          0 :         return 0;
     699                 :            : }
     700                 :            : 
     701                 :            : static int
     702                 :          0 : rte_port_ring_writer_nodrop_free(void *port)
     703                 :            : {
     704                 :            :         struct rte_port_ring_writer_nodrop *p =
     705                 :            :                         port;
     706                 :            : 
     707         [ #  # ]:          0 :         if (port == NULL) {
     708                 :          0 :                 PORT_LOG(ERR, "%s: Port is NULL", __func__);
     709                 :          0 :                 return -EINVAL;
     710                 :            :         }
     711                 :            : 
     712         [ #  # ]:          0 :         if (p->is_multi)
     713                 :            :                 rte_port_ring_multi_writer_nodrop_flush(port);
     714                 :            :         else
     715                 :            :                 rte_port_ring_writer_nodrop_flush(port);
     716                 :            : 
     717                 :          0 :         rte_free(port);
     718                 :            : 
     719                 :          0 :         return 0;
     720                 :            : }
     721                 :            : 
     722                 :            : static int
     723                 :          0 : rte_port_ring_writer_nodrop_stats_read(void *port,
     724                 :            :                 struct rte_port_out_stats *stats, int clear)
     725                 :            : {
     726                 :            :         struct rte_port_ring_writer_nodrop *p =
     727                 :            :                 port;
     728                 :            : 
     729         [ #  # ]:          0 :         if (stats != NULL)
     730                 :          0 :                 memcpy(stats, &p->stats, sizeof(p->stats));
     731                 :            : 
     732         [ #  # ]:          0 :         if (clear)
     733                 :          0 :                 memset(&p->stats, 0, sizeof(p->stats));
     734                 :            : 
     735                 :          0 :         return 0;
     736                 :            : }
     737                 :            : 
     738                 :            : /*
     739                 :            :  * Summary of port operations
     740                 :            :  */
     741                 :            : struct rte_port_in_ops rte_port_ring_reader_ops = {
     742                 :            :         .f_create = rte_port_ring_reader_create,
     743                 :            :         .f_free = rte_port_ring_reader_free,
     744                 :            :         .f_rx = rte_port_ring_reader_rx,
     745                 :            :         .f_stats = rte_port_ring_reader_stats_read,
     746                 :            : };
     747                 :            : 
     748                 :            : struct rte_port_out_ops rte_port_ring_writer_ops = {
     749                 :            :         .f_create = rte_port_ring_writer_create,
     750                 :            :         .f_free = rte_port_ring_writer_free,
     751                 :            :         .f_tx = rte_port_ring_writer_tx,
     752                 :            :         .f_tx_bulk = rte_port_ring_writer_tx_bulk,
     753                 :            :         .f_flush = rte_port_ring_writer_flush,
     754                 :            :         .f_stats = rte_port_ring_writer_stats_read,
     755                 :            : };
     756                 :            : 
     757                 :            : struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
     758                 :            :         .f_create = rte_port_ring_writer_nodrop_create,
     759                 :            :         .f_free = rte_port_ring_writer_nodrop_free,
     760                 :            :         .f_tx = rte_port_ring_writer_nodrop_tx,
     761                 :            :         .f_tx_bulk = rte_port_ring_writer_nodrop_tx_bulk,
     762                 :            :         .f_flush = rte_port_ring_writer_nodrop_flush,
     763                 :            :         .f_stats = rte_port_ring_writer_nodrop_stats_read,
     764                 :            : };
     765                 :            : 
     766                 :            : struct rte_port_in_ops rte_port_ring_multi_reader_ops = {
     767                 :            :         .f_create = rte_port_ring_multi_reader_create,
     768                 :            :         .f_free = rte_port_ring_reader_free,
     769                 :            :         .f_rx = rte_port_ring_multi_reader_rx,
     770                 :            :         .f_stats = rte_port_ring_reader_stats_read,
     771                 :            : };
     772                 :            : 
     773                 :            : struct rte_port_out_ops rte_port_ring_multi_writer_ops = {
     774                 :            :         .f_create = rte_port_ring_multi_writer_create,
     775                 :            :         .f_free = rte_port_ring_writer_free,
     776                 :            :         .f_tx = rte_port_ring_multi_writer_tx,
     777                 :            :         .f_tx_bulk = rte_port_ring_multi_writer_tx_bulk,
     778                 :            :         .f_flush = rte_port_ring_multi_writer_flush,
     779                 :            :         .f_stats = rte_port_ring_writer_stats_read,
     780                 :            : };
     781                 :            : 
     782                 :            : struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops = {
     783                 :            :         .f_create = rte_port_ring_multi_writer_nodrop_create,
     784                 :            :         .f_free = rte_port_ring_writer_nodrop_free,
     785                 :            :         .f_tx = rte_port_ring_multi_writer_nodrop_tx,
     786                 :            :         .f_tx_bulk = rte_port_ring_multi_writer_nodrop_tx_bulk,
     787                 :            :         .f_flush = rte_port_ring_multi_writer_nodrop_flush,
     788                 :            :         .f_stats = rte_port_ring_writer_nodrop_stats_read,
     789                 :            : };

Generated by: LCOV version 1.14