Noting updating slow path subfacet's time stamp can cause their datapath
flows deleted periodically. For example, CFM datapath flow have usespace
actions that are handled in dpif slow path. They are deleted and
recreated periodically without the fix.

This bug are not obvious during normal operation. Deleted CFM flow
would cause CFM packets to be handled by flow miss handler which will
reinstall the flow in the datapath. The only potentially observable
behavior is that when the user space is overwhelmed with flow miss packets,
the periodic CFM miss packets may get stuck behind other miss packets,
cause tunnel flapping.

Reported-by: Guolin Yang <gy...@nicira.com>
Signed-off-by: Andy Zhou <az...@nicira.com>
---
 ofproto/ofproto-dpif.c |   20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index c1c206b..e334755 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -3234,9 +3234,21 @@ handle_flow_miss_with_facet(struct flow_miss *miss, 
struct facet *facet,
      * action for an already installed facet.  This can occur when a
      * datapath flow with wildcards has a "userspace" action and flows
      * sent to userspace result in a different subfacet, which will then
-     * be rejected as overlapping by the datapath. */
+     * be rejected as overlapping by the datapath.
+     */
     if (miss->upcall_type == DPIF_UC_ACTION
         && !list_is_empty(&facet->subfacets)) {
+        struct dpif_backer *backer = miss->ofproto->backer;
+        const struct nlattr *key = miss->key;
+        size_t key_len = miss->key_len;
+        uint32_t key_hash;
+
+        key_hash = odp_flow_key_hash(key, key_len);
+        subfacet = subfacet_find(backer, key, key_len, key_hash);
+
+        if (subfacet) {
+            subfacet->used = MAX(subfacet->used, miss->stats.used);
+        }
         return;
     }
 
@@ -4385,7 +4397,10 @@ subfacet_find(struct dpif_backer *backer, const struct 
nlattr *key,
 /* Searches 'facet' (within 'ofproto') for a subfacet with the specified
  * 'key_fitness', 'key', and 'key_len' members in 'miss'.  Returns the
  * existing subfacet if there is one, otherwise creates and returns a
- * new subfacet. */
+ * new subfacet.
+ * Subfacet returned will have its ''used' timestamp set to no earlier
+ * than 'miss->used' time.
+ */
 static struct subfacet *
 subfacet_create(struct facet *facet, struct flow_miss *miss)
 {
@@ -4403,6 +4418,7 @@ subfacet_create(struct facet *facet, struct flow_miss 
*miss)
         subfacet = subfacet_find(backer, key, key_len, key_hash);
         if (subfacet) {
             if (subfacet->facet == facet) {
+                subfacet->used = MAX(subfacet->used, miss->stats.used);
                 return subfacet;
             }
 
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to