LCOV - code coverage report
Current view: top level - drivers/common/idpf - idpf_common_rxtx_avx512.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 492 0.0 %
Date: 2024-01-22 16:26:08 Functions: 0 6 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 282 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2023 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_vect.h>
       6                 :            : #include "idpf_common_device.h"
       7                 :            : #include "idpf_common_rxtx.h"
       8                 :            : 
       9                 :            : #ifndef __INTEL_COMPILER
      10                 :            : #pragma GCC diagnostic ignored "-Wcast-qual"
      11                 :            : #endif
      12                 :            : 
      13                 :            : #define IDPF_DESCS_PER_LOOP_AVX 8
      14                 :            : #define PKTLEN_SHIFT 10
      15                 :            : 
      16                 :            : static __rte_always_inline void
      17                 :            : idpf_singleq_rearm_common(struct idpf_rx_queue *rxq)
      18                 :            : {
      19                 :            :         struct rte_mbuf **rxp = &rxq->sw_ring[rxq->rxrearm_start];
      20                 :            :         volatile union virtchnl2_rx_desc *rxdp = rxq->rx_ring;
      21                 :            :         uint16_t rx_id;
      22                 :            :         int i;
      23                 :            : 
      24                 :            :         rxdp += rxq->rxrearm_start;
      25                 :            : 
      26                 :            :         /* Pull 'n' more MBUFs into the software ring */
      27         [ #  # ]:          0 :         if (rte_mempool_get_bulk(rxq->mp,
      28                 :            :                                  (void *)rxp,
      29                 :            :                                  IDPF_RXQ_REARM_THRESH) < 0) {
      30                 :          0 :                 if (rxq->rxrearm_nb + IDPF_RXQ_REARM_THRESH >=
      31         [ #  # ]:          0 :                     rxq->nb_rx_desc) {
      32                 :            :                         __m128i dma_addr0;
      33                 :            : 
      34                 :            :                         dma_addr0 = _mm_setzero_si128();
      35         [ #  # ]:          0 :                         for (i = 0; i < IDPF_VPMD_DESCS_PER_LOOP; i++) {
      36                 :          0 :                                 rxp[i] = &rxq->fake_mbuf;
      37                 :          0 :                                 _mm_store_si128((__m128i *)&rxdp[i].read,
      38                 :            :                                                 dma_addr0);
      39                 :            :                         }
      40                 :            :                 }
      41                 :          0 :                 __atomic_fetch_add(&rxq->rx_stats.mbuf_alloc_failed,
      42                 :            :                                    IDPF_RXQ_REARM_THRESH, __ATOMIC_RELAXED);
      43                 :          0 :                 return;
      44                 :            :         }
      45                 :            :         struct rte_mbuf *mb0, *mb1, *mb2, *mb3;
      46                 :            :         struct rte_mbuf *mb4, *mb5, *mb6, *mb7;
      47                 :            :         __m512i dma_addr0_3, dma_addr4_7;
      48                 :            :         __m512i hdr_room = _mm512_set1_epi64(RTE_PKTMBUF_HEADROOM);
      49                 :            :         /* Initialize the mbufs in vector, process 8 mbufs in one loop */
      50         [ #  # ]:          0 :         for (i = 0; i < IDPF_RXQ_REARM_THRESH;
      51                 :          0 :                         i += 8, rxp += 8, rxdp += 8) {
      52                 :            :                 __m128i vaddr0, vaddr1, vaddr2, vaddr3;
      53                 :            :                 __m128i vaddr4, vaddr5, vaddr6, vaddr7;
      54                 :            :                 __m256i vaddr0_1, vaddr2_3;
      55                 :            :                 __m256i vaddr4_5, vaddr6_7;
      56                 :            :                 __m512i vaddr0_3, vaddr4_7;
      57                 :            : 
      58                 :          0 :                 mb0 = rxp[0];
      59                 :          0 :                 mb1 = rxp[1];
      60                 :          0 :                 mb2 = rxp[2];
      61                 :          0 :                 mb3 = rxp[3];
      62                 :          0 :                 mb4 = rxp[4];
      63                 :          0 :                 mb5 = rxp[5];
      64                 :          0 :                 mb6 = rxp[6];
      65                 :          0 :                 mb7 = rxp[7];
      66                 :            : 
      67                 :            :                 /* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
      68                 :            :                 RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
      69                 :            :                                 offsetof(struct rte_mbuf, buf_addr) + 8);
      70                 :            :                 vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
      71                 :            :                 vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
      72                 :            :                 vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
      73                 :            :                 vaddr3 = _mm_loadu_si128((__m128i *)&mb3->buf_addr);
      74                 :            :                 vaddr4 = _mm_loadu_si128((__m128i *)&mb4->buf_addr);
      75                 :            :                 vaddr5 = _mm_loadu_si128((__m128i *)&mb5->buf_addr);
      76                 :            :                 vaddr6 = _mm_loadu_si128((__m128i *)&mb6->buf_addr);
      77                 :            :                 vaddr7 = _mm_loadu_si128((__m128i *)&mb7->buf_addr);
      78                 :            : 
      79                 :            :                 /**
      80                 :            :                  * merge 0 & 1, by casting 0 to 256-bit and inserting 1
      81                 :            :                  * into the high lanes. Similarly for 2 & 3, and so on.
      82                 :            :                  */
      83                 :            :                 vaddr0_1 =
      84                 :            :                         _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr0),
      85                 :            :                                                 vaddr1, 1);
      86                 :            :                 vaddr2_3 =
      87                 :            :                         _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr2),
      88                 :            :                                                 vaddr3, 1);
      89                 :            :                 vaddr4_5 =
      90                 :            :                         _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr4),
      91                 :            :                                                 vaddr5, 1);
      92                 :            :                 vaddr6_7 =
      93                 :            :                         _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr6),
      94                 :            :                                                 vaddr7, 1);
      95                 :            :                 vaddr0_3 =
      96                 :            :                         _mm512_inserti64x4(_mm512_castsi256_si512(vaddr0_1),
      97                 :            :                                                 vaddr2_3, 1);
      98                 :            :                 vaddr4_7 =
      99                 :            :                         _mm512_inserti64x4(_mm512_castsi256_si512(vaddr4_5),
     100                 :            :                                                 vaddr6_7, 1);
     101                 :            : 
     102                 :            :                 /* convert pa to dma_addr hdr/data */
     103                 :            :                 dma_addr0_3 = _mm512_unpackhi_epi64(vaddr0_3, vaddr0_3);
     104                 :            :                 dma_addr4_7 = _mm512_unpackhi_epi64(vaddr4_7, vaddr4_7);
     105                 :            : 
     106                 :            :                 /* add headroom to pa values */
     107                 :            :                 dma_addr0_3 = _mm512_add_epi64(dma_addr0_3, hdr_room);
     108                 :            :                 dma_addr4_7 = _mm512_add_epi64(dma_addr4_7, hdr_room);
     109                 :            : 
     110                 :            :                 /* flush desc with pa dma_addr */
     111                 :            :                 _mm512_store_si512((__m512i *)&rxdp->read, dma_addr0_3);
     112                 :            :                 _mm512_store_si512((__m512i *)&(rxdp + 4)->read, dma_addr4_7);
     113                 :            :         }
     114                 :            : 
     115                 :          0 :         rxq->rxrearm_start += IDPF_RXQ_REARM_THRESH;
     116         [ #  # ]:          0 :         if (rxq->rxrearm_start >= rxq->nb_rx_desc)
     117                 :          0 :                 rxq->rxrearm_start = 0;
     118                 :            : 
     119                 :          0 :         rxq->rxrearm_nb -= IDPF_RXQ_REARM_THRESH;
     120                 :            : 
     121         [ #  # ]:          0 :         rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
     122                 :            :                              (rxq->nb_rx_desc - 1) : (rxq->rxrearm_start - 1));
     123                 :            : 
     124                 :            :         /* Update the tail pointer on the NIC */
     125                 :          0 :         IDPF_PCI_REG_WRITE(rxq->qrx_tail, rx_id);
     126                 :            : }
     127                 :            : 
     128                 :            : static __rte_always_inline void
     129                 :            : idpf_singleq_rearm(struct idpf_rx_queue *rxq)
     130                 :            : {
     131                 :            :         int i;
     132                 :            :         uint16_t rx_id;
     133                 :            :         volatile union virtchnl2_rx_desc *rxdp = rxq->rx_ring;
     134                 :            :         struct rte_mempool_cache *cache =
     135         [ #  # ]:          0 :                 rte_mempool_default_cache(rxq->mp, rte_lcore_id());
     136                 :          0 :         struct rte_mbuf **rxp = &rxq->sw_ring[rxq->rxrearm_start];
     137                 :            : 
     138                 :          0 :         rxdp += rxq->rxrearm_start;
     139                 :            : 
     140         [ #  # ]:          0 :         if (unlikely(cache == NULL))
     141                 :            :                 return idpf_singleq_rearm_common(rxq);
     142                 :            : 
     143                 :            :         /* We need to pull 'n' more MBUFs into the software ring from mempool
     144                 :            :          * We inline the mempool function here, so we can vectorize the copy
     145                 :            :          * from the cache into the shadow ring.
     146                 :            :          */
     147                 :            : 
     148                 :            :         /* Can this be satisfied from the cache? */
     149         [ #  # ]:          0 :         if (cache->len < IDPF_RXQ_REARM_THRESH) {
     150                 :            :                 /* No. Backfill the cache first, and then fill from it */
     151                 :          0 :                 uint32_t req = IDPF_RXQ_REARM_THRESH + (cache->size -
     152                 :            :                                                         cache->len);
     153                 :            : 
     154                 :            :                 /* How many do we require i.e. number to fill the cache + the request */
     155                 :          0 :                 int ret = rte_mempool_ops_dequeue_bulk
     156                 :            :                                 (rxq->mp, &cache->objs[cache->len], req);
     157         [ #  # ]:          0 :                 if (ret == 0) {
     158                 :          0 :                         cache->len += req;
     159                 :            :                 } else {
     160                 :          0 :                         if (rxq->rxrearm_nb + IDPF_RXQ_REARM_THRESH >=
     161         [ #  # ]:          0 :                             rxq->nb_rx_desc) {
     162                 :            :                                 __m128i dma_addr0;
     163                 :            : 
     164                 :            :                                 dma_addr0 = _mm_setzero_si128();
     165         [ #  # ]:          0 :                                 for (i = 0; i < IDPF_VPMD_DESCS_PER_LOOP; i++) {
     166                 :          0 :                                         rxp[i] = &rxq->fake_mbuf;
     167                 :          0 :                                         _mm_storeu_si128((__m128i *)&rxdp[i].read,
     168                 :            :                                                          dma_addr0);
     169                 :            :                                 }
     170                 :            :                         }
     171                 :          0 :                         __atomic_fetch_add(&rxq->rx_stats.mbuf_alloc_failed,
     172                 :            :                                            IDPF_RXQ_REARM_THRESH, __ATOMIC_RELAXED);
     173                 :          0 :                         return;
     174                 :            :                 }
     175                 :            :         }
     176                 :            : 
     177                 :            :         const __m512i iova_offsets =  _mm512_set1_epi64(offsetof
     178                 :            :                                                         (struct rte_mbuf, buf_iova));
     179                 :            :         const __m512i headroom = _mm512_set1_epi64(RTE_PKTMBUF_HEADROOM);
     180                 :            : 
     181                 :            :         /* to shuffle the addresses to correct slots. Values 4-7 will contain
     182                 :            :          * zeros, so use 7 for a zero-value.
     183                 :            :          */
     184                 :            :         const __m512i permute_idx = _mm512_set_epi64(7, 7, 3, 1, 7, 7, 2, 0);
     185                 :            : 
     186                 :            :         /* Initialize the mbufs in vector, process 8 mbufs in one loop, taking
     187                 :            :          * from mempool cache and populating both shadow and HW rings
     188                 :            :          */
     189         [ #  # ]:          0 :         for (i = 0; i < IDPF_RXQ_REARM_THRESH / IDPF_DESCS_PER_LOOP_AVX; i++) {
     190                 :            :                 const __m512i mbuf_ptrs = _mm512_loadu_si512
     191                 :          0 :                         (&cache->objs[cache->len - IDPF_DESCS_PER_LOOP_AVX]);
     192                 :            :                 _mm512_storeu_si512(rxp, mbuf_ptrs);
     193                 :            : 
     194                 :            :                 const __m512i iova_base_addrs = _mm512_i64gather_epi64
     195                 :            :                                 (_mm512_add_epi64(mbuf_ptrs, iova_offsets),
     196                 :            :                                  0, /* base */
     197                 :            :                                  1  /* scale */);
     198                 :            :                 const __m512i iova_addrs = _mm512_add_epi64(iova_base_addrs,
     199                 :            :                                 headroom);
     200                 :            :                 const __m512i iovas0 = _mm512_castsi256_si512
     201                 :            :                                 (_mm512_extracti64x4_epi64(iova_addrs, 0));
     202                 :            :                 const __m512i iovas1 = _mm512_castsi256_si512
     203                 :            :                                 (_mm512_extracti64x4_epi64(iova_addrs, 1));
     204                 :            : 
     205                 :            :                 /* permute leaves desc 2-3 addresses in header address slots 0-1
     206                 :            :                  * but these are ignored by driver since header split not
     207                 :            :                  * enabled. Similarly for desc 6 & 7.
     208                 :            :                  */
     209                 :            :                 const __m512i desc0_1 = _mm512_permutexvar_epi64
     210                 :            :                                 (permute_idx,
     211                 :            :                                  iovas0);
     212                 :            :                 const __m512i desc2_3 = _mm512_bsrli_epi128(desc0_1, 8);
     213                 :            : 
     214                 :            :                 const __m512i desc4_5 = _mm512_permutexvar_epi64
     215                 :            :                                 (permute_idx,
     216                 :            :                                  iovas1);
     217                 :            :                 const __m512i desc6_7 = _mm512_bsrli_epi128(desc4_5, 8);
     218                 :            : 
     219                 :            :                 _mm512_storeu_si512((void *)rxdp, desc0_1);
     220                 :            :                 _mm512_storeu_si512((void *)(rxdp + 2), desc2_3);
     221                 :            :                 _mm512_storeu_si512((void *)(rxdp + 4), desc4_5);
     222                 :            :                 _mm512_storeu_si512((void *)(rxdp + 6), desc6_7);
     223                 :            : 
     224                 :          0 :                 rxp += IDPF_DESCS_PER_LOOP_AVX;
     225                 :          0 :                 rxdp += IDPF_DESCS_PER_LOOP_AVX;
     226                 :          0 :                 cache->len -= IDPF_DESCS_PER_LOOP_AVX;
     227                 :            :         }
     228                 :            : 
     229                 :          0 :         rxq->rxrearm_start += IDPF_RXQ_REARM_THRESH;
     230         [ #  # ]:          0 :         if (rxq->rxrearm_start >= rxq->nb_rx_desc)
     231                 :          0 :                 rxq->rxrearm_start = 0;
     232                 :            : 
     233                 :          0 :         rxq->rxrearm_nb -= IDPF_RXQ_REARM_THRESH;
     234                 :            : 
     235         [ #  # ]:          0 :         rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
     236                 :            :                            (rxq->nb_rx_desc - 1) : (rxq->rxrearm_start - 1));
     237                 :            : 
     238                 :            :         /* Update the tail pointer on the NIC */
     239                 :          0 :         IDPF_PCI_REG_WRITE(rxq->qrx_tail, rx_id);
     240                 :            : }
     241                 :            : 
     242                 :            : #define IDPF_RX_LEN_MASK 0x80808080
     243                 :            : static __rte_always_inline uint16_t
     244                 :            : _idpf_singleq_recv_raw_pkts_avx512(struct idpf_rx_queue *rxq,
     245                 :            :                                    struct rte_mbuf **rx_pkts,
     246                 :            :                                    uint16_t nb_pkts)
     247                 :            : {
     248                 :          0 :         const uint32_t *type_table = rxq->adapter->ptype_tbl;
     249                 :            : 
     250                 :          0 :         const __m256i mbuf_init = _mm256_set_epi64x(0, 0, 0,
     251                 :          0 :                                                     rxq->mbuf_initializer);
     252                 :          0 :         struct rte_mbuf **sw_ring = &rxq->sw_ring[rxq->rx_tail];
     253                 :          0 :         volatile union virtchnl2_rx_desc *rxdp = rxq->rx_ring;
     254                 :            : 
     255                 :          0 :         rxdp += rxq->rx_tail;
     256                 :            : 
     257                 :            :         rte_prefetch0(rxdp);
     258                 :            : 
     259                 :            :         /* nb_pkts has to be floor-aligned to IDPF_DESCS_PER_LOOP_AVX */
     260                 :          0 :         nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IDPF_DESCS_PER_LOOP_AVX);
     261                 :            : 
     262                 :            :         /* See if we need to rearm the RX queue - gives the prefetch a bit
     263                 :            :          * of time to act
     264                 :            :          */
     265         [ #  # ]:          0 :         if (rxq->rxrearm_nb > IDPF_RXQ_REARM_THRESH)
     266                 :            :                 idpf_singleq_rearm(rxq);
     267                 :            : 
     268                 :            :         /* Before we start moving massive data around, check to see if
     269                 :            :          * there is actually a packet available
     270                 :            :          */
     271         [ #  # ]:          0 :         if ((rxdp->flex_nic_wb.status_error0  &
     272                 :            :               rte_cpu_to_le_32(1 << VIRTCHNL2_RX_FLEX_DESC_STATUS0_DD_S)) == 0)
     273                 :            :                 return 0;
     274                 :            : 
     275                 :            :         /* 8 packets DD mask, LSB in each 32-bit value */
     276                 :            :         const __m256i dd_check = _mm256_set1_epi32(1);
     277                 :            : 
     278                 :            :         /* mask to shuffle from desc. to mbuf (4 descriptors)*/
     279                 :            :         const __m512i shuf_msk =
     280                 :            :                 _mm512_set_epi32
     281                 :            :                         (/* 1st descriptor */
     282                 :            :                          0xFFFFFFFF,    /* rss set as unknown */
     283                 :            :                          0xFFFF0504,    /* vlan_macip set as unknown */
     284                 :            :                                         /* octet 15~14, 16 bits data_len */
     285                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     286                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     287                 :            :                          0xFFFFFFFF,    /* pkt_type set as unknown */
     288                 :            :                          /* 2nd descriptor */
     289                 :            :                          0xFFFFFFFF,    /* rss set as unknown */
     290                 :            :                          0xFFFF0504,    /* vlan_macip set as unknown */
     291                 :            :                                         /* octet 15~14, 16 bits data_len */
     292                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     293                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     294                 :            :                          0xFFFFFFFF,    /* pkt_type set as unknown */
     295                 :            :                          /* 3rd descriptor */
     296                 :            :                          0xFFFFFFFF,    /* rss set as unknown */
     297                 :            :                          0xFFFF0504,    /* vlan_macip set as unknown */
     298                 :            :                                         /* octet 15~14, 16 bits data_len */
     299                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     300                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     301                 :            :                          0xFFFFFFFF,    /* pkt_type set as unknown */
     302                 :            :                          /* 4th descriptor */
     303                 :            :                          0xFFFFFFFF,    /* rss set as unknown */
     304                 :            :                          0xFFFF0504,    /* vlan_macip set as unknown */
     305                 :            :                                         /* octet 15~14, 16 bits data_len */
     306                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     307                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     308                 :            :                          0xFFFFFFFF     /* pkt_type set as unknown */
     309                 :            :                         );
     310                 :            :         /**
     311                 :            :          * compile-time check the shuffle layout is correct.
     312                 :            :          * NOTE: the first field (lowest address) is given last in set_epi
     313                 :            :          * calls above.
     314                 :            :          */
     315                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
     316                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
     317                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
     318                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
     319                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
     320                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
     321                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
     322                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
     323                 :            : 
     324                 :            :         uint16_t i, received;
     325                 :            : 
     326         [ #  # ]:          0 :         for (i = 0, received = 0; i < nb_pkts;
     327                 :          0 :              i += IDPF_DESCS_PER_LOOP_AVX,
     328                 :          0 :              rxdp += IDPF_DESCS_PER_LOOP_AVX) {
     329                 :            :                 /* step 1, copy over 8 mbuf pointers to rx_pkts array */
     330                 :          0 :                 _mm256_storeu_si256((void *)&rx_pkts[i],
     331                 :          0 :                                     _mm256_loadu_si256((void *)&sw_ring[i]));
     332                 :            : #ifdef RTE_ARCH_X86_64
     333                 :            :                 _mm256_storeu_si256
     334                 :          0 :                         ((void *)&rx_pkts[i + 4],
     335                 :          0 :                          _mm256_loadu_si256((void *)&sw_ring[i + 4]));
     336                 :            : #endif
     337                 :            : 
     338                 :            :                 __m512i raw_desc0_3, raw_desc4_7;
     339                 :            :                 const __m128i raw_desc7 =
     340                 :            :                         _mm_load_si128((void *)(rxdp + 7));
     341                 :          0 :                 rte_compiler_barrier();
     342                 :            :                 const __m128i raw_desc6 =
     343                 :            :                         _mm_load_si128((void *)(rxdp + 6));
     344                 :          0 :                 rte_compiler_barrier();
     345                 :            :                 const __m128i raw_desc5 =
     346                 :            :                         _mm_load_si128((void *)(rxdp + 5));
     347                 :          0 :                 rte_compiler_barrier();
     348                 :            :                 const __m128i raw_desc4 =
     349                 :            :                         _mm_load_si128((void *)(rxdp + 4));
     350                 :          0 :                 rte_compiler_barrier();
     351                 :            :                 const __m128i raw_desc3 =
     352                 :            :                         _mm_load_si128((void *)(rxdp + 3));
     353                 :          0 :                 rte_compiler_barrier();
     354                 :            :                 const __m128i raw_desc2 =
     355                 :            :                         _mm_load_si128((void *)(rxdp + 2));
     356                 :          0 :                 rte_compiler_barrier();
     357                 :            :                 const __m128i raw_desc1 =
     358                 :            :                         _mm_load_si128((void *)(rxdp + 1));
     359                 :          0 :                 rte_compiler_barrier();
     360                 :            :                 const __m128i raw_desc0 =
     361                 :            :                         _mm_load_si128((void *)(rxdp + 0));
     362                 :            : 
     363                 :            :                 raw_desc4_7 = _mm512_broadcast_i32x4(raw_desc4);
     364                 :            :                 raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc5, 1);
     365                 :            :                 raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc6, 2);
     366                 :            :                 raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc7, 3);
     367                 :            :                 raw_desc0_3 = _mm512_broadcast_i32x4(raw_desc0);
     368                 :            :                 raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc1, 1);
     369                 :            :                 raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc2, 2);
     370                 :            :                 raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc3, 3);
     371                 :            : 
     372                 :            :                 /**
     373                 :            :                  * convert descriptors 4-7 into mbufs, adjusting length and
     374                 :            :                  * re-arranging fields. Then write into the mbuf
     375                 :            :                  */
     376                 :            :                 const __m512i len4_7 = _mm512_slli_epi32(raw_desc4_7,
     377                 :            :                                                          PKTLEN_SHIFT);
     378                 :            :                 const __m512i desc4_7 = _mm512_mask_blend_epi16(IDPF_RX_LEN_MASK,
     379                 :            :                                                                 raw_desc4_7,
     380                 :            :                                                                 len4_7);
     381                 :            :                 __m512i mb4_7 = _mm512_shuffle_epi8(desc4_7, shuf_msk);
     382                 :            : 
     383                 :            :                 /**
     384                 :            :                  * to get packet types, shift 64-bit values down 30 bits
     385                 :            :                  * and so ptype is in lower 8-bits in each
     386                 :            :                  */
     387                 :            :                 const __m512i ptypes4_7 = _mm512_srli_epi64(desc4_7, 16);
     388                 :            :                 const __m256i ptypes6_7 = _mm512_extracti64x4_epi64(ptypes4_7, 1);
     389                 :            :                 const __m256i ptypes4_5 = _mm512_extracti64x4_epi64(ptypes4_7, 0);
     390                 :            :                 const uint8_t ptype7 = _mm256_extract_epi8(ptypes6_7, 16);
     391                 :            :                 const uint8_t ptype6 = _mm256_extract_epi8(ptypes6_7, 0);
     392                 :            :                 const uint8_t ptype5 = _mm256_extract_epi8(ptypes4_5, 16);
     393                 :            :                 const uint8_t ptype4 = _mm256_extract_epi8(ptypes4_5, 0);
     394                 :            : 
     395                 :          0 :                 const __m512i ptype4_7 = _mm512_set_epi32
     396                 :          0 :                         (0, 0, 0, type_table[ptype7],
     397                 :          0 :                          0, 0, 0, type_table[ptype6],
     398                 :          0 :                          0, 0, 0, type_table[ptype5],
     399         [ #  # ]:          0 :                          0, 0, 0, type_table[ptype4]);
     400                 :            :                 mb4_7 = _mm512_mask_blend_epi32(0x1111, mb4_7, ptype4_7);
     401                 :            : 
     402                 :            :                 /**
     403                 :            :                  * convert descriptors 0-3 into mbufs, adjusting length and
     404                 :            :                  * re-arranging fields. Then write into the mbuf
     405                 :            :                  */
     406                 :            :                 const __m512i len0_3 = _mm512_slli_epi32(raw_desc0_3,
     407                 :            :                                                          PKTLEN_SHIFT);
     408                 :            :                 const __m512i desc0_3 = _mm512_mask_blend_epi16(IDPF_RX_LEN_MASK,
     409                 :            :                                                                 raw_desc0_3,
     410                 :            :                                                                 len0_3);
     411                 :            :                 __m512i mb0_3 = _mm512_shuffle_epi8(desc0_3, shuf_msk);
     412                 :            : 
     413                 :            :                 /* get the packet types */
     414                 :            :                 const __m512i ptypes0_3 = _mm512_srli_epi64(desc0_3, 16);
     415                 :            :                 const __m256i ptypes2_3 = _mm512_extracti64x4_epi64(ptypes0_3, 1);
     416                 :            :                 const __m256i ptypes0_1 = _mm512_extracti64x4_epi64(ptypes0_3, 0);
     417                 :            :                 const uint8_t ptype3 = _mm256_extract_epi8(ptypes2_3, 16);
     418                 :            :                 const uint8_t ptype2 = _mm256_extract_epi8(ptypes2_3, 0);
     419                 :            :                 const uint8_t ptype1 = _mm256_extract_epi8(ptypes0_1, 16);
     420                 :            :                 const uint8_t ptype0 = _mm256_extract_epi8(ptypes0_1, 0);
     421                 :            : 
     422                 :          0 :                 const __m512i ptype0_3 = _mm512_set_epi32
     423                 :          0 :                         (0, 0, 0, type_table[ptype3],
     424                 :          0 :                          0, 0, 0, type_table[ptype2],
     425                 :          0 :                          0, 0, 0, type_table[ptype1],
     426         [ #  # ]:          0 :                          0, 0, 0, type_table[ptype0]);
     427                 :            :                 mb0_3 = _mm512_mask_blend_epi32(0x1111, mb0_3, ptype0_3);
     428                 :            : 
     429                 :            :                 /**
     430                 :            :                  * use permute/extract to get status content
     431                 :            :                  * After the operations, the packets status flags are in the
     432                 :            :                  * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
     433                 :            :                  */
     434                 :            :                 /* merge the status bits into one register */
     435                 :            :                 const __m512i status_permute_msk = _mm512_set_epi32
     436                 :            :                         (0, 0, 0, 0,
     437                 :            :                          0, 0, 0, 0,
     438                 :            :                          22, 30, 6, 14,
     439                 :            :                          18, 26, 2, 10);
     440                 :            :                 const __m512i raw_status0_7 = _mm512_permutex2var_epi32
     441                 :            :                         (raw_desc4_7, status_permute_msk, raw_desc0_3);
     442                 :            :                 __m256i status0_7 = _mm512_extracti64x4_epi64
     443                 :            :                         (raw_status0_7, 0);
     444                 :            : 
     445                 :            :                 /* now do flag manipulation */
     446                 :            : 
     447                 :            :                 /**
     448                 :            :                  * At this point, we have the 8 sets of flags in the low 16-bits
     449                 :            :                  * of each 32-bit value.
     450                 :            :                  * We want to extract these, and merge them with the mbuf init
     451                 :            :                  * data so we can do a single write to the mbuf to set the flags
     452                 :            :                  * and all the other initialization fields. Extracting the
     453                 :            :                  * appropriate flags means that we have to do a shift and blend
     454                 :            :                  * for each mbuf before we do the write. However, we can also
     455                 :            :                  * add in the previously computed rx_descriptor fields to
     456                 :            :                  * make a single 256-bit write per mbuf
     457                 :            :                  */
     458                 :            :                 /* check the structure matches expectations */
     459                 :            :                 RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
     460                 :            :                                  offsetof(struct rte_mbuf, rearm_data) + 8);
     461                 :            :                 RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
     462                 :            :                                  RTE_ALIGN(offsetof(struct rte_mbuf,
     463                 :            :                                                     rearm_data),
     464                 :            :                                                     16));
     465                 :            :                 /* build up data and do writes */
     466                 :            :                 __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
     467                 :            :                         rearm6, rearm7;
     468                 :            :                 const __m256i mb4_5 = _mm512_extracti64x4_epi64(mb4_7, 0);
     469                 :            :                 const __m256i mb6_7 = _mm512_extracti64x4_epi64(mb4_7, 1);
     470                 :            :                 const __m256i mb0_1 = _mm512_extracti64x4_epi64(mb0_3, 0);
     471                 :            :                 const __m256i mb2_3 = _mm512_extracti64x4_epi64(mb0_3, 1);
     472                 :            : 
     473                 :            :                 rearm6 = _mm256_permute2f128_si256(mbuf_init, mb6_7, 0x20);
     474                 :            :                 rearm4 = _mm256_permute2f128_si256(mbuf_init, mb4_5, 0x20);
     475                 :            :                 rearm2 = _mm256_permute2f128_si256(mbuf_init, mb2_3, 0x20);
     476                 :            :                 rearm0 = _mm256_permute2f128_si256(mbuf_init, mb0_1, 0x20);
     477                 :            : 
     478                 :            :                 /* write to mbuf */
     479         [ #  # ]:          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
     480                 :            :                                     rearm6);
     481                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
     482                 :            :                                     rearm4);
     483                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
     484                 :            :                                     rearm2);
     485         [ #  # ]:          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
     486                 :            :                                     rearm0);
     487                 :            : 
     488                 :            :                 rearm7 = _mm256_blend_epi32(mbuf_init, mb6_7, 0xF0);
     489                 :            :                 rearm5 = _mm256_blend_epi32(mbuf_init, mb4_5, 0xF0);
     490                 :            :                 rearm3 = _mm256_blend_epi32(mbuf_init, mb2_3, 0xF0);
     491                 :            :                 rearm1 = _mm256_blend_epi32(mbuf_init, mb0_1, 0xF0);
     492                 :            : 
     493                 :            :                 /* again write to mbufs */
     494                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
     495                 :            :                                     rearm7);
     496                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
     497                 :            :                                     rearm5);
     498                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
     499                 :            :                                     rearm3);
     500         [ #  # ]:          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
     501                 :            :                                     rearm1);
     502                 :            : 
     503                 :            :                 /* perform dd_check */
     504                 :            :                 status0_7 = _mm256_and_si256(status0_7, dd_check);
     505                 :            :                 status0_7 = _mm256_packs_epi32(status0_7,
     506                 :            :                                                _mm256_setzero_si256());
     507                 :            : 
     508         [ #  # ]:          0 :                 uint64_t burst = rte_popcount64
     509                 :            :                                         (_mm_cvtsi128_si64
     510                 :            :                                                 (_mm256_extracti128_si256
     511                 :            :                                                         (status0_7, 1)));
     512                 :          0 :                 burst += rte_popcount64
     513                 :            :                                 (_mm_cvtsi128_si64
     514                 :            :                                         (_mm256_castsi256_si128(status0_7)));
     515                 :          0 :                 received += burst;
     516         [ #  # ]:          0 :                 if (burst != IDPF_DESCS_PER_LOOP_AVX)
     517                 :            :                         break;
     518                 :            :         }
     519                 :            : 
     520                 :            :         /* update tail pointers */
     521                 :          0 :         rxq->rx_tail += received;
     522                 :          0 :         rxq->rx_tail &= (rxq->nb_rx_desc - 1);
     523   [ #  #  #  # ]:          0 :         if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep aligned */
     524                 :          0 :                 rxq->rx_tail--;
     525                 :          0 :                 received--;
     526                 :            :         }
     527                 :          0 :         rxq->rxrearm_nb += received;
     528                 :          0 :         return received;
     529                 :            : }
     530                 :            : 
     531                 :            : /**
     532                 :            :  * Notice:
     533                 :            :  * - nb_pkts < IDPF_DESCS_PER_LOOP, just return no packet
     534                 :            :  */
     535                 :            : uint16_t
     536                 :          0 : idpf_dp_singleq_recv_pkts_avx512(void *rx_queue, struct rte_mbuf **rx_pkts,
     537                 :            :                                  uint16_t nb_pkts)
     538                 :            : {
     539                 :          0 :         return _idpf_singleq_recv_raw_pkts_avx512(rx_queue, rx_pkts, nb_pkts);
     540                 :            : }
     541                 :            : 
     542                 :            : static __rte_always_inline void
     543                 :            : idpf_splitq_rearm_common(struct idpf_rx_queue *rx_bufq)
     544                 :            : {
     545                 :            :         struct rte_mbuf **rxp = &rx_bufq->sw_ring[rx_bufq->rxrearm_start];
     546                 :            :         volatile union virtchnl2_rx_buf_desc *rxdp = rx_bufq->rx_ring;
     547                 :            :         uint16_t rx_id;
     548                 :            :         int i;
     549                 :            : 
     550                 :            :         rxdp += rx_bufq->rxrearm_start;
     551                 :            : 
     552                 :            :         /* Pull 'n' more MBUFs into the software ring */
     553         [ #  # ]:          0 :         if (rte_mempool_get_bulk(rx_bufq->mp,
     554                 :            :                                  (void *)rxp,
     555                 :            :                                  IDPF_RXQ_REARM_THRESH) < 0) {
     556                 :          0 :                 if (rx_bufq->rxrearm_nb + IDPF_RXQ_REARM_THRESH >=
     557         [ #  # ]:          0 :                     rx_bufq->nb_rx_desc) {
     558                 :            :                         __m128i dma_addr0;
     559                 :            : 
     560                 :            :                         dma_addr0 = _mm_setzero_si128();
     561         [ #  # ]:          0 :                         for (i = 0; i < IDPF_VPMD_DESCS_PER_LOOP; i++) {
     562                 :          0 :                                 rxp[i] = &rx_bufq->fake_mbuf;
     563                 :          0 :                                 _mm_store_si128((__m128i *)&rxdp[i],
     564                 :            :                                                 dma_addr0);
     565                 :            :                         }
     566                 :            :                 }
     567                 :          0 :         __atomic_fetch_add(&rx_bufq->rx_stats.mbuf_alloc_failed,
     568                 :            :                            IDPF_RXQ_REARM_THRESH, __ATOMIC_RELAXED);
     569                 :          0 :                 return;
     570                 :            :         }
     571                 :            : 
     572                 :            :         /* Initialize the mbufs in vector, process 8 mbufs in one loop */
     573         [ #  # ]:          0 :         for (i = 0; i < IDPF_RXQ_REARM_THRESH;
     574                 :          0 :                         i += 8, rxp += 8, rxdp += 8) {
     575                 :          0 :                 rxdp[0].split_rd.pkt_addr = rxp[0]->buf_iova + RTE_PKTMBUF_HEADROOM;
     576                 :          0 :                 rxdp[1].split_rd.pkt_addr = rxp[1]->buf_iova + RTE_PKTMBUF_HEADROOM;
     577                 :          0 :                 rxdp[2].split_rd.pkt_addr = rxp[2]->buf_iova + RTE_PKTMBUF_HEADROOM;
     578                 :          0 :                 rxdp[3].split_rd.pkt_addr = rxp[3]->buf_iova + RTE_PKTMBUF_HEADROOM;
     579                 :          0 :                 rxdp[4].split_rd.pkt_addr = rxp[4]->buf_iova + RTE_PKTMBUF_HEADROOM;
     580                 :          0 :                 rxdp[5].split_rd.pkt_addr = rxp[5]->buf_iova + RTE_PKTMBUF_HEADROOM;
     581                 :          0 :                 rxdp[6].split_rd.pkt_addr = rxp[6]->buf_iova + RTE_PKTMBUF_HEADROOM;
     582                 :          0 :                 rxdp[7].split_rd.pkt_addr = rxp[7]->buf_iova + RTE_PKTMBUF_HEADROOM;
     583                 :            :         }
     584                 :            : 
     585                 :          0 :         rx_bufq->rxrearm_start += IDPF_RXQ_REARM_THRESH;
     586         [ #  # ]:          0 :         if (rx_bufq->rxrearm_start >= rx_bufq->nb_rx_desc)
     587                 :          0 :                 rx_bufq->rxrearm_start = 0;
     588                 :            : 
     589                 :          0 :         rx_bufq->rxrearm_nb -= IDPF_RXQ_REARM_THRESH;
     590                 :            : 
     591         [ #  # ]:          0 :         rx_id = (uint16_t)((rx_bufq->rxrearm_start == 0) ?
     592                 :            :                              (rx_bufq->nb_rx_desc - 1) : (rx_bufq->rxrearm_start - 1));
     593                 :            : 
     594                 :            :         /* Update the tail pointer on the NIC */
     595                 :          0 :         IDPF_PCI_REG_WRITE(rx_bufq->qrx_tail, rx_id);
     596                 :            : }
     597                 :            : 
     598                 :            : static __rte_always_inline void
     599                 :            : idpf_splitq_rearm(struct idpf_rx_queue *rx_bufq)
     600                 :            : {
     601                 :            :         int i;
     602                 :            :         uint16_t rx_id;
     603         [ #  # ]:          0 :         volatile union virtchnl2_rx_buf_desc *rxdp = rx_bufq->rx_ring;
     604                 :            :         struct rte_mempool_cache *cache =
     605         [ #  # ]:          0 :                 rte_mempool_default_cache(rx_bufq->mp, rte_lcore_id());
     606                 :          0 :         struct rte_mbuf **rxp = &rx_bufq->sw_ring[rx_bufq->rxrearm_start];
     607                 :            : 
     608                 :          0 :         rxdp += rx_bufq->rxrearm_start;
     609                 :            : 
     610         [ #  # ]:          0 :         if (unlikely(!cache))
     611                 :            :                 return idpf_splitq_rearm_common(rx_bufq);
     612                 :            : 
     613                 :            :         /* We need to pull 'n' more MBUFs into the software ring from mempool
     614                 :            :          * We inline the mempool function here, so we can vectorize the copy
     615                 :            :          * from the cache into the shadow ring.
     616                 :            :          */
     617                 :            : 
     618                 :            :         /* Can this be satisfied from the cache? */
     619         [ #  # ]:          0 :         if (cache->len < IDPF_RXQ_REARM_THRESH) {
     620                 :            :                 /* No. Backfill the cache first, and then fill from it */
     621                 :          0 :                 uint32_t req = IDPF_RXQ_REARM_THRESH + (cache->size -
     622                 :            :                                                         cache->len);
     623                 :            : 
     624                 :            :                 /* How many do we require i.e. number to fill the cache + the request */
     625                 :          0 :                 int ret = rte_mempool_ops_dequeue_bulk
     626                 :            :                                 (rx_bufq->mp, &cache->objs[cache->len], req);
     627         [ #  # ]:          0 :                 if (ret == 0) {
     628                 :          0 :                         cache->len += req;
     629                 :            :                 } else {
     630                 :          0 :                         if (rx_bufq->rxrearm_nb + IDPF_RXQ_REARM_THRESH >=
     631         [ #  # ]:          0 :                             rx_bufq->nb_rx_desc) {
     632                 :            :                                 __m128i dma_addr0;
     633                 :            : 
     634                 :            :                                 dma_addr0 = _mm_setzero_si128();
     635         [ #  # ]:          0 :                                 for (i = 0; i < IDPF_VPMD_DESCS_PER_LOOP; i++) {
     636                 :          0 :                                         rxp[i] = &rx_bufq->fake_mbuf;
     637                 :          0 :                                         _mm_storeu_si128((__m128i *)&rxdp[i],
     638                 :            :                                                          dma_addr0);
     639                 :            :                                 }
     640                 :            :                         }
     641                 :          0 :                 __atomic_fetch_add(&rx_bufq->rx_stats.mbuf_alloc_failed,
     642                 :            :                                    IDPF_RXQ_REARM_THRESH, __ATOMIC_RELAXED);
     643                 :          0 :                         return;
     644                 :            :                 }
     645                 :            :         }
     646                 :            : 
     647                 :            :         const __m512i iova_offsets =  _mm512_set1_epi64(offsetof
     648                 :            :                                                         (struct rte_mbuf, buf_iova));
     649                 :            :         const __m512i headroom = _mm512_set1_epi64(RTE_PKTMBUF_HEADROOM);
     650                 :            : 
     651                 :            :         /* Initialize the mbufs in vector, process 8 mbufs in one loop, taking
     652                 :            :          * from mempool cache and populating both shadow and HW rings
     653                 :            :          */
     654         [ #  # ]:          0 :         for (i = 0; i < IDPF_RXQ_REARM_THRESH / IDPF_DESCS_PER_LOOP_AVX; i++) {
     655                 :            :                 const __m512i mbuf_ptrs = _mm512_loadu_si512
     656                 :          0 :                         (&cache->objs[cache->len - IDPF_DESCS_PER_LOOP_AVX]);
     657                 :            :                 _mm512_storeu_si512(rxp, mbuf_ptrs);
     658                 :            : 
     659                 :            :                 const __m512i iova_base_addrs = _mm512_i64gather_epi64
     660                 :            :                                 (_mm512_add_epi64(mbuf_ptrs, iova_offsets),
     661                 :            :                                  0, /* base */
     662                 :            :                                  1  /* scale */);
     663                 :            :                 const __m512i iova_addrs = _mm512_add_epi64(iova_base_addrs,
     664                 :            :                                 headroom);
     665                 :            : 
     666                 :            :                 const __m512i iova_addrs_1 = _mm512_bsrli_epi128(iova_addrs, 8);
     667                 :            : 
     668                 :          0 :                 rxdp[0].split_rd.pkt_addr =
     669                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs, 0));
     670                 :          0 :                 rxdp[1].split_rd.pkt_addr =
     671                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs_1, 0));
     672                 :          0 :                 rxdp[2].split_rd.pkt_addr =
     673                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs, 1));
     674                 :          0 :                 rxdp[3].split_rd.pkt_addr =
     675                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs_1, 1));
     676                 :          0 :                 rxdp[4].split_rd.pkt_addr =
     677                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs, 2));
     678                 :          0 :                 rxdp[5].split_rd.pkt_addr =
     679                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs_1, 2));
     680                 :          0 :                 rxdp[6].split_rd.pkt_addr =
     681                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs, 3));
     682                 :          0 :                 rxdp[7].split_rd.pkt_addr =
     683                 :          0 :                         _mm_cvtsi128_si64(_mm512_extracti32x4_epi32(iova_addrs_1, 3));
     684                 :            : 
     685                 :          0 :                 rxp += IDPF_DESCS_PER_LOOP_AVX;
     686                 :          0 :                 rxdp += IDPF_DESCS_PER_LOOP_AVX;
     687                 :          0 :                 cache->len -= IDPF_DESCS_PER_LOOP_AVX;
     688                 :            :         }
     689                 :            : 
     690                 :          0 :         rx_bufq->rxrearm_start += IDPF_RXQ_REARM_THRESH;
     691         [ #  # ]:          0 :         if (rx_bufq->rxrearm_start >= rx_bufq->nb_rx_desc)
     692                 :          0 :                 rx_bufq->rxrearm_start = 0;
     693                 :            : 
     694                 :          0 :         rx_bufq->rxrearm_nb -= IDPF_RXQ_REARM_THRESH;
     695                 :            : 
     696         [ #  # ]:          0 :         rx_id = (uint16_t)((rx_bufq->rxrearm_start == 0) ?
     697                 :            :                            (rx_bufq->nb_rx_desc - 1) : (rx_bufq->rxrearm_start - 1));
     698                 :            : 
     699                 :            :         /* Update the tail pointer on the NIC */
     700                 :          0 :         IDPF_PCI_REG_WRITE(rx_bufq->qrx_tail, rx_id);
     701                 :            : }
     702                 :            : 
     703                 :            : static __rte_always_inline uint16_t
     704                 :            : _idpf_splitq_recv_raw_pkts_avx512(struct idpf_rx_queue *rxq,
     705                 :            :                                   struct rte_mbuf **rx_pkts,
     706                 :            :                                   uint16_t nb_pkts)
     707                 :            : {
     708                 :          0 :         const uint32_t *type_table = rxq->adapter->ptype_tbl;
     709                 :          0 :         const __m256i mbuf_init = _mm256_set_epi64x(0, 0, 0,
     710                 :          0 :                                                     rxq->bufq2->mbuf_initializer);
     711                 :            :         /* only handle bufq2 here */
     712                 :          0 :         struct rte_mbuf **sw_ring = &rxq->bufq2->sw_ring[rxq->rx_tail];
     713                 :          0 :         volatile union virtchnl2_rx_desc *rxdp = rxq->rx_ring;
     714                 :            : 
     715                 :          0 :         rxdp += rxq->rx_tail;
     716                 :            : 
     717                 :            :         rte_prefetch0(rxdp);
     718                 :            : 
     719                 :            :         /* nb_pkts has to be floor-aligned to IDPF_DESCS_PER_LOOP_AVX */
     720                 :          0 :         nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IDPF_DESCS_PER_LOOP_AVX);
     721                 :            : 
     722                 :            :         /* See if we need to rearm the RX queue - gives the prefetch a bit
     723                 :            :          * of time to act
     724                 :            :          */
     725         [ #  # ]:          0 :         if (rxq->bufq2->rxrearm_nb > IDPF_RXQ_REARM_THRESH)
     726                 :            :                 idpf_splitq_rearm(rxq->bufq2);
     727                 :            : 
     728                 :            :         /* Before we start moving massive data around, check to see if
     729                 :            :          * there is actually a packet available
     730                 :            :          */
     731                 :          0 :         if (((rxdp->flex_adv_nic_3_wb.pktlen_gen_bufq_id &
     732                 :          0 :               VIRTCHNL2_RX_FLEX_DESC_ADV_GEN_M) >>
     733         [ #  # ]:          0 :              VIRTCHNL2_RX_FLEX_DESC_ADV_GEN_S) != rxq->expected_gen_id)
     734                 :            :                 return 0;
     735                 :            : 
     736                 :            :         const __m512i dd_check = _mm512_set1_epi64(1);
     737                 :            :         const __m512i gen_check = _mm512_set1_epi64((uint64_t)1<<46);
     738                 :            : 
     739                 :            :         /* mask to shuffle from desc. to mbuf (4 descriptors)*/
     740                 :            :         const __m512i shuf_msk =
     741                 :            :                 _mm512_set_epi32
     742                 :            :                         (/* 1st descriptor */
     743                 :            :                          0xFFFFFFFF,    /* octet 4~7, 32bits rss */
     744                 :            :                          0xFFFF0504,    /* octet 2~3, low 16 bits vlan_macip */
     745                 :            :                                         /* octet 15~14, 16 bits data_len */
     746                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     747                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     748                 :            :                          0xFFFFFFFF,    /* pkt_type set as unknown */
     749                 :            :                          /* 2nd descriptor */
     750                 :            :                          0xFFFFFFFF,    /* octet 4~7, 32bits rss */
     751                 :            :                          0xFFFF0504,    /* octet 2~3, low 16 bits vlan_macip */
     752                 :            :                                         /* octet 15~14, 16 bits data_len */
     753                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     754                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     755                 :            :                          0xFFFFFFFF,    /* pkt_type set as unknown */
     756                 :            :                          /* 3rd descriptor */
     757                 :            :                          0xFFFFFFFF,    /* octet 4~7, 32bits rss */
     758                 :            :                          0xFFFF0504,    /* octet 2~3, low 16 bits vlan_macip */
     759                 :            :                                         /* octet 15~14, 16 bits data_len */
     760                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     761                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     762                 :            :                          0xFFFFFFFF,    /* pkt_type set as unknown */
     763                 :            :                          /* 4th descriptor */
     764                 :            :                          0xFFFFFFFF,    /* octet 4~7, 32bits rss */
     765                 :            :                          0xFFFF0504,    /* octet 2~3, low 16 bits vlan_macip */
     766                 :            :                                         /* octet 15~14, 16 bits data_len */
     767                 :            :                          0xFFFF0504,    /* skip high 16 bits pkt_len, zero out */
     768                 :            :                                         /* octet 15~14, low 16 bits pkt_len */
     769                 :            :                          0xFFFFFFFF     /* pkt_type set as unknown */
     770                 :            :                         );
     771                 :            :         /**
     772                 :            :          * compile-time check the above crc and shuffle layout is correct.
     773                 :            :          * NOTE: the first field (lowest address) is given last in set_epi
     774                 :            :          * calls above.
     775                 :            :          */
     776                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
     777                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
     778                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
     779                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
     780                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
     781                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
     782                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
     783                 :            :                          offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
     784                 :            : 
     785                 :            :         uint16_t i, received;
     786                 :            : 
     787         [ #  # ]:          0 :         for (i = 0, received = 0; i < nb_pkts;
     788                 :          0 :              i += IDPF_DESCS_PER_LOOP_AVX,
     789                 :          0 :              rxdp += IDPF_DESCS_PER_LOOP_AVX) {
     790                 :            :                 /* step 1, copy over 8 mbuf pointers to rx_pkts array */
     791                 :          0 :                 _mm256_storeu_si256((void *)&rx_pkts[i],
     792                 :          0 :                                     _mm256_loadu_si256((void *)&sw_ring[i]));
     793                 :            : #ifdef RTE_ARCH_X86_64
     794                 :            :                 _mm256_storeu_si256
     795                 :          0 :                         ((void *)&rx_pkts[i + 4],
     796                 :          0 :                          _mm256_loadu_si256((void *)&sw_ring[i + 4]));
     797                 :            : #endif
     798                 :            : 
     799                 :            :                 __m512i raw_desc0_3, raw_desc4_7;
     800                 :            :                 const __m128i raw_desc7 =
     801                 :            :                         _mm_load_si128((void *)(rxdp + 7));
     802                 :          0 :                 rte_compiler_barrier();
     803                 :            :                 const __m128i raw_desc6 =
     804                 :            :                         _mm_load_si128((void *)(rxdp + 6));
     805                 :          0 :                 rte_compiler_barrier();
     806                 :            :                 const __m128i raw_desc5 =
     807                 :            :                         _mm_load_si128((void *)(rxdp + 5));
     808                 :          0 :                 rte_compiler_barrier();
     809                 :            :                 const __m128i raw_desc4 =
     810                 :            :                         _mm_load_si128((void *)(rxdp + 4));
     811                 :          0 :                 rte_compiler_barrier();
     812                 :            :                 const __m128i raw_desc3 =
     813                 :            :                         _mm_load_si128((void *)(rxdp + 3));
     814                 :          0 :                 rte_compiler_barrier();
     815                 :            :                 const __m128i raw_desc2 =
     816                 :            :                         _mm_load_si128((void *)(rxdp + 2));
     817                 :          0 :                 rte_compiler_barrier();
     818                 :            :                 const __m128i raw_desc1 =
     819                 :            :                         _mm_load_si128((void *)(rxdp + 1));
     820                 :          0 :                 rte_compiler_barrier();
     821                 :            :                 const __m128i raw_desc0 =
     822                 :            :                         _mm_load_si128((void *)(rxdp + 0));
     823                 :            : 
     824                 :            :                 raw_desc4_7 = _mm512_broadcast_i32x4(raw_desc4);
     825                 :            :                 raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc5, 1);
     826                 :            :                 raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc6, 2);
     827                 :            :                 raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc7, 3);
     828                 :            :                 raw_desc0_3 = _mm512_broadcast_i32x4(raw_desc0);
     829                 :            :                 raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc1, 1);
     830                 :            :                 raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc2, 2);
     831                 :            :                 raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc3, 3);
     832                 :            : 
     833                 :            :                 /**
     834                 :            :                  * convert descriptors 4-7 into mbufs, adjusting length and
     835                 :            :                  * re-arranging fields. Then write into the mbuf
     836                 :            :                  */
     837                 :            :                 const __m512i len_mask = _mm512_set_epi32(0xffffffff, 0xffffffff,
     838                 :            :                                                           0xffff3fff, 0xffffffff,
     839                 :            :                                                           0xffffffff, 0xffffffff,
     840                 :            :                                                           0xffff3fff, 0xffffffff,
     841                 :            :                                                           0xffffffff, 0xffffffff,
     842                 :            :                                                           0xffff3fff, 0xffffffff,
     843                 :            :                                                           0xffffffff, 0xffffffff,
     844                 :            :                                                           0xffff3fff, 0xffffffff);
     845                 :            :                 const __m512i desc4_7 = _mm512_and_epi32(raw_desc4_7, len_mask);
     846                 :            :                 __m512i mb4_7 = _mm512_shuffle_epi8(desc4_7, shuf_msk);
     847                 :            : 
     848                 :            :                 /**
     849                 :            :                  * to get packet types, shift 64-bit values down 30 bits
     850                 :            :                  * and so ptype is in lower 8-bits in each
     851                 :            :                  */
     852                 :            :                 const __m512i ptypes4_7 = _mm512_srli_epi64(desc4_7, 16);
     853                 :            :                 const __m256i ptypes6_7 = _mm512_extracti64x4_epi64(ptypes4_7, 1);
     854                 :            :                 const __m256i ptypes4_5 = _mm512_extracti64x4_epi64(ptypes4_7, 0);
     855                 :            :                 const uint8_t ptype7 = _mm256_extract_epi8(ptypes6_7, 16);
     856                 :            :                 const uint8_t ptype6 = _mm256_extract_epi8(ptypes6_7, 0);
     857                 :            :                 const uint8_t ptype5 = _mm256_extract_epi8(ptypes4_5, 16);
     858                 :            :                 const uint8_t ptype4 = _mm256_extract_epi8(ptypes4_5, 0);
     859                 :            : 
     860                 :          0 :                 const __m512i ptype4_7 = _mm512_set_epi32
     861                 :          0 :                         (0, 0, 0, type_table[ptype7],
     862                 :          0 :                          0, 0, 0, type_table[ptype6],
     863                 :          0 :                          0, 0, 0, type_table[ptype5],
     864         [ #  # ]:          0 :                          0, 0, 0, type_table[ptype4]);
     865                 :            :                 mb4_7 = _mm512_mask_blend_epi32(0x1111, mb4_7, ptype4_7);
     866                 :            : 
     867                 :            :                 /**
     868                 :            :                  * convert descriptors 0-3 into mbufs, adjusting length and
     869                 :            :                  * re-arranging fields. Then write into the mbuf
     870                 :            :                  */
     871                 :            :                 const __m512i desc0_3 = _mm512_and_epi32(raw_desc0_3, len_mask);
     872                 :            :                 __m512i mb0_3 = _mm512_shuffle_epi8(desc0_3, shuf_msk);
     873                 :            : 
     874                 :            :                 /* get the packet types */
     875                 :            :                 const __m512i ptypes0_3 = _mm512_srli_epi64(desc0_3, 16);
     876                 :            :                 const __m256i ptypes2_3 = _mm512_extracti64x4_epi64(ptypes0_3, 1);
     877                 :            :                 const __m256i ptypes0_1 = _mm512_extracti64x4_epi64(ptypes0_3, 0);
     878                 :            :                 const uint8_t ptype3 = _mm256_extract_epi8(ptypes2_3, 16);
     879                 :            :                 const uint8_t ptype2 = _mm256_extract_epi8(ptypes2_3, 0);
     880                 :            :                 const uint8_t ptype1 = _mm256_extract_epi8(ptypes0_1, 16);
     881                 :            :                 const uint8_t ptype0 = _mm256_extract_epi8(ptypes0_1, 0);
     882                 :            : 
     883                 :          0 :                 const __m512i ptype0_3 = _mm512_set_epi32
     884                 :          0 :                         (0, 0, 0, type_table[ptype3],
     885                 :          0 :                          0, 0, 0, type_table[ptype2],
     886                 :          0 :                          0, 0, 0, type_table[ptype1],
     887         [ #  # ]:          0 :                          0, 0, 0, type_table[ptype0]);
     888                 :            :                 mb0_3 = _mm512_mask_blend_epi32(0x1111, mb0_3, ptype0_3);
     889                 :            : 
     890                 :            :                 /**
     891                 :            :                  * use permute/extract to get status and generation bit content
     892                 :            :                  * After the operations, the packets status flags are in the
     893                 :            :                  * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
     894                 :            :                  */
     895                 :            : 
     896                 :            :                 const __m512i dd_permute_msk = _mm512_set_epi64
     897                 :            :                         (11, 15, 3, 7, 9, 13, 1, 5);
     898                 :            :                 const __m512i status0_7 = _mm512_permutex2var_epi64
     899                 :            :                         (raw_desc4_7, dd_permute_msk, raw_desc0_3);
     900                 :            :                 const __m512i gen_permute_msk = _mm512_set_epi64
     901                 :            :                         (10, 14, 2, 6, 8, 12, 0, 4);
     902                 :            :                 const __m512i raw_gen0_7 = _mm512_permutex2var_epi64
     903                 :            :                         (raw_desc4_7, gen_permute_msk, raw_desc0_3);
     904                 :            : 
     905                 :            :                 /* now do flag manipulation */
     906                 :            : 
     907                 :            :                 /**
     908                 :            :                  * At this point, we have the 8 sets of flags in the low 16-bits
     909                 :            :                  * of each 32-bit value in vlan0.
     910                 :            :                  * We want to extract these, and merge them with the mbuf init
     911                 :            :                  * data so we can do a single write to the mbuf to set the flags
     912                 :            :                  * and all the other initialization fields. Extracting the
     913                 :            :                  * appropriate flags means that we have to do a shift and blend
     914                 :            :                  * for each mbuf before we do the write. However, we can also
     915                 :            :                  * add in the previously computed rx_descriptor fields to
     916                 :            :                  * make a single 256-bit write per mbuf
     917                 :            :                  */
     918                 :            :                 /* check the structure matches expectations */
     919                 :            :                 RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
     920                 :            :                                  offsetof(struct rte_mbuf, rearm_data) + 8);
     921                 :            :                 RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
     922                 :            :                                  RTE_ALIGN(offsetof(struct rte_mbuf,
     923                 :            :                                                     rearm_data),
     924                 :            :                                                     16));
     925                 :            :                                 /* build up data and do writes */
     926                 :            :                 __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
     927                 :            :                         rearm6, rearm7;
     928                 :            :                 const __m256i mb4_5 = _mm512_extracti64x4_epi64(mb4_7, 0);
     929                 :            :                 const __m256i mb6_7 = _mm512_extracti64x4_epi64(mb4_7, 1);
     930                 :            :                 const __m256i mb0_1 = _mm512_extracti64x4_epi64(mb0_3, 0);
     931                 :            :                 const __m256i mb2_3 = _mm512_extracti64x4_epi64(mb0_3, 1);
     932                 :            : 
     933                 :            :                 rearm6 = _mm256_permute2f128_si256(mbuf_init, mb6_7, 0x20);
     934                 :            :                 rearm4 = _mm256_permute2f128_si256(mbuf_init, mb4_5, 0x20);
     935                 :            :                 rearm2 = _mm256_permute2f128_si256(mbuf_init, mb2_3, 0x20);
     936                 :            :                 rearm0 = _mm256_permute2f128_si256(mbuf_init, mb0_1, 0x20);
     937                 :            : 
     938                 :            :                 /* write to mbuf */
     939         [ #  # ]:          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
     940                 :            :                                     rearm6);
     941                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
     942                 :            :                                     rearm4);
     943                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
     944                 :            :                                     rearm2);
     945         [ #  # ]:          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
     946                 :            :                                     rearm0);
     947                 :            : 
     948                 :            :                 rearm7 = _mm256_blend_epi32(mbuf_init, mb6_7, 0xF0);
     949                 :            :                 rearm5 = _mm256_blend_epi32(mbuf_init, mb4_5, 0xF0);
     950                 :            :                 rearm3 = _mm256_blend_epi32(mbuf_init, mb2_3, 0xF0);
     951                 :            :                 rearm1 = _mm256_blend_epi32(mbuf_init, mb0_1, 0xF0);
     952                 :            : 
     953                 :            :                 /* again write to mbufs */
     954                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
     955                 :            :                                     rearm7);
     956                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
     957                 :            :                                     rearm5);
     958                 :          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
     959                 :            :                                     rearm3);
     960         [ #  # ]:          0 :                 _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
     961                 :            :                                     rearm1);
     962                 :            : 
     963                 :            :                 const __mmask8 dd_mask = _mm512_cmpeq_epi64_mask(
     964                 :            :                         _mm512_and_epi64(status0_7, dd_check), dd_check);
     965                 :          0 :                 const __mmask8 gen_mask = _mm512_cmpeq_epi64_mask(
     966                 :            :                         _mm512_and_epi64(raw_gen0_7, gen_check),
     967         [ #  # ]:          0 :                         _mm512_set1_epi64((uint64_t)rxq->expected_gen_id << 46));
     968         [ #  # ]:          0 :                 const __mmask8 recv_mask = _kand_mask8(dd_mask, gen_mask);
     969         [ #  # ]:          0 :                 uint16_t burst = rte_popcount32(_cvtmask8_u32(recv_mask));
     970                 :            : 
     971                 :          0 :                 received += burst;
     972         [ #  # ]:          0 :                 if (burst != IDPF_DESCS_PER_LOOP_AVX)
     973                 :            :                         break;
     974                 :            :         }
     975                 :            : 
     976                 :            :         /* update tail pointers */
     977                 :          0 :         rxq->rx_tail += received;
     978                 :          0 :         rxq->expected_gen_id ^= ((rxq->rx_tail & rxq->nb_rx_desc) != 0);
     979                 :          0 :         rxq->rx_tail &= (rxq->nb_rx_desc - 1);
     980   [ #  #  #  # ]:          0 :         if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep aligned */
     981                 :          0 :                 rxq->rx_tail--;
     982                 :          0 :                 received--;
     983                 :            :         }
     984                 :            : 
     985                 :          0 :         rxq->bufq2->rxrearm_nb += received;
     986                 :          0 :         return received;
     987                 :            : }
     988                 :            : 
     989                 :            : /* only bufq2 can receive pkts */
     990                 :            : uint16_t
     991                 :          0 : idpf_dp_splitq_recv_pkts_avx512(void *rx_queue, struct rte_mbuf **rx_pkts,
     992                 :            :                              uint16_t nb_pkts)
     993                 :            : {
     994                 :          0 :         return _idpf_splitq_recv_raw_pkts_avx512(rx_queue, rx_pkts,
     995                 :            :                                                  nb_pkts);
     996                 :            : }
     997                 :            : 
     998                 :            : static __rte_always_inline int
     999                 :            : idpf_tx_singleq_free_bufs_avx512(struct idpf_tx_queue *txq)
    1000                 :          0 : {
    1001                 :            :         struct idpf_tx_vec_entry *txep;
    1002                 :            :         uint32_t n;
    1003                 :            :         uint32_t i;
    1004                 :            :         int nb_free = 0;
    1005                 :          0 :         struct rte_mbuf *m, *free[txq->rs_thresh];
    1006                 :            : 
    1007                 :            :         /* check DD bits on threshold descriptor */
    1008         [ #  # ]:          0 :         if ((txq->tx_ring[txq->next_dd].qw1 &
    1009                 :            :                         rte_cpu_to_le_64(IDPF_TXD_QW1_DTYPE_M)) !=
    1010                 :            :                         rte_cpu_to_le_64(IDPF_TX_DESC_DTYPE_DESC_DONE))
    1011                 :            :                 return 0;
    1012                 :            : 
    1013                 :          0 :         n = txq->rs_thresh;
    1014                 :            : 
    1015                 :            :          /* first buffer to free from S/W ring is at index
    1016                 :            :           * tx_next_dd - (tx_rs_thresh-1)
    1017                 :            :           */
    1018                 :          0 :         txep = (void *)txq->sw_ring;
    1019                 :          0 :         txep += txq->next_dd - (n - 1);
    1020                 :            : 
    1021   [ #  #  #  # ]:          0 :         if (txq->offloads & IDPF_TX_OFFLOAD_MBUF_FAST_FREE && (n & 31) == 0) {
    1022         [ #  # ]:          0 :                 struct rte_mempool *mp = txep[0].mbuf->pool;
    1023                 :            :                 struct rte_mempool_cache *cache = rte_mempool_default_cache(mp,
    1024                 :            :                                                                 rte_lcore_id());
    1025                 :            :                 void **cache_objs;
    1026                 :            : 
    1027   [ #  #  #  # ]:          0 :                 if (cache == NULL || cache->len == 0)
    1028                 :          0 :                         goto normal;
    1029                 :            : 
    1030                 :          0 :                 cache_objs = &cache->objs[cache->len];
    1031                 :            : 
    1032         [ #  # ]:          0 :                 if (n > RTE_MEMPOOL_CACHE_MAX_SIZE) {
    1033                 :          0 :                         rte_mempool_ops_enqueue_bulk(mp, (void *)txep, n);
    1034                 :          0 :                         goto done;
    1035                 :            :                 }
    1036                 :            : 
    1037                 :            :                 /* The cache follows the following algorithm
    1038                 :            :                  *   1. Add the objects to the cache
    1039                 :            :                  *   2. Anything greater than the cache min value (if it crosses the
    1040                 :            :                  *   cache flush threshold) is flushed to the ring.
    1041                 :            :                  */
    1042                 :            :                 /* Add elements back into the cache */
    1043                 :            :                 uint32_t copied = 0;
    1044                 :            :                 /* n is multiple of 32 */
    1045         [ #  # ]:          0 :                 while (copied < n) {
    1046                 :          0 :                         const __m512i a = _mm512_loadu_si512(&txep[copied]);
    1047                 :          0 :                         const __m512i b = _mm512_loadu_si512(&txep[copied + 8]);
    1048                 :          0 :                         const __m512i c = _mm512_loadu_si512(&txep[copied + 16]);
    1049                 :          0 :                         const __m512i d = _mm512_loadu_si512(&txep[copied + 24]);
    1050                 :            : 
    1051                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied], a);
    1052                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied + 8], b);
    1053                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied + 16], c);
    1054                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied + 24], d);
    1055                 :          0 :                         copied += 32;
    1056                 :            :                 }
    1057                 :          0 :                 cache->len += n;
    1058                 :            : 
    1059         [ #  # ]:          0 :                 if (cache->len >= cache->flushthresh) {
    1060                 :          0 :                         rte_mempool_ops_enqueue_bulk(mp,
    1061                 :          0 :                                                      &cache->objs[cache->size],
    1062                 :          0 :                                                      cache->len - cache->size);
    1063                 :          0 :                         cache->len = cache->size;
    1064                 :            :                 }
    1065                 :          0 :                 goto done;
    1066                 :            :         }
    1067                 :            : 
    1068                 :          0 : normal:
    1069         [ #  # ]:          0 :         m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
    1070         [ #  # ]:          0 :         if (likely(m != NULL)) {
    1071                 :          0 :                 free[0] = m;
    1072                 :            :                 nb_free = 1;
    1073         [ #  # ]:          0 :                 for (i = 1; i < n; i++) {
    1074         [ #  # ]:          0 :                         m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
    1075         [ #  # ]:          0 :                         if (likely(m != NULL)) {
    1076         [ #  # ]:          0 :                                 if (likely(m->pool == free[0]->pool)) {
    1077                 :          0 :                                         free[nb_free++] = m;
    1078                 :            :                                 } else {
    1079         [ #  # ]:          0 :                                         rte_mempool_put_bulk(free[0]->pool,
    1080                 :            :                                                              (void *)free,
    1081                 :            :                                                              nb_free);
    1082                 :          0 :                                         free[0] = m;
    1083                 :            :                                         nb_free = 1;
    1084                 :            :                                 }
    1085                 :            :                         }
    1086                 :            :                 }
    1087         [ #  # ]:          0 :                 rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
    1088                 :            :         } else {
    1089         [ #  # ]:          0 :                 for (i = 1; i < n; i++) {
    1090         [ #  # ]:          0 :                         m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
    1091         [ #  # ]:          0 :                         if (m != NULL)
    1092         [ #  # ]:          0 :                                 rte_mempool_put(m->pool, m);
    1093                 :            :                 }
    1094                 :            :         }
    1095                 :            : 
    1096                 :          0 : done:
    1097                 :            :         /* buffers were freed, update counters */
    1098                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_free + txq->rs_thresh);
    1099                 :          0 :         txq->next_dd = (uint16_t)(txq->next_dd + txq->rs_thresh);
    1100         [ #  # ]:          0 :         if (txq->next_dd >= txq->nb_tx_desc)
    1101                 :          0 :                 txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
    1102                 :            : 
    1103                 :            :         return txq->rs_thresh;
    1104                 :            : }
    1105                 :            : 
    1106                 :            : static __rte_always_inline void
    1107                 :            : tx_backlog_entry_avx512(struct idpf_tx_vec_entry *txep,
    1108                 :            :                         struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
    1109                 :            : {
    1110                 :            :         int i;
    1111                 :            : 
    1112   [ #  #  #  #  :          0 :         for (i = 0; i < (int)nb_pkts; ++i)
             #  #  #  # ]
    1113                 :          0 :                 txep[i].mbuf = tx_pkts[i];
    1114                 :            : }
    1115                 :            : 
    1116                 :            : static __rte_always_inline void
    1117                 :            : idpf_singleq_vtx1(volatile struct idpf_base_tx_desc *txdp,
    1118                 :            :           struct rte_mbuf *pkt, uint64_t flags)
    1119                 :            : {
    1120                 :          0 :         uint64_t high_qw =
    1121                 :            :                 (IDPF_TX_DESC_DTYPE_DATA |
    1122                 :            :                  ((uint64_t)flags  << IDPF_TXD_QW1_CMD_S) |
    1123                 :          0 :                  ((uint64_t)pkt->data_len << IDPF_TXD_QW1_TX_BUF_SZ_S));
    1124                 :            : 
    1125                 :          0 :         __m128i descriptor = _mm_set_epi64x(high_qw,
    1126                 :          0 :                                             pkt->buf_iova + pkt->data_off);
    1127                 :            :         _mm_storeu_si128((__m128i *)txdp, descriptor);
    1128                 :            : }
    1129                 :            : 
    1130                 :            : #define IDPF_TX_LEN_MASK 0xAA
    1131                 :            : #define IDPF_TX_OFF_MASK 0x55
    1132                 :            : static __rte_always_inline void
    1133                 :            : idpf_singleq_vtx(volatile struct idpf_base_tx_desc *txdp,
    1134                 :            :          struct rte_mbuf **pkt, uint16_t nb_pkts,  uint64_t flags)
    1135                 :            : {
    1136                 :            :         const uint64_t hi_qw_tmpl = (IDPF_TX_DESC_DTYPE_DATA  |
    1137                 :            :                         ((uint64_t)flags  << IDPF_TXD_QW1_CMD_S));
    1138                 :            : 
    1139                 :            :         /* if unaligned on 32-bit boundary, do one to align */
    1140   [ #  #  #  #  :          0 :         if (((uintptr_t)txdp & 0x1F) != 0 && nb_pkts != 0) {
                   #  # ]
    1141                 :          0 :                 idpf_singleq_vtx1(txdp, *pkt, flags);
    1142                 :          0 :                 nb_pkts--, txdp++, pkt++;
    1143                 :            :         }
    1144                 :            : 
    1145                 :            :         /* do 4 at a time while possible, in bursts */
    1146   [ #  #  #  # ]:          0 :         for (; nb_pkts > 3; txdp += 4, pkt += 4, nb_pkts -= 4) {
    1147                 :          0 :                 uint64_t hi_qw3 =
    1148                 :            :                         hi_qw_tmpl |
    1149                 :          0 :                         ((uint64_t)pkt[3]->data_len <<
    1150                 :            :                          IDPF_TXD_QW1_TX_BUF_SZ_S);
    1151                 :          0 :                 uint64_t hi_qw2 =
    1152                 :            :                         hi_qw_tmpl |
    1153                 :          0 :                         ((uint64_t)pkt[2]->data_len <<
    1154                 :            :                          IDPF_TXD_QW1_TX_BUF_SZ_S);
    1155                 :          0 :                 uint64_t hi_qw1 =
    1156                 :            :                         hi_qw_tmpl |
    1157                 :          0 :                         ((uint64_t)pkt[1]->data_len <<
    1158                 :            :                          IDPF_TXD_QW1_TX_BUF_SZ_S);
    1159                 :          0 :                 uint64_t hi_qw0 =
    1160                 :            :                         hi_qw_tmpl |
    1161                 :          0 :                         ((uint64_t)pkt[0]->data_len <<
    1162                 :            :                          IDPF_TXD_QW1_TX_BUF_SZ_S);
    1163                 :            : 
    1164                 :            :                 __m512i desc0_3 =
    1165                 :          0 :                         _mm512_set_epi64
    1166                 :            :                                 (hi_qw3,
    1167                 :          0 :                                  pkt[3]->buf_iova + pkt[3]->data_off,
    1168                 :            :                                  hi_qw2,
    1169                 :          0 :                                  pkt[2]->buf_iova + pkt[2]->data_off,
    1170                 :            :                                  hi_qw1,
    1171                 :          0 :                                  pkt[1]->buf_iova + pkt[1]->data_off,
    1172                 :            :                                  hi_qw0,
    1173                 :          0 :                                  pkt[0]->buf_iova + pkt[0]->data_off);
    1174                 :            :                 _mm512_storeu_si512((void *)txdp, desc0_3);
    1175                 :            :         }
    1176                 :            : 
    1177                 :            :         /* do any last ones */
    1178   [ #  #  #  # ]:          0 :         while (nb_pkts) {
    1179                 :          0 :                 idpf_singleq_vtx1(txdp, *pkt, flags);
    1180                 :          0 :                 txdp++, pkt++, nb_pkts--;
    1181                 :            :         }
    1182                 :            : }
    1183                 :            : 
    1184                 :            : static __rte_always_inline uint16_t
    1185                 :            : idpf_singleq_xmit_fixed_burst_vec_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
    1186                 :            :                                          uint16_t nb_pkts)
    1187                 :            : {
    1188                 :            :         struct idpf_tx_queue *txq = tx_queue;
    1189                 :            :         volatile struct idpf_base_tx_desc *txdp;
    1190                 :            :         struct idpf_tx_vec_entry *txep;
    1191                 :            :         uint16_t n, nb_commit, tx_id;
    1192                 :            :         uint64_t flags = IDPF_TX_DESC_CMD_EOP;
    1193                 :            :         uint64_t rs = IDPF_TX_DESC_CMD_RS | flags;
    1194                 :            : 
    1195                 :            :         /* cross rx_thresh boundary is not allowed */
    1196                 :          0 :         nb_pkts = RTE_MIN(nb_pkts, txq->rs_thresh);
    1197                 :            : 
    1198                 :          0 :         if (txq->nb_free < txq->free_thresh)
    1199                 :            :                 idpf_tx_singleq_free_bufs_avx512(txq);
    1200                 :            : 
    1201                 :          0 :         nb_pkts = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts);
    1202                 :            :         nb_commit = nb_pkts;
    1203         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0))
    1204                 :            :                 return 0;
    1205                 :            : 
    1206                 :          0 :         tx_id = txq->tx_tail;
    1207                 :          0 :         txdp = &txq->tx_ring[tx_id];
    1208                 :          0 :         txep = (void *)txq->sw_ring;
    1209                 :          0 :         txep += tx_id;
    1210                 :            : 
    1211                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_free - nb_pkts);
    1212                 :            : 
    1213                 :          0 :         n = (uint16_t)(txq->nb_tx_desc - tx_id);
    1214         [ #  # ]:          0 :         if (nb_commit >= n) {
    1215                 :          0 :                 tx_backlog_entry_avx512(txep, tx_pkts, n);
    1216                 :            : 
    1217         [ #  # ]:          0 :                 idpf_singleq_vtx(txdp, tx_pkts, n - 1, flags);
    1218                 :          0 :                 tx_pkts += (n - 1);
    1219                 :          0 :                 txdp += (n - 1);
    1220                 :            : 
    1221                 :          0 :                 idpf_singleq_vtx1(txdp, *tx_pkts++, rs);
    1222                 :            : 
    1223                 :          0 :                 nb_commit = (uint16_t)(nb_commit - n);
    1224                 :            : 
    1225                 :            :                 tx_id = 0;
    1226                 :          0 :                 txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
    1227                 :            : 
    1228                 :            :                 /* avoid reach the end of ring */
    1229                 :          0 :                 txdp = &txq->tx_ring[tx_id];
    1230                 :          0 :                 txep = (void *)txq->sw_ring;
    1231                 :            :                 txep += tx_id;
    1232                 :            :         }
    1233                 :            : 
    1234                 :          0 :         tx_backlog_entry_avx512(txep, tx_pkts, nb_commit);
    1235                 :            : 
    1236                 :            :         idpf_singleq_vtx(txdp, tx_pkts, nb_commit, flags);
    1237                 :            : 
    1238                 :          0 :         tx_id = (uint16_t)(tx_id + nb_commit);
    1239         [ #  # ]:          0 :         if (tx_id > txq->next_rs) {
    1240                 :          0 :                 txq->tx_ring[txq->next_rs].qw1 |=
    1241                 :            :                         rte_cpu_to_le_64(((uint64_t)IDPF_TX_DESC_CMD_RS) <<
    1242                 :            :                                          IDPF_TXD_QW1_CMD_S);
    1243                 :          0 :                 txq->next_rs =
    1244                 :          0 :                         (uint16_t)(txq->next_rs + txq->rs_thresh);
    1245                 :            :         }
    1246                 :            : 
    1247                 :          0 :         txq->tx_tail = tx_id;
    1248                 :            : 
    1249                 :          0 :         IDPF_PCI_REG_WRITE(txq->qtx_tail, txq->tx_tail);
    1250                 :            : 
    1251                 :          0 :         return nb_pkts;
    1252                 :            : }
    1253                 :            : 
    1254                 :            : static __rte_always_inline uint16_t
    1255                 :            : idpf_singleq_xmit_pkts_vec_avx512_cmn(void *tx_queue, struct rte_mbuf **tx_pkts,
    1256                 :            :                               uint16_t nb_pkts)
    1257                 :            : {
    1258                 :            :         uint16_t nb_tx = 0;
    1259                 :            :         struct idpf_tx_queue *txq = tx_queue;
    1260                 :            : 
    1261         [ #  # ]:          0 :         while (nb_pkts) {
    1262                 :            :                 uint16_t ret, num;
    1263                 :            : 
    1264                 :          0 :                 num = (uint16_t)RTE_MIN(nb_pkts, txq->rs_thresh);
    1265         [ #  # ]:          0 :                 ret = idpf_singleq_xmit_fixed_burst_vec_avx512(tx_queue, &tx_pkts[nb_tx],
    1266                 :            :                                                        num);
    1267                 :          0 :                 nb_tx += ret;
    1268                 :          0 :                 nb_pkts -= ret;
    1269         [ #  # ]:          0 :                 if (ret < num)
    1270                 :            :                         break;
    1271                 :            :         }
    1272                 :            : 
    1273                 :            :         return nb_tx;
    1274                 :            : }
    1275                 :            : 
    1276                 :            : uint16_t
    1277                 :          0 : idpf_dp_singleq_xmit_pkts_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
    1278                 :            :                                  uint16_t nb_pkts)
    1279                 :            : {
    1280                 :          0 :         return idpf_singleq_xmit_pkts_vec_avx512_cmn(tx_queue, tx_pkts, nb_pkts);
    1281                 :            : }
    1282                 :            : 
    1283                 :            : static __rte_always_inline void
    1284                 :            : idpf_splitq_scan_cq_ring(struct idpf_tx_queue *cq)
    1285                 :            : {
    1286                 :            :         struct idpf_splitq_tx_compl_desc *compl_ring;
    1287                 :            :         struct idpf_tx_queue *txq;
    1288                 :            :         uint16_t genid, txq_qid, cq_qid, i;
    1289                 :            :         uint8_t ctype;
    1290                 :            : 
    1291                 :          0 :         cq_qid = cq->tx_tail;
    1292                 :            : 
    1293         [ #  # ]:          0 :         for (i = 0; i < IDPD_TXQ_SCAN_CQ_THRESH; i++) {
    1294         [ #  # ]:          0 :                 if (cq_qid == cq->nb_tx_desc) {
    1295                 :            :                         cq_qid = 0;
    1296                 :          0 :                         cq->expected_gen_id ^= 1;
    1297                 :            :                 }
    1298                 :          0 :                 compl_ring = &cq->compl_ring[cq_qid];
    1299                 :          0 :                 genid = (compl_ring->qid_comptype_gen &
    1300                 :            :                         rte_cpu_to_le_64(IDPF_TXD_COMPLQ_GEN_M)) >> IDPF_TXD_COMPLQ_GEN_S;
    1301         [ #  # ]:          0 :                 if (genid != cq->expected_gen_id)
    1302                 :            :                         break;
    1303                 :          0 :                 ctype = (rte_le_to_cpu_16(compl_ring->qid_comptype_gen) &
    1304                 :          0 :                         IDPF_TXD_COMPLQ_COMPL_TYPE_M) >> IDPF_TXD_COMPLQ_COMPL_TYPE_S;
    1305                 :          0 :                 txq_qid = (rte_le_to_cpu_16(compl_ring->qid_comptype_gen) &
    1306                 :            :                         IDPF_TXD_COMPLQ_QID_M) >> IDPF_TXD_COMPLQ_QID_S;
    1307                 :          0 :                 txq = cq->txqs[txq_qid - cq->tx_start_qid];
    1308                 :          0 :                 txq->ctype[ctype]++;
    1309                 :          0 :                 cq_qid++;
    1310                 :            :         }
    1311                 :            : 
    1312                 :          0 :         cq->tx_tail = cq_qid;
    1313                 :            : }
    1314                 :            : 
    1315                 :            : static __rte_always_inline int
    1316                 :            : idpf_tx_splitq_free_bufs_avx512(struct idpf_tx_queue *txq)
    1317                 :          0 : {
    1318                 :            :         struct idpf_tx_vec_entry *txep;
    1319                 :            :         uint32_t n;
    1320                 :            :         uint32_t i;
    1321                 :            :         int nb_free = 0;
    1322                 :          0 :         struct rte_mbuf *m, *free[txq->rs_thresh];
    1323                 :            : 
    1324                 :          0 :         n = txq->rs_thresh;
    1325                 :            : 
    1326                 :            :          /* first buffer to free from S/W ring is at index
    1327                 :            :           * tx_next_dd - (tx_rs_thresh-1)
    1328                 :            :           */
    1329                 :          0 :         txep = (void *)txq->sw_ring;
    1330                 :          0 :         txep += txq->next_dd - (n - 1);
    1331                 :            : 
    1332   [ #  #  #  # ]:          0 :         if (txq->offloads & IDPF_TX_OFFLOAD_MBUF_FAST_FREE && (n & 31) == 0) {
    1333         [ #  # ]:          0 :                 struct rte_mempool *mp = txep[0].mbuf->pool;
    1334                 :            :                 struct rte_mempool_cache *cache = rte_mempool_default_cache(mp,
    1335                 :            :                                                                 rte_lcore_id());
    1336                 :            :                 void **cache_objs;
    1337                 :            : 
    1338   [ #  #  #  # ]:          0 :                 if (!cache || cache->len == 0)
    1339                 :          0 :                         goto normal;
    1340                 :            : 
    1341                 :          0 :                 cache_objs = &cache->objs[cache->len];
    1342                 :            : 
    1343         [ #  # ]:          0 :                 if (n > RTE_MEMPOOL_CACHE_MAX_SIZE) {
    1344                 :          0 :                         rte_mempool_ops_enqueue_bulk(mp, (void *)txep, n);
    1345                 :          0 :                         goto done;
    1346                 :            :                 }
    1347                 :            : 
    1348                 :            :                 /* The cache follows the following algorithm
    1349                 :            :                  *   1. Add the objects to the cache
    1350                 :            :                  *   2. Anything greater than the cache min value (if it crosses the
    1351                 :            :                  *   cache flush threshold) is flushed to the ring.
    1352                 :            :                  */
    1353                 :            :                 /* Add elements back into the cache */
    1354                 :            :                 uint32_t copied = 0;
    1355                 :            :                 /* n is multiple of 32 */
    1356         [ #  # ]:          0 :                 while (copied < n) {
    1357                 :          0 :                         const __m512i a = _mm512_loadu_si512(&txep[copied]);
    1358                 :          0 :                         const __m512i b = _mm512_loadu_si512(&txep[copied + 8]);
    1359                 :          0 :                         const __m512i c = _mm512_loadu_si512(&txep[copied + 16]);
    1360                 :          0 :                         const __m512i d = _mm512_loadu_si512(&txep[copied + 24]);
    1361                 :            : 
    1362                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied], a);
    1363                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied + 8], b);
    1364                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied + 16], c);
    1365                 :          0 :                         _mm512_storeu_si512(&cache_objs[copied + 24], d);
    1366                 :          0 :                         copied += 32;
    1367                 :            :                 }
    1368                 :          0 :                 cache->len += n;
    1369                 :            : 
    1370         [ #  # ]:          0 :                 if (cache->len >= cache->flushthresh) {
    1371                 :          0 :                         rte_mempool_ops_enqueue_bulk(mp,
    1372                 :          0 :                                                      &cache->objs[cache->size],
    1373                 :          0 :                                                      cache->len - cache->size);
    1374                 :          0 :                         cache->len = cache->size;
    1375                 :            :                 }
    1376                 :          0 :                 goto done;
    1377                 :            :         }
    1378                 :            : 
    1379                 :          0 : normal:
    1380         [ #  # ]:          0 :         m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
    1381         [ #  # ]:          0 :         if (likely(m)) {
    1382                 :          0 :                 free[0] = m;
    1383                 :            :                 nb_free = 1;
    1384         [ #  # ]:          0 :                 for (i = 1; i < n; i++) {
    1385         [ #  # ]:          0 :                         m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
    1386         [ #  # ]:          0 :                         if (likely(m)) {
    1387         [ #  # ]:          0 :                                 if (likely(m->pool == free[0]->pool)) {
    1388                 :          0 :                                         free[nb_free++] = m;
    1389                 :            :                                 } else {
    1390         [ #  # ]:          0 :                                         rte_mempool_put_bulk(free[0]->pool,
    1391                 :            :                                                              (void *)free,
    1392                 :            :                                                              nb_free);
    1393                 :          0 :                                         free[0] = m;
    1394                 :            :                                         nb_free = 1;
    1395                 :            :                                 }
    1396                 :            :                         }
    1397                 :            :                 }
    1398         [ #  # ]:          0 :                 rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
    1399                 :            :         } else {
    1400         [ #  # ]:          0 :                 for (i = 1; i < n; i++) {
    1401         [ #  # ]:          0 :                         m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
    1402         [ #  # ]:          0 :                         if (m)
    1403         [ #  # ]:          0 :                                 rte_mempool_put(m->pool, m);
    1404                 :            :                 }
    1405                 :            :         }
    1406                 :            : 
    1407                 :          0 : done:
    1408                 :            :         /* buffers were freed, update counters */
    1409                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_free + txq->rs_thresh);
    1410                 :          0 :         txq->next_dd = (uint16_t)(txq->next_dd + txq->rs_thresh);
    1411         [ #  # ]:          0 :         if (txq->next_dd >= txq->nb_tx_desc)
    1412                 :          0 :                 txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
    1413                 :          0 :         txq->ctype[IDPF_TXD_COMPLT_RS] -= txq->rs_thresh;
    1414                 :            : 
    1415                 :          0 :         return txq->rs_thresh;
    1416                 :            : }
    1417                 :            : 
    1418                 :            : #define IDPF_TXD_FLEX_QW1_TX_BUF_SZ_S   48
    1419                 :            : 
    1420                 :            : static __rte_always_inline void
    1421                 :            : idpf_splitq_vtx1(volatile struct idpf_flex_tx_sched_desc *txdp,
    1422                 :            :           struct rte_mbuf *pkt, uint64_t flags)
    1423                 :            : {
    1424                 :          0 :         uint64_t high_qw =
    1425                 :            :                 (IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE |
    1426                 :            :                  ((uint64_t)flags) |
    1427                 :          0 :                  ((uint64_t)pkt->data_len << IDPF_TXD_FLEX_QW1_TX_BUF_SZ_S));
    1428                 :            : 
    1429                 :          0 :         __m128i descriptor = _mm_set_epi64x(high_qw,
    1430                 :          0 :                                             pkt->buf_iova + pkt->data_off);
    1431                 :            :         _mm_storeu_si128((__m128i *)txdp, descriptor);
    1432                 :            : }
    1433                 :            : 
    1434                 :            : static __rte_always_inline void
    1435                 :            : idpf_splitq_vtx(volatile struct idpf_flex_tx_sched_desc *txdp,
    1436                 :            :          struct rte_mbuf **pkt, uint16_t nb_pkts,  uint64_t flags)
    1437                 :            : {
    1438                 :            :         const uint64_t hi_qw_tmpl = (IDPF_TX_DESC_DTYPE_FLEX_FLOW_SCHE  |
    1439                 :            :                         ((uint64_t)flags));
    1440                 :            : 
    1441                 :            :         /* if unaligned on 32-bit boundary, do one to align */
    1442   [ #  #  #  #  :          0 :         if (((uintptr_t)txdp & 0x1F) != 0 && nb_pkts != 0) {
                   #  # ]
    1443                 :          0 :                 idpf_splitq_vtx1(txdp, *pkt, flags);
    1444                 :          0 :                 nb_pkts--, txdp++, pkt++;
    1445                 :            :         }
    1446                 :            : 
    1447                 :            :         /* do 4 at a time while possible, in bursts */
    1448   [ #  #  #  # ]:          0 :         for (; nb_pkts > 3; txdp += 4, pkt += 4, nb_pkts -= 4) {
    1449                 :          0 :                 uint64_t hi_qw3 =
    1450                 :            :                         hi_qw_tmpl |
    1451                 :          0 :                         ((uint64_t)pkt[3]->data_len <<
    1452                 :            :                          IDPF_TXD_FLEX_QW1_TX_BUF_SZ_S);
    1453                 :          0 :                 uint64_t hi_qw2 =
    1454                 :            :                         hi_qw_tmpl |
    1455                 :          0 :                         ((uint64_t)pkt[2]->data_len <<
    1456                 :            :                          IDPF_TXD_FLEX_QW1_TX_BUF_SZ_S);
    1457                 :          0 :                 uint64_t hi_qw1 =
    1458                 :            :                         hi_qw_tmpl |
    1459                 :          0 :                         ((uint64_t)pkt[1]->data_len <<
    1460                 :            :                          IDPF_TXD_FLEX_QW1_TX_BUF_SZ_S);
    1461                 :          0 :                 uint64_t hi_qw0 =
    1462                 :            :                         hi_qw_tmpl |
    1463                 :          0 :                         ((uint64_t)pkt[0]->data_len <<
    1464                 :            :                          IDPF_TXD_FLEX_QW1_TX_BUF_SZ_S);
    1465                 :            : 
    1466                 :            :                 __m512i desc0_3 =
    1467                 :          0 :                         _mm512_set_epi64
    1468                 :            :                                 (hi_qw3,
    1469                 :          0 :                                  pkt[3]->buf_iova + pkt[3]->data_off,
    1470                 :            :                                  hi_qw2,
    1471                 :          0 :                                  pkt[2]->buf_iova + pkt[2]->data_off,
    1472                 :            :                                  hi_qw1,
    1473                 :          0 :                                  pkt[1]->buf_iova + pkt[1]->data_off,
    1474                 :            :                                  hi_qw0,
    1475                 :          0 :                                  pkt[0]->buf_iova + pkt[0]->data_off);
    1476                 :            :                 _mm512_storeu_si512((void *)txdp, desc0_3);
    1477                 :            :         }
    1478                 :            : 
    1479                 :            :         /* do any last ones */
    1480   [ #  #  #  # ]:          0 :         while (nb_pkts) {
    1481                 :          0 :                 idpf_splitq_vtx1(txdp, *pkt, flags);
    1482                 :          0 :                 txdp++, pkt++, nb_pkts--;
    1483                 :            :         }
    1484                 :            : }
    1485                 :            : 
    1486                 :            : static __rte_always_inline uint16_t
    1487                 :            : idpf_splitq_xmit_fixed_burst_vec_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
    1488                 :            :                                         uint16_t nb_pkts)
    1489                 :            : {
    1490                 :            :         struct idpf_tx_queue *txq = (struct idpf_tx_queue *)tx_queue;
    1491                 :            :         volatile struct idpf_flex_tx_sched_desc *txdp;
    1492                 :            :         struct idpf_tx_vec_entry *txep;
    1493                 :            :         uint16_t n, nb_commit, tx_id;
    1494                 :            :         /* bit2 is reserved and must be set to 1 according to Spec */
    1495                 :            :         uint64_t cmd_dtype = IDPF_TXD_FLEX_FLOW_CMD_EOP;
    1496                 :            : 
    1497                 :          0 :         tx_id = txq->tx_tail;
    1498                 :            : 
    1499                 :            :         /* cross rx_thresh boundary is not allowed */
    1500                 :          0 :         nb_pkts = RTE_MIN(nb_pkts, txq->rs_thresh);
    1501                 :            : 
    1502                 :          0 :         nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts);
    1503                 :          0 :         if (unlikely(nb_pkts == 0))
    1504                 :            :                 return 0;
    1505                 :            : 
    1506                 :            :         tx_id = txq->tx_tail;
    1507                 :          0 :         txdp = &txq->desc_ring[tx_id];
    1508                 :          0 :         txep = (void *)txq->sw_ring;
    1509                 :          0 :         txep += tx_id;
    1510                 :            : 
    1511                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_free - nb_pkts);
    1512                 :            : 
    1513                 :          0 :         n = (uint16_t)(txq->nb_tx_desc - tx_id);
    1514         [ #  # ]:          0 :         if (nb_commit >= n) {
    1515                 :          0 :                 tx_backlog_entry_avx512(txep, tx_pkts, n);
    1516                 :            : 
    1517         [ #  # ]:          0 :                 idpf_splitq_vtx((void *)txdp, tx_pkts, n - 1, cmd_dtype);
    1518                 :          0 :                 tx_pkts += (n - 1);
    1519                 :          0 :                 txdp += (n - 1);
    1520                 :            : 
    1521                 :          0 :                 idpf_splitq_vtx1((void *)txdp, *tx_pkts++, cmd_dtype);
    1522                 :            : 
    1523                 :          0 :                 nb_commit = (uint16_t)(nb_commit - n);
    1524                 :            : 
    1525                 :            :                 tx_id = 0;
    1526                 :          0 :                 txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
    1527                 :            : 
    1528                 :            :                 /* avoid reach the end of ring */
    1529                 :          0 :                 txdp = &txq->desc_ring[tx_id];
    1530                 :          0 :                 txep = (void *)txq->sw_ring;
    1531                 :            :                 txep += tx_id;
    1532                 :            :         }
    1533                 :            : 
    1534                 :          0 :         tx_backlog_entry_avx512(txep, tx_pkts, nb_commit);
    1535                 :            : 
    1536                 :            :         idpf_splitq_vtx((void *)txdp, tx_pkts, nb_commit, cmd_dtype);
    1537                 :            : 
    1538                 :          0 :         tx_id = (uint16_t)(tx_id + nb_commit);
    1539         [ #  # ]:          0 :         if (tx_id > txq->next_rs)
    1540                 :          0 :                 txq->next_rs =
    1541                 :          0 :                         (uint16_t)(txq->next_rs + txq->rs_thresh);
    1542                 :            : 
    1543                 :          0 :         txq->tx_tail = tx_id;
    1544                 :            : 
    1545                 :          0 :         IDPF_PCI_REG_WRITE(txq->qtx_tail, txq->tx_tail);
    1546                 :            : 
    1547                 :          0 :         return nb_pkts;
    1548                 :            : }
    1549                 :            : 
    1550                 :            : static __rte_always_inline uint16_t
    1551                 :            : idpf_splitq_xmit_pkts_vec_avx512_cmn(void *tx_queue, struct rte_mbuf **tx_pkts,
    1552                 :            :                                      uint16_t nb_pkts)
    1553                 :            : {
    1554                 :            :         struct idpf_tx_queue *txq = (struct idpf_tx_queue *)tx_queue;
    1555                 :            :         uint16_t nb_tx = 0;
    1556                 :            : 
    1557         [ #  # ]:          0 :         while (nb_pkts) {
    1558                 :            :                 uint16_t ret, num;
    1559                 :            : 
    1560                 :          0 :                 idpf_splitq_scan_cq_ring(txq->complq);
    1561                 :            : 
    1562         [ #  # ]:          0 :                 if (txq->ctype[IDPF_TXD_COMPLT_RS] > txq->free_thresh)
    1563                 :            :                         idpf_tx_splitq_free_bufs_avx512(txq);
    1564                 :            : 
    1565                 :          0 :                 num = (uint16_t)RTE_MIN(nb_pkts, txq->rs_thresh);
    1566                 :          0 :                 ret = idpf_splitq_xmit_fixed_burst_vec_avx512(tx_queue,
    1567         [ #  # ]:          0 :                                                               &tx_pkts[nb_tx],
    1568                 :            :                                                               num);
    1569                 :          0 :                 nb_tx += ret;
    1570                 :          0 :                 nb_pkts -= ret;
    1571         [ #  # ]:          0 :                 if (ret < num)
    1572                 :            :                         break;
    1573                 :            :         }
    1574                 :            : 
    1575                 :            :         return nb_tx;
    1576                 :            : }
    1577                 :            : 
    1578                 :            : uint16_t
    1579                 :          0 : idpf_dp_splitq_xmit_pkts_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
    1580                 :            :                                 uint16_t nb_pkts)
    1581                 :            : {
    1582                 :          0 :         return idpf_splitq_xmit_pkts_vec_avx512_cmn(tx_queue, tx_pkts, nb_pkts);
    1583                 :            : }
    1584                 :            : 
    1585                 :            : static inline void
    1586                 :          0 : idpf_tx_release_mbufs_avx512(struct idpf_tx_queue *txq)
    1587                 :            : {
    1588                 :            :         unsigned int i;
    1589                 :          0 :         const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1);
    1590                 :          0 :         struct idpf_tx_vec_entry *swr = (void *)txq->sw_ring;
    1591                 :            : 
    1592   [ #  #  #  # ]:          0 :         if (txq->sw_ring == NULL || txq->nb_free == max_desc)
    1593                 :            :                 return;
    1594                 :            : 
    1595                 :          0 :         i = txq->next_dd - txq->rs_thresh + 1;
    1596         [ #  # ]:          0 :         if (txq->tx_tail < i) {
    1597         [ #  # ]:          0 :                 for (; i < txq->nb_tx_desc; i++) {
    1598                 :          0 :                         rte_pktmbuf_free_seg(swr[i].mbuf);
    1599                 :          0 :                         swr[i].mbuf = NULL;
    1600                 :            :                 }
    1601                 :            :                 i = 0;
    1602                 :            :         }
    1603         [ #  # ]:          0 :         for (; i < txq->tx_tail; i++) {
    1604                 :          0 :                 rte_pktmbuf_free_seg(swr[i].mbuf);
    1605                 :          0 :                 swr[i].mbuf = NULL;
    1606                 :            :         }
    1607                 :            : }
    1608                 :            : 
    1609                 :            : static const struct idpf_txq_ops avx512_tx_vec_ops = {
    1610                 :            :         .release_mbufs = idpf_tx_release_mbufs_avx512,
    1611                 :            : };
    1612                 :            : 
    1613                 :            : int __rte_cold
    1614                 :          0 : idpf_qc_tx_vec_avx512_setup(struct idpf_tx_queue *txq)
    1615                 :            : {
    1616         [ #  # ]:          0 :         if (!txq)
    1617                 :            :                 return 0;
    1618                 :            : 
    1619                 :          0 :         txq->ops = &avx512_tx_vec_ops;
    1620                 :          0 :         return 0;
    1621                 :            : }

Generated by: LCOV version 1.14