[ovs-dev] [PATCH 1/1] dpif-netdev: Conditional EMC insert

Ciara Loftus ciara.loftus at intel.com
Thu Jan 12 16:49:59 UTC 2017


Unconditional insertion of EMC entries results in EMC thrashing at high
numbers of parallel flows. When this occurs, the performance of the EMC
often falls below that of the dpcls classifier, rendering the EMC
practically useless.

Instead of unconditionally inserting entries into the EMC when a miss
occurs, use a 1% probability of insertion. This ensures that the most
frequent flows have the highest chance of creating an entry in the EMC,
and the probability of thrashing the EMC is also greatly reduced.

Signed-off-by: Ciara Loftus <ciara.loftus at intel.com>
Signed-off-by: Georg Schmuecking <georg.schmuecking at ericsson.com>
Co-authored-by: Georg Schmuecking <georg.schmuecking at ericsson.com>
---
 lib/dpif-netdev.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 546a1e9..8d55ba2 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -144,6 +144,9 @@ struct netdev_flow_key {
 #define EM_FLOW_HASH_MASK (EM_FLOW_HASH_ENTRIES - 1)
 #define EM_FLOW_HASH_SEGS 2
 
+#define EM_FLOW_INSERT_PROB 100
+#define EM_FLOW_INSERT_MIN (UINT32_MAX / EM_FLOW_INSERT_PROB)
+
 struct emc_entry {
     struct dp_netdev_flow *flow;
     struct netdev_flow_key key;   /* key.hash used for emc hash value. */
@@ -1994,6 +1997,19 @@ emc_insert(struct emc_cache *cache, const struct netdev_flow_key *key,
     emc_change_entry(to_be_replaced, flow, key);
 }
 
+static inline void
+emc_probabilistic_insert(struct dp_netdev_pmd_thread *pmd,
+                         struct emc_cache *cache,
+                         const struct netdev_flow_key *key,
+                         struct dp_netdev_flow *flow)
+{
+    /* One in every EM_FLOW_INSERT_PROB packets are inserted to reduce
+     * thrashing */
+    if ((key->hash ^ (uint32_t)pmd->last_cycles) <= EM_FLOW_INSERT_MIN) {
+        emc_insert(cache, key, flow);
+    }
+}
+
 static inline struct dp_netdev_flow *
 emc_lookup(struct emc_cache *cache, const struct netdev_flow_key *key)
 {
@@ -4092,7 +4108,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd, struct dp_packet *packet,
         }
         ovs_mutex_unlock(&pmd->flow_mutex);
 
-        emc_insert(&pmd->flow_cache, key, netdev_flow);
+        emc_probabilistic_insert(pmd, &pmd->flow_cache, key, netdev_flow);
     }
 }
 
@@ -4187,7 +4203,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
 
         flow = dp_netdev_flow_cast(rules[i]);
 
-        emc_insert(flow_cache, &keys[i], flow);
+        emc_probabilistic_insert(pmd, flow_cache, &keys[i], flow);
         dp_netdev_queue_batches(packet, flow, &keys[i].mf, batches, n_batches);
     }
 
-- 
2.4.3



More information about the dev mailing list