This commit adds IPv4 profile specific hashing which uses fixed offsets into the packet to improve hashing perforamnce.
Signed-off-by: Kumar Amber <kumar.am...@intel.com> Signed-off-by: Harry van Haaren <harry.van.haa...@intel.com> Co-authored-by: Harry van Haaren <harry.van.haa...@intel.com> --- v4: - Use pre-defined hash length values. v3: - Fix check-patch sign-offs. --- --- NEWS | 1 + lib/dpif-netdev-extract-avx512.c | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/NEWS b/NEWS index b4719f16e..1bfced84a 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ Post-v2.17.0 IPv6/TCP. * Add AVX512 optimized profiles to miniflow extract for VLAN/IPv6/UDP and VLAN/IPv6/TCP. + * Add IPv4 profile based 5tuple hashing optimizations. v2.17.0 - xx xxx xxxx --------------------- diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c index 8056aa9d6..84cdcc716 100644 --- a/lib/dpif-netdev-extract-avx512.c +++ b/lib/dpif-netdev-extract-avx512.c @@ -326,6 +326,10 @@ struct mfex_profile { uint64_t mf_bits[FLOWMAP_UNITS]; uint16_t dp_pkt_offs[4]; uint16_t dp_pkt_min_size; + + /* Constant data offsets for Hashing. */ + uint8_t hash_pkt_offs[6]; + uint32_t hash_len; }; /* Ensure dp_pkt_offs[4] is the correct size as in struct dp_packet. */ @@ -379,6 +383,13 @@ enum MFEX_PROFILES { PROFILE_COUNT, }; +/* Packet offsets for 5 tuple Hash function. */ +#define HASH_IPV4 \ + 26, 30, 23, 34, 0, 0 + +#define HASH_DT1Q_IPV4 \ + 30, 34, 27, 38, 0, 0 + /* 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 @@ -399,6 +410,9 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = 0, UINT16_MAX, 14, 34, }, .dp_pkt_min_size = 42, + + .hash_pkt_offs = { HASH_IPV4 }, + .hash_len = 72, }, [PROFILE_ETH_IPV4_TCP] = { @@ -422,6 +436,9 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = 0, UINT16_MAX, 14, 34, }, .dp_pkt_min_size = 54, + + .hash_pkt_offs = { HASH_IPV4 }, + .hash_len = 80, }, [PROFILE_ETH_VLAN_IPV4_UDP] = { @@ -441,6 +458,9 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = 14, UINT16_MAX, 18, 38, }, .dp_pkt_min_size = 46, + + .hash_pkt_offs = { HASH_DT1Q_IPV4 }, + .hash_len = 80, }, [PROFILE_ETH_VLAN_IPV4_TCP] = { @@ -466,6 +486,9 @@ static const struct mfex_profile mfex_profiles[PROFILE_COUNT] = 14, UINT16_MAX, 18, 38, }, .dp_pkt_min_size = 58, + + .hash_pkt_offs = { HASH_DT1Q_IPV4 }, + .hash_len = 88, }, [PROFILE_ETH_IPV6_UDP] = { @@ -651,6 +674,33 @@ mfex_check_tcp_data_offset(const struct tcp_header *tcp) return ret; } +static inline void +mfex_5tuple_hash_ipv4(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 *ipv4_src = (void *) &pkt[pkt_offsets[0]]; + void *ipv4_dst = (void *) &pkt[pkt_offsets[1]]; + void *ports_l4 = (void *) &pkt[pkt_offsets[3]]; + + /* IPv4 Src and Dst. */ + hash = hash_add(hash, *(uint32_t *) ipv4_src); + hash = hash_add(hash, *(uint32_t *) ipv4_dst); + /* IPv4 proto. */ + hash = hash_add(hash, pkt[pkt_offsets[2]]); + /* 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); + } +} + /* Generic loop to process any mfex profile. This code is specialized into * multiple actual MFEX implementation functions. Its marked ALWAYS_INLINE * to ensure the compiler specializes each instance. The code is marked "hot" @@ -761,6 +811,10 @@ mfex_avx512_process(struct dp_packet_batch *packets, /* Process TCP flags, and store to blocks. */ const struct tcp_header *tcp = (void *)&pkt[38]; mfex_handle_tcp_flags(tcp, &blocks[7]); + + mfex_5tuple_hash_ipv4(packet, pkt, &keys[i], + profile->hash_pkt_offs); + keys[i].len = profile->hash_len; } break; case PROFILE_ETH_VLAN_IPV4_UDP: { @@ -772,6 +826,10 @@ mfex_avx512_process(struct dp_packet_batch *packets, UDP_HEADER_LEN)) { continue; } + + mfex_5tuple_hash_ipv4(packet, pkt, &keys[i], + profile->hash_pkt_offs); + keys[i].len = profile->hash_len; } break; case PROFILE_ETH_IPV4_TCP: { @@ -786,6 +844,10 @@ mfex_avx512_process(struct dp_packet_batch *packets, TCP_HEADER_LEN)) { continue; } + + mfex_5tuple_hash_ipv4(packet, pkt, &keys[i], + profile->hash_pkt_offs); + keys[i].len = profile->hash_len; } break; case PROFILE_ETH_IPV4_UDP: { @@ -797,6 +859,9 @@ mfex_avx512_process(struct dp_packet_batch *packets, continue; } + mfex_5tuple_hash_ipv4(packet, pkt, &keys[i], + profile->hash_pkt_offs); + keys[i].len = profile->hash_len; } break; case PROFILE_ETH_IPV6_UDP: { -- 2.25.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev