LCOV - code coverage report
Current view: top level - lib/node - ip4_lookup_sse.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 106 0.0 %
Date: 2025-02-01 18:54:23 Functions: 0 1 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 46 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2020 Marvell International Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #ifndef __INCLUDE_IP4_LOOKUP_SSE_H__
       6                 :            : #define __INCLUDE_IP4_LOOKUP_SSE_H__
       7                 :            : 
       8                 :            : /* X86 SSE */
       9                 :            : static uint16_t
      10                 :          0 : ip4_lookup_node_process_vec(struct rte_graph *graph, struct rte_node *node,
      11                 :            :                         void **objs, uint16_t nb_objs)
      12                 :            : {
      13                 :            :         struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3, **pkts;
      14                 :          0 :         struct rte_lpm *lpm = IP4_LOOKUP_NODE_LPM(node->ctx);
      15                 :          0 :         const int dyn = IP4_LOOKUP_NODE_PRIV1_OFF(node->ctx);
      16                 :            :         rte_edge_t next0, next1, next2, next3, next_index;
      17                 :            :         struct rte_ipv4_hdr *ipv4_hdr;
      18                 :            :         uint32_t ip0, ip1, ip2, ip3;
      19                 :            :         void **to_next, **from;
      20                 :            :         uint16_t last_spec = 0;
      21                 :            :         uint16_t n_left_from;
      22                 :            :         uint16_t held = 0;
      23                 :            :         uint32_t drop_nh;
      24                 :            :         rte_xmm_t dst;
      25                 :            :         __m128i dip; /* SSE register */
      26                 :            :         int rc, i;
      27                 :            : 
      28                 :            :         /* Speculative next */
      29                 :            :         next_index = RTE_NODE_IP4_LOOKUP_NEXT_REWRITE;
      30                 :            :         /* Drop node */
      31                 :            :         drop_nh = ((uint32_t)RTE_NODE_IP4_LOOKUP_NEXT_PKT_DROP) << 16;
      32                 :            : 
      33                 :            :         pkts = (struct rte_mbuf **)objs;
      34                 :            :         from = objs;
      35                 :            :         n_left_from = nb_objs;
      36                 :            : 
      37         [ #  # ]:          0 :         if (n_left_from >= 4) {
      38         [ #  # ]:          0 :                 for (i = 0; i < 4; i++)
      39                 :          0 :                         rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[i], void *,
      40                 :            :                                                 sizeof(struct rte_ether_hdr)));
      41                 :            :         }
      42                 :            : 
      43                 :            :         /* Get stream for the speculated next node */
      44                 :          0 :         to_next = rte_node_next_stream_get(graph, node, next_index, nb_objs);
      45         [ #  # ]:          0 :         while (n_left_from >= 4) {
      46                 :            :                 /* Prefetch next-next mbufs */
      47         [ #  # ]:          0 :                 if (likely(n_left_from > 11)) {
      48                 :          0 :                         rte_prefetch0(pkts[8]);
      49                 :          0 :                         rte_prefetch0(pkts[9]);
      50                 :          0 :                         rte_prefetch0(pkts[10]);
      51                 :          0 :                         rte_prefetch0(pkts[11]);
      52                 :            :                 }
      53                 :            : 
      54                 :            :                 /* Prefetch next mbuf data */
      55         [ #  # ]:          0 :                 if (likely(n_left_from > 7)) {
      56                 :          0 :                         rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[4], void *,
      57                 :            :                                                 sizeof(struct rte_ether_hdr)));
      58                 :          0 :                         rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[5], void *,
      59                 :            :                                                 sizeof(struct rte_ether_hdr)));
      60                 :          0 :                         rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[6], void *,
      61                 :            :                                                 sizeof(struct rte_ether_hdr)));
      62                 :          0 :                         rte_prefetch0(rte_pktmbuf_mtod_offset(pkts[7], void *,
      63                 :            :                                                 sizeof(struct rte_ether_hdr)));
      64                 :            :                 }
      65                 :            : 
      66                 :          0 :                 mbuf0 = pkts[0];
      67                 :          0 :                 mbuf1 = pkts[1];
      68                 :          0 :                 mbuf2 = pkts[2];
      69                 :          0 :                 mbuf3 = pkts[3];
      70                 :            : 
      71                 :          0 :                 pkts += 4;
      72                 :          0 :                 n_left_from -= 4;
      73                 :            : 
      74                 :            :                 /* Extract DIP of mbuf0 */
      75                 :          0 :                 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf0, struct rte_ipv4_hdr *,
      76                 :            :                                                 sizeof(struct rte_ether_hdr));
      77                 :          0 :                 ip0 = ipv4_hdr->dst_addr;
      78                 :            :                 /* Extract cksum, ttl as ipv4 hdr is in cache */
      79                 :          0 :                 node_mbuf_priv1(mbuf0, dyn)->cksum = ipv4_hdr->hdr_checksum;
      80                 :          0 :                 node_mbuf_priv1(mbuf0, dyn)->ttl = ipv4_hdr->time_to_live;
      81                 :            : 
      82                 :            :                 /* Extract DIP of mbuf1 */
      83                 :          0 :                 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf1, struct rte_ipv4_hdr *,
      84                 :            :                                                 sizeof(struct rte_ether_hdr));
      85                 :          0 :                 ip1 = ipv4_hdr->dst_addr;
      86                 :            :                 /* Extract cksum, ttl as ipv4 hdr is in cache */
      87                 :          0 :                 node_mbuf_priv1(mbuf1, dyn)->cksum = ipv4_hdr->hdr_checksum;
      88                 :          0 :                 node_mbuf_priv1(mbuf1, dyn)->ttl = ipv4_hdr->time_to_live;
      89                 :            : 
      90                 :            :                 /* Extract DIP of mbuf2 */
      91                 :          0 :                 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf2, struct rte_ipv4_hdr *,
      92                 :            :                                                 sizeof(struct rte_ether_hdr));
      93                 :          0 :                 ip2 = ipv4_hdr->dst_addr;
      94                 :            :                 /* Extract cksum, ttl as ipv4 hdr is in cache */
      95                 :          0 :                 node_mbuf_priv1(mbuf2, dyn)->cksum = ipv4_hdr->hdr_checksum;
      96                 :          0 :                 node_mbuf_priv1(mbuf2, dyn)->ttl = ipv4_hdr->time_to_live;
      97                 :            : 
      98                 :            :                 /* Extract DIP of mbuf3 */
      99                 :          0 :                 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf3, struct rte_ipv4_hdr *,
     100                 :            :                                                 sizeof(struct rte_ether_hdr));
     101                 :          0 :                 ip3 = ipv4_hdr->dst_addr;
     102                 :            : 
     103                 :            :                 /* Prepare for lookup x4 */
     104                 :          0 :                 dip = _mm_set_epi32(ip3, ip2, ip1, ip0);
     105                 :            : 
     106                 :            :                 /* Byte swap 4 IPV4 addresses. */
     107                 :            :                 const __m128i bswap_mask = _mm_set_epi8(
     108                 :            :                         12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3);
     109                 :            :                 dip = _mm_shuffle_epi8(dip, bswap_mask);
     110                 :            : 
     111                 :            :                 /* Extract cksum, ttl as ipv4 hdr is in cache */
     112                 :          0 :                 node_mbuf_priv1(mbuf3, dyn)->cksum = ipv4_hdr->hdr_checksum;
     113                 :          0 :                 node_mbuf_priv1(mbuf3, dyn)->ttl = ipv4_hdr->time_to_live;
     114                 :            : 
     115                 :            :                 /* Perform LPM lookup to get NH and next node */
     116                 :          0 :                 rte_lpm_lookupx4(lpm, dip, dst.u32, drop_nh);
     117                 :            : 
     118         [ #  # ]:          0 :                 NODE_INCREMENT_XSTAT_ID(node, 0, dst.u16[1] == (drop_nh >> 16), 1);
     119         [ #  # ]:          0 :                 NODE_INCREMENT_XSTAT_ID(node, 0, dst.u16[3] == (drop_nh >> 16), 1);
     120         [ #  # ]:          0 :                 NODE_INCREMENT_XSTAT_ID(node, 0, dst.u16[5] == (drop_nh >> 16), 1);
     121         [ #  # ]:          0 :                 NODE_INCREMENT_XSTAT_ID(node, 0, dst.u16[7] == (drop_nh >> 16), 1);
     122                 :            : 
     123                 :            :                 /* Extract next node id and NH */
     124                 :          0 :                 node_mbuf_priv1(mbuf0, dyn)->nh = dst.u32[0] & 0xFFFF;
     125                 :          0 :                 next0 = (dst.u32[0] >> 16);
     126                 :            : 
     127                 :          0 :                 node_mbuf_priv1(mbuf1, dyn)->nh = dst.u32[1] & 0xFFFF;
     128                 :          0 :                 next1 = (dst.u32[1] >> 16);
     129                 :            : 
     130                 :          0 :                 node_mbuf_priv1(mbuf2, dyn)->nh = dst.u32[2] & 0xFFFF;
     131                 :          0 :                 next2 = (dst.u32[2] >> 16);
     132                 :            : 
     133                 :          0 :                 node_mbuf_priv1(mbuf3, dyn)->nh = dst.u32[3] & 0xFFFF;
     134                 :          0 :                 next3 = (dst.u32[3] >> 16);
     135                 :            : 
     136                 :            :                 /* Enqueue four to next node */
     137                 :          0 :                 rte_edge_t fix_spec =
     138                 :            :                         (next_index ^ next0) | (next_index ^ next1) |
     139                 :            :                         (next_index ^ next2) | (next_index ^ next3);
     140                 :            : 
     141         [ #  # ]:          0 :                 if (unlikely(fix_spec)) {
     142                 :            :                         /* Copy things successfully speculated till now */
     143         [ #  # ]:          0 :                         rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
     144                 :          0 :                         from += last_spec;
     145                 :          0 :                         to_next += last_spec;
     146                 :          0 :                         held += last_spec;
     147                 :            :                         last_spec = 0;
     148                 :            : 
     149                 :            :                         /* Next0 */
     150         [ #  # ]:          0 :                         if (next_index == next0) {
     151                 :          0 :                                 to_next[0] = from[0];
     152                 :          0 :                                 to_next++;
     153                 :          0 :                                 held++;
     154                 :            :                         } else {
     155                 :          0 :                                 rte_node_enqueue_x1(graph, node, next0,
     156                 :            :                                                     from[0]);
     157                 :            :                         }
     158                 :            : 
     159                 :            :                         /* Next1 */
     160         [ #  # ]:          0 :                         if (next_index == next1) {
     161                 :          0 :                                 to_next[0] = from[1];
     162                 :          0 :                                 to_next++;
     163                 :          0 :                                 held++;
     164                 :            :                         } else {
     165                 :          0 :                                 rte_node_enqueue_x1(graph, node, next1,
     166                 :            :                                                     from[1]);
     167                 :            :                         }
     168                 :            : 
     169                 :            :                         /* Next2 */
     170         [ #  # ]:          0 :                         if (next_index == next2) {
     171                 :          0 :                                 to_next[0] = from[2];
     172                 :          0 :                                 to_next++;
     173                 :          0 :                                 held++;
     174                 :            :                         } else {
     175                 :          0 :                                 rte_node_enqueue_x1(graph, node, next2,
     176                 :            :                                                     from[2]);
     177                 :            :                         }
     178                 :            : 
     179                 :            :                         /* Next3 */
     180         [ #  # ]:          0 :                         if (next_index == next3) {
     181                 :          0 :                                 to_next[0] = from[3];
     182                 :          0 :                                 to_next++;
     183                 :          0 :                                 held++;
     184                 :            :                         } else {
     185                 :          0 :                                 rte_node_enqueue_x1(graph, node, next3,
     186                 :            :                                                     from[3]);
     187                 :            :                         }
     188                 :            : 
     189                 :          0 :                         from += 4;
     190                 :            : 
     191                 :            :                 } else {
     192                 :          0 :                         last_spec += 4;
     193                 :            :                 }
     194                 :            :         }
     195                 :            : 
     196         [ #  # ]:          0 :         while (n_left_from > 0) {
     197                 :            :                 uint32_t next_hop;
     198                 :            : 
     199                 :          0 :                 mbuf0 = pkts[0];
     200                 :            : 
     201                 :          0 :                 pkts += 1;
     202                 :          0 :                 n_left_from -= 1;
     203                 :            : 
     204                 :            :                 /* Extract DIP of mbuf0 */
     205                 :          0 :                 ipv4_hdr = rte_pktmbuf_mtod_offset(mbuf0, struct rte_ipv4_hdr *,
     206                 :            :                                                 sizeof(struct rte_ether_hdr));
     207                 :            :                 /* Extract cksum, ttl as ipv4 hdr is in cache */
     208         [ #  # ]:          0 :                 node_mbuf_priv1(mbuf0, dyn)->cksum = ipv4_hdr->hdr_checksum;
     209                 :          0 :                 node_mbuf_priv1(mbuf0, dyn)->ttl = ipv4_hdr->time_to_live;
     210                 :            : 
     211         [ #  # ]:          0 :                 rc = rte_lpm_lookup(lpm, rte_be_to_cpu_32(ipv4_hdr->dst_addr),
     212                 :            :                                     &next_hop);
     213                 :            :                 next_hop = (rc == 0) ? next_hop : drop_nh;
     214         [ #  # ]:          0 :                 NODE_INCREMENT_XSTAT_ID(node, 0, rc != 0, 1);
     215                 :            : 
     216                 :          0 :                 node_mbuf_priv1(mbuf0, dyn)->nh = next_hop & 0xFFFF;
     217                 :          0 :                 next0 = (next_hop >> 16);
     218                 :            : 
     219         [ #  # ]:          0 :                 if (unlikely(next_index ^ next0)) {
     220                 :            :                         /* Copy things successfully speculated till now */
     221         [ #  # ]:          0 :                         rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
     222                 :          0 :                         from += last_spec;
     223                 :          0 :                         to_next += last_spec;
     224                 :          0 :                         held += last_spec;
     225                 :            :                         last_spec = 0;
     226                 :            : 
     227                 :          0 :                         rte_node_enqueue_x1(graph, node, next0, from[0]);
     228                 :          0 :                         from += 1;
     229                 :            :                 } else {
     230                 :          0 :                         last_spec += 1;
     231                 :            :                 }
     232                 :            :         }
     233                 :            : 
     234                 :            :         /* !!! Home run !!! */
     235         [ #  # ]:          0 :         if (likely(last_spec == nb_objs)) {
     236                 :          0 :                 rte_node_next_stream_move(graph, node, next_index);
     237                 :          0 :                 return nb_objs;
     238                 :            :         }
     239                 :            : 
     240                 :          0 :         held += last_spec;
     241                 :            :         /* Copy things successfully speculated till now */
     242         [ #  # ]:          0 :         rte_memcpy(to_next, from, last_spec * sizeof(from[0]));
     243                 :            :         rte_node_next_stream_put(graph, node, next_index, held);
     244                 :            : 
     245                 :            :         return nb_objs;
     246                 :            : }
     247                 :            : 
     248                 :            : #endif /* __INCLUDE_IP4_LOOKUP_SSE_H__ */

Generated by: LCOV version 1.14