While commit ab39371d68842b7e4000cc5d8718e6fc04e92795
(ovn-controller: Handle physical changes correctly) addressed
unit test failures, it did so at the cost of performance: [1]
notes that ovn-controller cpu usage is now pegged at 100%.

Root cause of this is that while the storage for tunnels is
persisted, their creation is not (which the above changed
incorrectly assumed was the case).  This patch persists
tunneled data across invocations of physical_run.  A side
effect is that renaming of localfvif_map_changed variable
to physical_map_changed and extending its scope to include
tunnel changes.

[1] http://openvswitch.org/pipermail/dev/2016-July/076058.html

Signed-off-by: Ryan Moats <rmo...@us.ibm.com>
---
 ovn/controller/physical.c | 59 +++++++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index a104e33..e788fe5 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -605,8 +605,13 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
         uuid_generate(hc_uuid);
     }
 
+    /* This bool tracks physical mapping changes. */
+    bool physical_map_changed = false;
+
     struct simap new_localvif_to_ofport =
         SIMAP_INITIALIZER(&new_localvif_to_ofport);
+    struct simap new_tunnel_to_ofport = 
+        SIMAP_INITIALIZER(&new_tunnel_to_ofport);
     for (int i = 0; i < br_int->n_ports; i++) {
         const struct ovsrec_port *port_rec = br_int->ports[i];
         if (!strcmp(port_rec->name, br_int->name)) {
@@ -668,18 +673,23 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
                     continue;
                 }
 
-                struct chassis_tunnel *tun = xmalloc(sizeof *tun);
-                hmap_insert(&tunnels, &tun->hmap_node,
-                            hash_string(chassis_id, 0));
-                tun->chassis_id = chassis_id;
-                tun->ofport = u16_to_ofp(ofport);
-                tun->type = tunnel_type;
-                full_binding_processing = true;
-                binding_reset_processing();
-
-                /* Reprocess logical flow table immediately. */
-                lflow_reset_processing();
-                poll_immediate_wake();
+                simap_put(&new_tunnel_to_ofport, chassis_id, ofport);
+                struct chassis_tunnel *tun;
+                if ((tun = chassis_tunnel_find(chassis_id))) {
+                    /* If the tunnel's ofport has changed, update. */
+                    if (tun->ofport != u16_to_ofp(ofport)) {
+                        tun->ofport = u16_to_ofp(ofport);
+                        physical_map_changed = true;
+                    }
+                } else {
+                    tun = xmalloc(sizeof *tun);
+                    hmap_insert(&tunnels, &tun->hmap_node,
+                                hash_string(chassis_id, 0));
+                    tun->chassis_id = chassis_id;
+                    tun->ofport = u16_to_ofp(ofport);
+                    tun->type = tunnel_type;
+                    physical_map_changed = true;
+                }
                 break;
             } else {
                 const char *iface_id = smap_get(&iface_rec->external_ids,
@@ -691,29 +701,38 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
         }
     }
 
+    /* Remove tunnels that are no longer here. */
+    struct chassis_tunnel *tun, *tun_next;
+    HMAP_FOR_EACH_SAFE (tun, tun_next, hmap_node, &tunnels) {
+        if (!simap_find(&new_tunnel_to_ofport, tun->chassis_id)) {
+            hmap_remove(&tunnels, &tun->hmap_node);
+            physical_map_changed = true;
+            free(tun);
+        }
+    }
+
     /* Capture changed or removed openflow ports. */
-    bool localvif_map_changed = false;
     struct simap_node *vif_name, *vif_name_next;
     SIMAP_FOR_EACH_SAFE (vif_name, vif_name_next, &localvif_to_ofport) {
         int newport;
         if ((newport = simap_get(&new_localvif_to_ofport, vif_name->name))) {
             if (newport != simap_get(&localvif_to_ofport, vif_name->name)) {
                 simap_put(&localvif_to_ofport, vif_name->name, newport);
-                localvif_map_changed = true;
+                physical_map_changed = true;
             }
         } else {
             simap_find_and_delete(&localvif_to_ofport, vif_name->name);
-            localvif_map_changed = true;
+            physical_map_changed = true;
         }
     }
     SIMAP_FOR_EACH (vif_name, &new_localvif_to_ofport) {
         if (!simap_get(&localvif_to_ofport, vif_name->name)) {
             simap_put(&localvif_to_ofport, vif_name->name,
                       simap_get(&new_localvif_to_ofport, vif_name->name));
-            localvif_map_changed = true;
+            physical_map_changed = true;
         }
     }
-    if (localvif_map_changed) {
+    if (physical_map_changed) {
         full_binding_processing = true;
 
         /* Reprocess logical flow table immediately. */
@@ -769,7 +788,6 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
      * ports.  We set MFF_LOG_DATAPATH, MFF_LOG_INPORT, and
      * MFF_LOG_OUTPORT from the tunnel key data, then resubmit to table
      * 33 to handle packets to the local hypervisor. */
-    struct chassis_tunnel *tun;
     HMAP_FOR_EACH (tun, hmap_node, &tunnels) {
         struct match match = MATCH_CATCHALL_INITIALIZER;
         match_set_in_port(&match, tun->ofport);
@@ -858,10 +876,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id 
mff_ovn_geneve,
     ofctrl_add_flow(OFTABLE_DROP_LOOPBACK, 0, &match, &ofpacts, hc_uuid);
 
     ofpbuf_uninit(&ofpacts);
-    HMAP_FOR_EACH_POP (tun, hmap_node, &tunnels) {
-        free(tun);
-    }
-    hmap_clear(&tunnels);
 
     simap_destroy(&new_localvif_to_ofport);
+    simap_destroy(&new_tunnel_to_ofport);
 }
-- 
1.9.1

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

Reply via email to