ebb439
From 93f257e672f814b87ff30512aadc4afc4387c3eb Mon Sep 17 00:00:00 2001
ebb439
From: Han Zhou <hzhou@ovn.org>
ebb439
Date: Fri, 2 Oct 2020 12:47:52 -0700
ebb439
Subject: [PATCH 2/7] ofctrl.c: Avoid repeatedly linking an installed flow and
ebb439
 a desired flow.
ebb439
ebb439
In update_installed_flows_by_compare() there are two loops. The first
ebb439
loop iterates the installed flows and find its peer in desired flows to:
ebb439
ebb439
1. uninstall flows that are not needed anymore
ebb439
ebb439
2. update flows if needed
ebb439
ebb439
At the same time, it links the desired flow found for the installed flow
ebb439
which also set the desired flow as the current active installed flow.
ebb439
ebb439
The second loop iterates the desired flows and find its peer in installed
ebb439
flows to install missing flows. At the same time it will detect if there
ebb439
are conflict desired flows matching same installed flow then just link
ebb439
them.
ebb439
ebb439
However, currently in the second loop, it blindly link the desired flows to the
ebb439
installed flows, without checking if it is already linked in the first loop.
ebb439
Lucky enough, this won't cause any real problem so far, because when there are
ebb439
conflict flows, the one found in the first loop will be set as active in the
ebb439
installed_flow, and in the function link_installed_to_desired() checks if it is
ebb439
already the active desired flow it just does nothing but return.  However, the
ebb439
check in the link_installed_to_desired() is confusing because a desired_flow
ebb439
may be linked to the installed_flow already but not the active flow, and the
ebb439
check is insufficient. It should be rather an assertion and let the caller
ebb439
ensure that a pair of desired_flow and installed_flow is never linked twice.
ebb439
ebb439
For the above reason, this patch does the following changes:
ebb439
ebb439
1. Removes the check in link_installed_to_desired() and convert it to an assert.
ebb439
ebb439
2. Before calling link_installed_to_desired() in the above mentioned loop,
ebb439
   check if the desired flow is already installed.
ebb439
ebb439
Acked-by: Dumitru Ceara <dceara@redhat.com>
ebb439
Signed-off-by: Han Zhou <hzhou@ovn.org>
ebb439
(cherry picked from upstream commit 7cab7bd1268ba67429954da4f73de91090acf779)
ebb439
ebb439
Change-Id: I84f8d7c771c30785dc8c30ce2d4c8c0b4735faae
ebb439
---
ebb439
 controller/ofctrl.c | 19 ++++++++++++++-----
ebb439
 1 file changed, 14 insertions(+), 5 deletions(-)
ebb439
ebb439
diff --git a/controller/ofctrl.c b/controller/ofctrl.c
ebb439
index e725c00..4425d98 100644
ebb439
--- a/controller/ofctrl.c
ebb439
+++ b/controller/ofctrl.c
ebb439
@@ -806,13 +806,18 @@ desired_flow_set_active(struct desired_flow *d)
ebb439
     d->installed_flow->desired_flow = d;
ebb439
 }
ebb439
 
ebb439
+/* Adds the desired flow to the list of desired flows that have same match
ebb439
+ * conditions as the installed flow.
ebb439
+ *
ebb439
+ * If the newly added desired flow is the first one in the list, it is also set
ebb439
+ * as the active one.
ebb439
+ *
ebb439
+ * It is caller's responsibility to make sure the link between the pair didn't
ebb439
+ * exist before. */
ebb439
 static void
ebb439
 link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
ebb439
 {
ebb439
-    if (i->desired_flow == d) {
ebb439
-        return;
ebb439
-    }
ebb439
-
ebb439
+    ovs_assert(i->desired_flow != d);
ebb439
     if (ovs_list_is_empty(&i->desired_refs)) {
ebb439
         ovs_assert(!i->desired_flow);
ebb439
         i->desired_flow = d;
ebb439
@@ -1705,8 +1710,12 @@ update_installed_flows_by_compare(struct ovn_desired_flow_table *flow_table,
ebb439
             /* Copy 'd' from 'flow_table' to installed_flows. */
ebb439
             i = installed_flow_dup(d);
ebb439
             hmap_insert(&installed_flows, &i->match_hmap_node, i->flow.hash);
ebb439
+            link_installed_to_desired(i, d);
ebb439
+        } else if (!d->installed_flow) {
ebb439
+            /* This is a desired_flow that conflicts with one installed
ebb439
+             * previously but not linked yet. */
ebb439
+            link_installed_to_desired(i, d);
ebb439
         }
ebb439
-        link_installed_to_desired(i, d);
ebb439
     }
ebb439
 }
ebb439
 
ebb439
-- 
ebb439
1.8.3.1
ebb439