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
