[ovs-dev] [RFC] odp-execute: dp_hash HW offload inconsistency.

Roni Bar Yanai roniba at mellanox.com
Wed Jan 8 11:08:57 UTC 2020


Hi Ilya,

I have a setup with vxlan,  and then I do dp_hash (after pop).
First packet does pop in SW, so RSS is invalidated (and anyway it was probably
 calculated on outer),  dp_hash is calculated again SW.
Following packet will do decap in HW so packet has a valid internal RSS (mark+rss),
And it is used as the hash. I have inconsistency between the packets that passed
 through SW and packet that were offloaded with the same 5-tuple (internal).

I know vxlan pop is not offload yet, but we hope it will soon.
I thought of solving this issue by calling netdev_offload_dpdk layer to calc the hash in case
when HW offload Is enabled. So it will be the same hash for both cases.
dp_hash HW offload without a tunnel, will have the same issue, as HW will use some hash not
 necessarily the same as RSS configuration, and even if RSS is used, in SW there is another
salt on top of that, so packet with same 5-tuple offload vs not offloaded will get different hash.

diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 563ad1d..26dc907 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -822,14 +822,18 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
                 DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
                     /* RSS hash can be used here instead of 5tuple for
                      * performance reasons. */
-                    if (dp_packet_rss_valid(packet)) {
-                        hash = dp_packet_get_rss_hash(packet);
-                        hash = hash_int(hash, hash_act->hash_basis);
+                    if (netdev_is_flow_api_enabled()) {
+                            hash = netdev_offload_dpdk_set_dp_hash(packet);
                     } else {
-                        flow_extract(packet, &flow);
-                        hash = flow_hash_5tuple(&flow, hash_act->hash_basis);
-                    }
-                    packet->md.dp_hash = hash;
+
+                        if (dp_packet_rss_valid(packet)) {
+                            hash = dp_packet_get_rss_hash(packet);
+                            hash = hash_int(hash, hash_act->hash_basis);
+                        } else {
+                            flow_extract(packet, &flow);
+                            hash = flow_hash_5tuple(&flow, hash_act->hash_basis);
+                        }
+                        packet->md.dp_hash = hash;
                 }
                 break;
             }

What do you think?

BR,
Roni



More information about the dev mailing list