Add incremental processing of lflows in ovn-controller by
taking the simple approach of marking each lflow dirty when
touched and have lflow_run only process dirty flows.

This needs unit test code before the RFC tag comes off.

Signed-off-by: RYAN D. MOATS <rmo...@us.ibm.com>
---
 ovn/controller/lflow.c |   17 +++++++----------
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index e586365..b5a0ebb 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -172,6 +172,7 @@ struct logical_datapath {
     uint32_t tunnel_key;        /* 'tunnel_key' from Datapath_Binding row. */
     struct simap ports;         /* Logical port name to port number. */
     enum ldp_type type;         /* Type of logical datapath */
+    uint8_t dirty;              /* Does this path need to be reprogrammed? */
 };
 
 /* Contains "struct logical_datapath"s. */
@@ -205,6 +206,7 @@ ldp_create(const struct sbrec_datapath_binding *binding)
     ldp->tunnel_key = binding->tunnel_key;
     const char *ls = smap_get(&binding->external_ids, "logical-switch");
     ldp->type = ls ? LDP_TYPE_SWITCH : LDP_TYPE_ROUTER;
+    ldp->dirty = 1;
     simap_init(&ldp->ports);
     return ldp;
 }
@@ -233,6 +235,7 @@ ldp_run(struct controller_ctx *ctx)
     struct logical_datapath *ldp;
     HMAP_FOR_EACH (ldp, hmap_node, &logical_datapaths) {
         simap_clear(&ldp->ports);
+        ldp->dirty = 1;
     }
 
     const struct sbrec_port_binding *binding;
@@ -240,12 +243,14 @@ ldp_run(struct controller_ctx *ctx)
         struct logical_datapath *ldp = ldp_lookup_or_create(binding->datapath);
 
         simap_put(&ldp->ports, binding->logical_port, binding->tunnel_key);
+        ldp->dirty = 1;
     }
 
     const struct sbrec_multicast_group *mc;
     SBREC_MULTICAST_GROUP_FOR_EACH (mc, ctx->ovnsb_idl) {
         struct logical_datapath *ldp = ldp_lookup_or_create(mc->datapath);
         simap_put(&ldp->ports, mc->name, mc->tunnel_key);
+        ldp->dirty = 1;
     }
 
     struct logical_datapath *next_ldp;
@@ -291,7 +296,7 @@ lflow_run(struct controller_ctx *ctx, struct hmap 
*flow_table,
          * point in maintaining any flows for it anyway, so skip it. */
         const struct logical_datapath *ldp;
         ldp = ldp_lookup(lflow->logical_datapath);
-        if (!ldp) {
+        if (!ldp || !ldp->dirty) {
             continue;
         }
 
@@ -308,15 +313,6 @@ lflow_run(struct controller_ctx *ctx, struct hmap 
*flow_table,
              * after a packet leaves a logical router.  Further optimization
              * is possible, but not based on what we know with local_datapaths
              * right now.
-             *
-             * A better approach would be a kind of "flood fill" algorithm:
-             *
-             *   1. Initialize set S to the logical datapaths that have a port
-             *      located on the hypervisor.
-             *
-             *   2. For each patch port P in a logical datapath in S, add the
-             *      logical datapath of the remote end of P to S.  Iterate
-             *      until S reaches a fixed point.
              */
 
             struct hmap_node *ld;
@@ -424,6 +420,7 @@ lflow_run(struct controller_ctx *ctx, struct hmap 
*flow_table,
         expr_matches_destroy(&matches);
         ofpbuf_uninit(&ofpacts);
         conj_id_ofs += n_conjs;
+        ldp->dirty = 0;
     }
 }
 
-- 
1.7.1

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

Reply via email to