For packets which don't already have a hash calculated, miniflow_hash_5tuple() calculates the hash of a packet using the previously built miniflow.
This commit adds IPv4 profile specific hashing which uses fixed offsets into the packet to improve hashing performance. Signed-off-by: Harry van Haaren <harry.van.haa...@intel.com> Co-authored-by: Harry van Haaren <harry.van.haa...@intel.com> Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> Co-authored-by: Ilya Maximets <i.maxim...@ovn.org> Signed-off-by: Kumar Amber <kumar.am...@intel.com> Acked-by: Cian Ferriter <cian.ferri...@intel.com> --- v10: - Make the hahsing function generic and independent of magic numbers. v9: - Use memcpy in place of typecast to fix memory alingment. v8: - Fix comments from cian. v4: - Use pre-defined hash length values. v3: - Fix check-patch sign-offs. --- --- --- NEWS | 3 ++- lib/dp-packet.h | 32 ++++++++++++++++++++++++++++++++ lib/dpif-netdev-extract-avx512.c | 6 +++++- lib/flow.c | 6 ++++++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 8fa57836a..5d3d048f6 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,8 @@ Post-v2.17.0 - OVSDB: * '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 - 17 Feb 2022 --------------------- diff --git a/lib/dp-packet.h b/lib/dp-packet.h index ee0805ae6..7c5da258a 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -1085,6 +1085,38 @@ dp_packet_l4_checksum_bad(const struct dp_packet *p) DP_PACKET_OL_RX_L4_CKSUM_BAD; } +static inline void ALWAYS_INLINE +dp_packet_update_rss_hash_ipv4_tcp_udp(struct dp_packet *packet) +{ + if (dp_packet_rss_valid(packet)) { + return; + } + + const uint8_t *pkt = dp_packet_data(packet); + const uint16_t l3_ofs = packet->l3_ofs; + const void *ipv4_src = &pkt[l3_ofs + offsetof(struct ip_header, ip_src)]; + const void *ipv4_dst = &pkt[l3_ofs + offsetof(struct ip_header, ip_dst)]; + const void *l4_ports = &pkt[packet->l4_ofs]; + uint32_t ip_src, ip_dst, ports; + uint32_t hash = 0; + + memcpy(&ip_src, ipv4_src, sizeof ip_src); + memcpy(&ip_dst, ipv4_dst, sizeof ip_dst); + memcpy(&ports, l4_ports, sizeof ports); + + /* IPv4 Src and Dst. */ + hash = hash_add(hash, ip_src); + hash = hash_add(hash, ip_dst); + /* IPv4 proto. */ + hash = hash_add(hash, + pkt[l3_ofs + offsetof(struct ip_header, ip_proto)]); + /* L4 ports. */ + hash = hash_add(hash, ports); + hash = hash_finish(hash, 42); + + dp_packet_set_rss_hash(packet, hash); +} + #ifdef __cplusplus } #endif diff --git a/lib/dpif-netdev-extract-avx512.c b/lib/dpif-netdev-extract-avx512.c index c1c1fefb6..fa9148efe 100644 --- a/lib/dpif-netdev-extract-avx512.c +++ b/lib/dpif-netdev-extract-avx512.c @@ -48,6 +48,7 @@ #include "dpif-netdev-private-dpcls.h" #include "dpif-netdev-private-extract.h" #include "dpif-netdev-private-flow.h" +#include "dp-packet.h" /* AVX512-BW level permutex2var_epi8 emulation. */ static inline __m512i @@ -577,6 +578,7 @@ 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]); + dp_packet_update_rss_hash_ipv4_tcp_udp(packet); } break; case PROFILE_ETH_VLAN_IPV4_UDP: { @@ -588,6 +590,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, UDP_HEADER_LEN)) { continue; } + dp_packet_update_rss_hash_ipv4_tcp_udp(packet); } break; case PROFILE_ETH_IPV4_TCP: { @@ -602,6 +605,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, TCP_HEADER_LEN)) { continue; } + dp_packet_update_rss_hash_ipv4_tcp_udp(packet); } break; case PROFILE_ETH_IPV4_UDP: { @@ -612,7 +616,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, UDP_HEADER_LEN)) { continue; } - + dp_packet_update_rss_hash_ipv4_tcp_udp(packet); } break; default: break; diff --git a/lib/flow.c b/lib/flow.c index dd523c889..8ab9df3fc 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -1017,6 +1017,9 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) miniflow_push_be16(mf, tp_dst, tcp->tcp_dst); miniflow_push_be16(mf, ct_tp_src, ct_tp_src); miniflow_push_be16(mf, ct_tp_dst, ct_tp_dst); + if (dl_type == htons(ETH_TYPE_IP)) { + dp_packet_update_rss_hash_ipv4_tcp_udp(packet); + } } } } else if (OVS_LIKELY(nw_proto == IPPROTO_UDP)) { @@ -1027,6 +1030,9 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) miniflow_push_be16(mf, tp_dst, udp->udp_dst); miniflow_push_be16(mf, ct_tp_src, ct_tp_src); miniflow_push_be16(mf, ct_tp_dst, ct_tp_dst); + if (dl_type == htons(ETH_TYPE_IP)) { + dp_packet_update_rss_hash_ipv4_tcp_udp(packet); + } } } else if (OVS_LIKELY(nw_proto == IPPROTO_SCTP)) { if (OVS_LIKELY(size >= SCTP_HEADER_LEN)) { -- 2.25.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev