[ovs-dev] [PATCH v9 08/10] Convert binding_run to incremental processing.

Ryan Moats rmoats at us.ibm.com
Fri Mar 11 21:06:23 UTC 2016


From: RYAN D. MOATS <rmoats at us.ibm.com>

Persist all_lports structure and ensure that binding_run
resets to process the entire port binding table when chassis
are added/removed or when get_local_iface_ids finds new ports
on the local vswitch.

Signed-off-by: RYAN D. MOATS <rmoats at us.ibm.com>
---
 ovn/controller/binding.c        |   55 ++++++++++++++++++++++++++++++--------
 ovn/controller/binding.h        |    1 +
 ovn/controller/encaps.c         |    4 +-
 ovn/controller/lflow.h          |    1 +
 ovn/controller/ovn-controller.h |    1 +
 5 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index 87cae99..dd80d56 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -50,6 +50,16 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)
                          &ovsrec_interface_col_ingress_policing_burst);
 }
 
+struct sset all_lports = SSET_INITIALIZER(&all_lports);
+
+unsigned int binding_seqno = 0;
+
+void
+reset_binding_seqno(void)
+{
+    binding_seqno = 0;
+}
+
 static void
 get_local_iface_ids(const struct ovsrec_bridge *br_int, struct shash *lports)
 {
@@ -73,6 +83,10 @@ get_local_iface_ids(const struct ovsrec_bridge *br_int, struct shash *lports)
                 continue;
             }
             shash_add(lports, iface_id, iface_rec);
+            if (!sset_find(&all_lports, iface_id)) {
+                sset_add(&all_lports, iface_id);
+                reset_binding_seqno();
+            }
         }
     }
 }
@@ -130,7 +144,12 @@ struct hmap local_datapaths_by_seqno =
 static struct local_datapath *
 local_datapath_lookup_by_seqno(unsigned int ins_seqno)
 {
-    return hmap_first_with_hash(&local_datapaths_by_seqno, ins_seqno);
+    struct hmap_node *ld = hmap_first_with_hash(&local_datapaths_by_seqno,
+                                                ins_seqno);
+    if (ld) {
+        return CONTAINER_OF(ld, struct local_datapath, seqno_hmap_node);
+    }
+    return NULL;
 }
 
 static void
@@ -138,8 +157,13 @@ remove_local_datapath(struct hmap *local_datapaths, unsigned int ins_seqno)
 {
     struct local_datapath *ld = local_datapath_lookup_by_seqno(ins_seqno);
     if (ld) {
+        if (ld->logical_port) {
+            sset_find_and_delete(&all_lports, ld->logical_port);
+            free(ld->logical_port);
+        }
         hmap_remove(local_datapaths, &ld->hmap_node);
         hmap_remove(&local_datapaths_by_seqno, &ld->seqno_hmap_node);
+        free(ld);
         reset_flow_processing();
     }
 }
@@ -155,6 +179,8 @@ add_local_datapath(struct hmap *local_datapaths,
     }
 
     struct local_datapath *ld = xzalloc(sizeof *ld);
+    ld->logical_port = xmemdup(binding_rec->logical_port,
+                               strlen(binding_rec->logical_port));
     hmap_insert(local_datapaths, &ld->hmap_node,
                 binding_rec->datapath->tunnel_key);
     hmap_insert(&local_datapaths_by_seqno, &ld->seqno_hmap_node, ins_seqno);
@@ -193,28 +219,38 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
          * We'll remove our chassis from all port binding records below. */
     }
 
-    struct sset all_lports = SSET_INITIALIZER(&all_lports);
-    struct shash_node *node;
-    SHASH_FOR_EACH (node, &lports) {
-        sset_add(&all_lports, node->name);
-    }
-
     /* Run through each binding record to see if it is resident on this
      * chassis and update the binding accordingly.  This includes both
      * directly connected logical ports and children of those ports. */
     SBREC_PORT_BINDING_FOR_EACH_TRACKED(binding_rec, ctx->ovnsb_idl) {
         unsigned int del_seqno = sbrec_port_binding_row_get_seqno(binding_rec,
             OVSDB_IDL_CHANGE_DELETE);
+        unsigned int mod_seqno = sbrec_port_binding_row_get_seqno(binding_rec,
+            OVSDB_IDL_CHANGE_MODIFY);
         unsigned int ins_seqno = sbrec_port_binding_row_get_seqno(binding_rec,
             OVSDB_IDL_CHANGE_INSERT);
+        if (del_seqno <= binding_seqno && mod_seqno <= binding_seqno
+            && ins_seqno <= binding_seqno) {
+            continue;
+        }
 
         /* if the row has a del_seqno > 0, then trying to process the row
          * isn't going to work (as it has already been freed) */
         if (del_seqno > 0) {
             remove_local_datapath(local_datapaths, ins_seqno);
+            if (del_seqno >= binding_seqno) {
+                binding_seqno = del_seqno;
+            }
             continue;
         }
 
+        if (mod_seqno >= binding_seqno) {
+            binding_seqno = mod_seqno;
+        }
+        if (ins_seqno >= binding_seqno) {
+            binding_seqno = ins_seqno;
+        }
+
         const struct ovsrec_interface *iface_rec
             = shash_find_and_delete(&lports, binding_rec->logical_port);
         if (iface_rec
@@ -259,14 +295,9 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
         }
     }
 
-    SHASH_FOR_EACH (node, &lports) {
-        VLOG_DBG("No port binding record for lport %s", node->name);
-    }
-
     update_ct_zones(&all_lports, ct_zones, ct_zone_bitmap);
 
     shash_destroy(&lports);
-    sset_destroy(&all_lports);
 }
 
 /* Returns true if the database is all cleaned up, false if more work is
diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h
index 6e19c10..ba0be95 100644
--- a/ovn/controller/binding.h
+++ b/ovn/controller/binding.h
@@ -26,6 +26,7 @@ struct ovsrec_bridge;
 struct simap;
 
 void binding_register_ovs_idl(struct ovsdb_idl *);
+void reset_binding_seqno(void);
 void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int,
                  const char *chassis_id, struct simap *ct_zones,
                  unsigned long *ct_zone_bitmap, struct hmap *local_datapaths);
diff --git a/ovn/controller/encaps.c b/ovn/controller/encaps.c
index 282594e..653314a 100644
--- a/ovn/controller/encaps.c
+++ b/ovn/controller/encaps.c
@@ -263,7 +263,7 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
                 sset_delete(&tc.port_names, port_hash->port->name);
                 hmap_remove(&tc.tunnel_hmap, &port_hash->node);
                 free(port_hash);
-                reset_flow_processing();
+                reset_binding_seqno();
             }
             if (encaps_seqno <= del_seqno) {
                 encaps_seqno = del_seqno;
@@ -290,7 +290,7 @@ encaps_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int,
                     continue;
                 }
                 tunnel_add(&tc, chassis_rec->name, encap);
-                reset_flow_processing();
+                reset_binding_seqno();
             }
             if (encaps_seqno <= ins_seqno) {
                 encaps_seqno = ins_seqno;
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index 31b187a..f18af6d 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -56,6 +56,7 @@ struct uuid;
 #define LOG_PIPELINE_LEN 16
 
 void lflow_init(void);
+void reset_flow_processing(void);
 unsigned int lflow_run(struct controller_ctx *, const struct simap *ct_zones,
                        struct hmap *local_datapaths, unsigned int seqno);
 void lflow_destroy(void);
diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h
index 04faf93..761070b 100644
--- a/ovn/controller/ovn-controller.h
+++ b/ovn/controller/ovn-controller.h
@@ -39,6 +39,7 @@ struct controller_ctx {
 struct local_datapath {
     struct hmap_node hmap_node;
     struct hmap_node seqno_hmap_node;
+    char *logical_port;    // for the delete case
     const struct sbrec_port_binding *localnet_port;
 };
 
-- 
1.7.1




More information about the dev mailing list