This commit adds IPv4 profile specific hashing which uses fixed offsets into the packet to improve hashing performance.
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 | 2 + lib/dpif-netdev-extract-avx512.c | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/NEWS b/NEWS index df633e8e2..2090498bb 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ Post-v2.17.0 * 'relay' service model now supports transaction history, i.e. honors the 'last-txn-id' field in 'monitor_cond_since' requests from clients. + - Userspace datapath: + * 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 c1c1fefb6..e0db86629 100644 --- a/lib/dpif-netdev-extract-avx512.c +++ b/lib/dpif-netdev-extract-avx512.c @@ -278,6 +278,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. */ @@ -327,6 +331,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 @@ -347,6 +358,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] = { @@ -370,6 +384,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] = { @@ -389,6 +406,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] = { @@ -414,6 +434,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, }, }; @@ -467,6 +490,33 @@ mfex_handle_tcp_flags(const struct tcp_header *tcp, uint64_t *block) *block = ctl_u64 << 32; } +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" @@ -577,6 +627,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: { @@ -588,6 +642,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: { @@ -602,6 +660,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: { @@ -613,6 +675,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; default: break; -- 2.25.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev