This commit adds IPv6 profile specific hashing which
uses fixed offsets into the packet to improve hashing
perforamnce.

Hash value is autovalidated by MFEX autovalidator.

Signed-off-by: Kumar Amber <[email protected]>
Signed-off-by: Harry van Haaren <[email protected]>
Co-authored-by: Harry van Haaren <[email protected]>

---
v4:
- Use pre-defined hash length values
v2:
- Fix check-patch sign-offs
---
 NEWS                             |  1 +
 lib/dpif-netdev-extract-avx512.c | 61 ++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/NEWS b/NEWS
index a99c4675b..47b34317f 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@ Post-v2.16.0
      * Add AVX512 optimized profiles to miniflow extract for VLAN/IPv6/UDP
        and VLAN/IPv6/TCP.
      * Add IPv4 profile based 5tuple hashing optimizations.
+     * Add IPv6 profile based 5tuple hashing optimizations.
 
 
 v2.16.0 - 16 Aug 2021
diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c
index 1088744d0..db2650e05 100644
--- a/lib/dpif-netdev-extract-avx512.c
+++ b/lib/dpif-netdev-extract-avx512.c
@@ -361,6 +361,12 @@ enum MFEX_PROFILES {
 #define HASH_DT1Q_IPV4 \
     30, 34, 27, 38, 0, 0
 
+#define HASH_IPV6 \
+    22, 30, 38, 46, 20, 54
+
+#define HASH_DT1Q_IPV6 \
+    26, 34, 42, 50, 24, 58
+
 /* Static const instances of profiles. These are compile-time constants,
  * and are specialized into individual miniflow-extract functions.
  * NOTE: Order of the fields is significant, any change in the order must be
@@ -456,6 +462,9 @@ static const struct mfex_profile 
mfex_profiles[PROFILE_COUNT] =
             0, UINT16_MAX, 14, 54,
         },
         .dp_pkt_min_size = 54,
+
+        .hash_pkt_offs = { HASH_IPV6 },
+        .hash_len = 96,
     },
 
     [PROFILE_ETH_IPV6_TCP] = {
@@ -470,6 +479,9 @@ static const struct mfex_profile 
mfex_profiles[PROFILE_COUNT] =
             0, UINT16_MAX, 14, 54,
         },
         .dp_pkt_min_size = 54,
+
+        .hash_pkt_offs = { HASH_IPV6 },
+        .hash_len = 104,
     },
 
     [PROFILE_ETH_VLAN_IPV6_TCP] = {
@@ -486,6 +498,9 @@ static const struct mfex_profile 
mfex_profiles[PROFILE_COUNT] =
             14, UINT16_MAX, 18, 58,
         },
         .dp_pkt_min_size = 66,
+
+        .hash_pkt_offs = { HASH_DT1Q_IPV6 },
+        .hash_len = 112,
     },
 
     [PROFILE_ETH_VLAN_IPV6_UDP] = {
@@ -502,6 +517,9 @@ static const struct mfex_profile 
mfex_profiles[PROFILE_COUNT] =
             14, UINT16_MAX, 18, 58,
         },
         .dp_pkt_min_size = 66,
+
+        .hash_pkt_offs = { HASH_DT1Q_IPV6 },
+        .hash_len = 104,
     },
 };
 
@@ -580,6 +598,37 @@ mfex_5tuple_hash_ipv4(struct dp_packet *packet, const 
uint8_t *pkt,
     }
 }
 
+static inline void
+mfex_5tuple_hash_ipv6(struct dp_packet *packet, const uint8_t *pkt,
+                      struct netdev_flow_key *key,
+                      const uint8_t *pkt_offsets)
+{
+    if (!dp_packet_rss_valid(packet)) {
+        uint32_t hash = 0;
+        void *ipv6_src_lo = (void *) &pkt[pkt_offsets[0]];
+        void *ipv6_src_hi = (void *) &pkt[pkt_offsets[1]];
+        void *ipv6_dst_lo = (void *) &pkt[pkt_offsets[2]];
+        void *ipv6_dst_hi = (void *) &pkt[pkt_offsets[3]];
+        void *ports_l4 = (void *) &pkt[pkt_offsets[5]];
+
+        /* IPv6 Src and Dst. */
+        hash = hash_add64(hash, *(uint64_t *) ipv6_src_lo);
+        hash = hash_add64(hash, *(uint64_t *) ipv6_src_hi);
+        hash = hash_add64(hash, *(uint64_t *) ipv6_dst_lo);
+        hash = hash_add64(hash, *(uint64_t *) ipv6_dst_hi);
+        /* IPv6 proto. */
+        hash = hash_add(hash, pkt[pkt_offsets[4]]);
+        /* L4 ports. */
+        hash = hash_add(hash, *(uint32_t *) ports_l4);
+        hash = hash_finish(hash, 42);
+
+        dp_packet_set_rss_hash(packet, hash);
+        key->hash = hash;
+    } else {
+        key->hash = dp_packet_get_rss_hash(packet);
+    }
+}
+
 /* Protocol specific helper functions, for calculating offsets/lenghts. */
 static int32_t
 mfex_ipv4_set_l2_pad_size(struct dp_packet *pkt, struct ip_header *nh,
@@ -777,6 +826,9 @@ mfex_avx512_process(struct dp_packet_batch *packets,
                 /* Process UDP header. */
                 mfex_handle_ipv6_l4((void *)&pkt[54], &blocks[9]);
 
+                mfex_5tuple_hash_ipv6(packet, pkt, &keys[i],
+                                      profile->hash_pkt_offs);
+                keys[i].len = profile->hash_len;
             } break;
 
         case PROFILE_ETH_IPV6_TCP: {
@@ -794,6 +846,9 @@ mfex_avx512_process(struct dp_packet_batch *packets,
                 const struct tcp_header *tcp = (void *)&pkt[54];
                 mfex_handle_tcp_flags(tcp, &blocks[9]);
 
+                mfex_5tuple_hash_ipv6(packet, pkt, &keys[i],
+                                      profile->hash_pkt_offs);
+                keys[i].len = profile->hash_len;
             } break;
 
         case PROFILE_ETH_VLAN_IPV6_TCP: {
@@ -814,6 +869,9 @@ mfex_avx512_process(struct dp_packet_batch *packets,
                 const struct tcp_header *tcp = (void *)&pkt[58];
                 mfex_handle_tcp_flags(tcp, &blocks[10]);
 
+                mfex_5tuple_hash_ipv6(packet, pkt, &keys[i],
+                                      profile->hash_pkt_offs);
+                keys[i].len = profile->hash_len;
             } break;
 
         case PROFILE_ETH_VLAN_IPV6_UDP: {
@@ -832,6 +890,9 @@ mfex_avx512_process(struct dp_packet_batch *packets,
                 /* Process UDP header. */
                 mfex_handle_ipv6_l4((void *)&pkt[58], &blocks[10]);
 
+                mfex_5tuple_hash_ipv6(packet, pkt, &keys[i],
+                                      profile->hash_pkt_offs);
+                keys[i].len = profile->hash_len;
             } break;
         default:
             break;
-- 
2.25.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to