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

Reply via email to