From: Kumar Amber <[email protected]> This commit adds IPv4 profile specific hashing which uses fixed offsets into the packet to improve hashing performance.
Signed-off-by: Kumar Amber <[email protected]> Signed-off-by: Harry van Haaren <[email protected]> Co-authored-by: Harry van Haaren <[email protected]> --- v5: - Rename "hash_len" to "key_len" to describe its use better. --- NEWS | 2 +- lib/dpif-netdev-extract-avx512.c | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index afef81b40..e70c968a6 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Post-v2.16.0 - Userspace datapath: * Optimized flow lookups for datapath flows with simple match criteria. See 'Simple Match Lookup' in Documentation/topics/dpdk/bridge.rst. + * Add IPv4 profile based 5tuple hashing optimizations. - DPDK: * EAL argument --socket-mem is no longer configured by default upon start-up. If dpdk-socket-mem and dpdk-alloc-mem are not specified, @@ -38,7 +39,6 @@ Post-v2.16.0 now dp_hash. Previously this was limited to 64 buckets. This change is mainly for the benefit of OVN load balancing configurations. - v2.16.0 - 16 Aug 2021 --------------------- - Removed support for 1024-bit Diffie-Hellman key exchange, which is now diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c index d23349482..64b1c29cb 100644 --- a/lib/dpif-netdev-extract-avx512.c +++ b/lib/dpif-netdev-extract-avx512.c @@ -258,6 +258,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 key_len; }; /* Ensure dp_pkt_offs[4] is the correct size as in struct dp_packet. */ @@ -307,6 +311,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 @@ -326,6 +337,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 }, + .key_len = 72, }, [PROFILE_ETH_IPV4_TCP] = { @@ -348,6 +362,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 }, + .key_len = 80, }, [PROFILE_ETH_VLAN_IPV4_UDP] = { @@ -366,6 +383,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 }, + .key_len = 80, }, [PROFILE_ETH_VLAN_IPV4_TCP] = { @@ -390,10 +410,40 @@ 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 }, + .key_len = 88, }, }; +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); + } +} + /* 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, @@ -551,6 +601,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->key_len; } break; case PROFILE_ETH_VLAN_IPV4_UDP: { @@ -562,6 +616,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->key_len; } break; case PROFILE_ETH_IPV4_TCP: { @@ -576,6 +634,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->key_len; } break; case PROFILE_ETH_IPV4_UDP: { @@ -587,6 +649,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->key_len; } break; default: break; -- 2.25.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
