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