From: Russell Bryant Date: Wed, 20 Jan 2016 18:29:25 +0000 (-0500) Subject: ovn-controller: Only process lflows for local datapaths. X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=b1e04512f7150aa9d98a121b32f820c316522372;hp=993225bd48296e79b95c5ea0237ee307ebd20a0c;p=cascardo%2Fovs.git ovn-controller: Only process lflows for local datapaths. Previously, ovn-controller translated logical flows into OpenFlow flows for *every* logical datapath. This patch makes it so we skip doing so for the egress pipeline if the datapath is a logical switch with no logical ports bound locally. In that case, the flows have no effect. This was the code path taking the most time in a large scale OVN environment and was an easy optimization to make based on the existing local_datapaths info. In this environment, while idling, ovn-controller was taking up about 20% CPU with this patch, while other nodes were in the 40-70% range. Reported-at: https://bugs.launchpad.net/networking-ovn/+bug/1536003 Signed-off-by: Russell Bryant Tested-by: Matt Mulsow Acked-by: Ben Pfaff Acked-By: Kyle Mestery --- diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c index 32491cf04..f1d8ada71 100644 --- a/ovn/controller/lflow.c +++ b/ovn/controller/lflow.c @@ -157,6 +157,11 @@ symtab_init(void) /* Logical datapaths and logical port numbers. */ +enum ldp_type { + LDP_TYPE_ROUTER, + LDP_TYPE_SWITCH, +}; + /* A logical datapath. * * 'ports' maps 'logical_port' names to 'tunnel_key' values in the OVN_SB @@ -166,6 +171,7 @@ struct logical_datapath { struct uuid uuid; /* UUID from Datapath_Binding row. */ 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 */ }; /* Contains "struct logical_datapath"s. */ @@ -197,6 +203,8 @@ ldp_create(const struct sbrec_datapath_binding *binding) uuid_hash(&binding->header_.uuid)); ldp->uuid = binding->header_.uuid; 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; simap_init(&ldp->ports); return ldp; } @@ -267,7 +275,8 @@ lflow_init(void) * into OpenFlow flows. See ovn-architecture(7) for more information. */ void lflow_run(struct controller_ctx *ctx, struct hmap *flow_table, - const struct simap *ct_zones) + const struct simap *ct_zones, + struct hmap *local_datapaths) { struct hmap flows = HMAP_INITIALIZER(&flows); uint32_t conj_id_ofs = 1; @@ -286,8 +295,29 @@ lflow_run(struct controller_ctx *ctx, struct hmap *flow_table, continue; } - /* Determine translation of logical table IDs to physical table IDs. */ bool ingress = !strcmp(lflow->pipeline, "ingress"); + + if (ldp->type == LDP_TYPE_SWITCH && !ingress) { + /* For a logical switch datapath, local_datapaths tells us if there + * are any local ports for this datapath. If not, processing + * logical flows for the egress pipeline of this datapath is + * unnecessary. + * + * We still need the ingress pipeline because even if there are no + * local ports, we still may need to execute the ingress pipeline + * after a packet leaves a logical router. Further optimization + * is possible, but not based on what we know with local_datapaths + * right now. + */ + + struct hmap_node *ld; + ld = hmap_first_with_hash(local_datapaths, ldp->tunnel_key); + if (!ld) { + continue; + } + } + + /* Determine translation of logical table IDs to physical table IDs. */ uint8_t first_ptable = (ingress ? OFTABLE_LOG_INGRESS_PIPELINE : OFTABLE_LOG_EGRESS_PIPELINE); diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h index 4a4fa8315..ccbad3004 100644 --- a/ovn/controller/lflow.h +++ b/ovn/controller/lflow.h @@ -57,7 +57,8 @@ struct uuid; void lflow_init(void); void lflow_run(struct controller_ctx *, struct hmap *flow_table, - const struct simap *ct_zones); + const struct simap *ct_zones, + struct hmap *local_datapaths); void lflow_destroy(void); #endif /* ovn/lflow.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 98c6dbac9..3638342ec 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -300,7 +300,7 @@ main(int argc, char *argv[]) pinctrl_run(&ctx, br_int); struct hmap flow_table = HMAP_INITIALIZER(&flow_table); - lflow_run(&ctx, &flow_table, &ct_zones); + lflow_run(&ctx, &flow_table, &ct_zones, &local_datapaths); if (chassis_id) { physical_run(&ctx, mff_ovn_geneve, br_int, chassis_id, &ct_zones, &flow_table);