[ovs-dev] [PATCH RFC] dpcls: Avoid one 8-byte chunk in subtable mask.

antonio.fischetti at intel.com antonio.fischetti at intel.com
Mon Dec 19 22:43:47 UTC 2016


This patch skips the chunk comprising of dp_hash and in_port in the
subtable mask when the dpcls refers to a physical port.  This will
slightly speed up the hash computation as one expensive function call
to hash_add64() can be skipped.

The idea behind is that the packets coming from a physical port
shall have the same 8-bytes chunk in their dp_hash/in_port portion of
the miniflow.  When hash is computed in the NIC, dp_hash is zero leaving
only the in_port in the chunk.  This doesn't contribute effectively in
spreading hash values and avoiding collisions.
This approach could be extended to other port types.

Signed-off-by: Antonio Fischetti <antonio.fischetti at intel.com>
Signed-off-by: Bhanuprakash Bodireddy <bhanuprakash.bodireddy at intel.com>
Co-authored-by: Bhanuprakash Bodireddy bhanuprakash.bodireddy at intel.com
---
 lib/dpif-netdev.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 1a47a45..cd8715f 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1856,18 +1856,34 @@ netdev_flow_key_from_flow(struct netdev_flow_key *dst,
 /* Initialize a netdev_flow_key 'mask' from 'match'. */
 static inline void
 netdev_flow_mask_init(struct netdev_flow_key *mask,
-                      const struct match *match)
+                      const struct match *match,
+                      char * port_type)
 {
     uint64_t *dst = miniflow_values(&mask->mf);
     struct flowmap fmap;
     uint32_t hash = 0;
     size_t idx;
+    bool phy_port = false;
+
+    if (port_type && !strcmp(port_type, "dpdk")) {
+        phy_port = true;
+    }
 
     /* Only check masks that make sense for the flow. */
     flow_wc_map(&match->flow, &fmap);
     flowmap_init(&mask->mf.map);
+    /* Check that dp_hash and in_port must be into the same structure chunk. */
+    BUILD_ASSERT_DECL(offsetof(struct flow, dp_hash)/sizeof(*dst) ==
+            offsetof(struct flow, in_port)/sizeof(*dst));
+#define DPHASH_INPORT_MAP_IDX (offsetof(struct flow, dp_hash)/sizeof(*dst))
 
     FLOWMAP_FOR_EACH_INDEX(idx, fmap) {
+        if (phy_port && idx == DPHASH_INPORT_MAP_IDX) {
+            /* This chunk contains Sw-Hash and Port Nr.  As all packets coming
+             * from the same physical port have the same in_port value
+             * and dp_hash set to 0, this 8-bytes chunk will be ignored. */
+            continue;
+        }
         uint64_t mask_u64 = flow_u64_value(&match->wc.masks, idx);
 
         if (mask_u64) {
@@ -2278,7 +2294,15 @@ dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd,
     struct dpcls *cls;
     odp_port_t in_port = match->flow.in_port.odp_port;
 
-    netdev_flow_mask_init(&mask, match);
+    struct dpif_port dpifport;
+
+    if (pmd && pmd->dp) {
+        const struct dpif * pdpif = pmd->dp->dpif;
+        if (pdpif) {
+            dpif_netdev_port_query_by_number(pdpif, in_port, &dpifport);
+        }
+    }
+    netdev_flow_mask_init(&mask, match, dpifport.type);
     /* Make sure wc does not have metadata. */
     ovs_assert(!FLOWMAP_HAS_FIELD(&mask.mf.map, metadata)
                && !FLOWMAP_HAS_FIELD(&mask.mf.map, regs));
-- 
2.4.11



More information about the dev mailing list