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 IPv6 profile specific hashing which uses fixed offsets into the packet to improve hashing performance. Signed-off-by: Kumar Amber <kumar.am...@intel.com> Acked-by: Harry van Haaren <harry.van.haa...@intel.com> --- lib/dp-packet.h | 43 ++++++++++++++++++++++++++++++++ lib/dpif-netdev-extract-avx512.c | 8 +++--- lib/flow.c | 4 +++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/dp-packet.h b/lib/dp-packet.h index 7c5da258a..277bb51b8 100644 --- a/lib/dp-packet.h +++ b/lib/dp-packet.h @@ -1117,6 +1117,49 @@ dp_packet_update_rss_hash_ipv4_tcp_udp(struct dp_packet *packet) dp_packet_set_rss_hash(packet, hash); } +static inline void ALWAYS_INLINE +dp_packet_update_rss_hash_ipv6_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; + uint32_t ipv6_src_off = offsetof(struct ovs_16aligned_ip6_hdr, ip6_src); + uint32_t ipv6_dst_off = offsetof(struct ovs_16aligned_ip6_hdr, ip6_dst); + uint32_t ipv6_proto_off = offsetof(struct ovs_16aligned_ip6_hdr, + ip6_ctlun.ip6_un1.ip6_un1_nxt); + const void *ipv6_src_l = &pkt[l3_ofs + ipv6_src_off]; + const void *ipv6_src_h = &pkt[l3_ofs + ipv6_src_off + 8]; + const void *ipv6_dst_l = &pkt[l3_ofs + ipv6_dst_off]; + const void *ipv6_dst_h = &pkt[l3_ofs + ipv6_dst_off + 8]; + const void *l4_ports = &pkt[packet->l4_ofs]; + uint64_t ipv6_src_lo, ipv6_src_hi; + uint64_t ipv6_dst_lo, ipv6_dst_hi; + uint32_t ports; + uint32_t hash = 0; + + memcpy(&ipv6_src_lo, ipv6_src_l, sizeof ipv6_src_lo); + memcpy(&ipv6_src_hi, ipv6_src_h, sizeof ipv6_src_hi); + memcpy(&ipv6_dst_lo, ipv6_dst_l, sizeof ipv6_dst_lo); + memcpy(&ipv6_dst_hi, ipv6_dst_h, sizeof ipv6_dst_hi); + memcpy(&ports, l4_ports, sizeof ports); + + /* IPv6 Src and Dst. */ + hash = hash_add64(hash, ipv6_src_lo); + hash = hash_add64(hash, ipv6_src_hi); + hash = hash_add64(hash, ipv6_dst_lo); + hash = hash_add64(hash, ipv6_dst_hi); + /* IPv6 proto. */ + hash = hash_add(hash, pkt[l3_ofs + ipv6_proto_off]); + /* 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 b6b7294fc..de823e32a 100644 --- a/lib/dpif-netdev-extract-avx512.c +++ b/lib/dpif-netdev-extract-avx512.c @@ -866,7 +866,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, /* Process UDP header. */ mfex_handle_ipv6_l4((void *)&pkt[54], &blocks[9]); - + dp_packet_update_rss_hash_ipv6_tcp_udp(packet); } break; case PROFILE_ETH_IPV6_TCP: { @@ -889,7 +889,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, continue; } mfex_handle_tcp_flags(tcp, &blocks[9]); - + dp_packet_update_rss_hash_ipv6_tcp_udp(packet); } break; case PROFILE_ETH_VLAN_IPV6_TCP: { @@ -915,7 +915,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, continue; } mfex_handle_tcp_flags(tcp, &blocks[10]); - + dp_packet_update_rss_hash_ipv6_tcp_udp(packet); } break; case PROFILE_ETH_VLAN_IPV6_UDP: { @@ -936,7 +936,7 @@ mfex_avx512_process(struct dp_packet_batch *packets, /* Process UDP header. */ mfex_handle_ipv6_l4((void *)&pkt[58], &blocks[10]); - + dp_packet_update_rss_hash_ipv6_tcp_udp(packet); } break; default: break; diff --git a/lib/flow.c b/lib/flow.c index 8ab9df3fc..b1e1fb34d 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -1019,6 +1019,8 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) 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 (dl_type == htons(ETH_TYPE_IPV6)) { + dp_packet_update_rss_hash_ipv6_tcp_udp(packet); } } } @@ -1032,6 +1034,8 @@ miniflow_extract(struct dp_packet *packet, struct miniflow *dst) 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 (dl_type == htons(ETH_TYPE_IPV6)) { + dp_packet_update_rss_hash_ipv6_tcp_udp(packet); } } } else if (OVS_LIKELY(nw_proto == IPPROTO_SCTP)) { -- 2.25.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev