Skip to content

Commit

Permalink
ovn-controller: Only rebuild if something changed.
Browse files Browse the repository at this point in the history
Most of the work done in the ovn-controller main loop only needs to
happen if something has changed either in either the ovs or ovn-sb
database.  This patch makes most of the work get skipped if neither
database changed.

In a large scale environment, ovn-controller was using a large amouint
of CPU in what should be an idle state.  This was partially due to
ovn-controller recalculating the full state of the system every time it
woke up, due to some sort of keepalive (an ovsdb or openflow echo
request).

Reported-at: https://bugs.launchpad.net/networking-ovn/+bug/1536003
Signed-off-by: Russell Bryant <russell@ovn.org>
  • Loading branch information
russellb committed Jan 20, 2016
1 parent bd6f241 commit 88f1597
Showing 1 changed file with 33 additions and 18 deletions.
51 changes: 33 additions & 18 deletions ovn/controller/ovn-controller.c
Expand Up @@ -273,6 +273,8 @@ main(int argc, char *argv[])
struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths);

/* Main loop. */
unsigned int ovs_seqno = 0;
unsigned int ovnsb_seqno = 0;
exiting = false;
while (!exiting) {
struct controller_ctx ctx = {
Expand All @@ -281,32 +283,45 @@ main(int argc, char *argv[])
.ovnsb_idl = ovnsb_idl_loop.idl,
.ovnsb_idl_txn = ovsdb_idl_loop_run(&ovnsb_idl_loop),
};
bool ovsdb_changed = false;

if (ovs_seqno != ovsdb_idl_get_seqno(ovs_idl_loop.idl)) {
ovs_seqno = ovsdb_idl_get_seqno(ovs_idl_loop.idl);
ovsdb_changed = true;
}
if (ovnsb_seqno != ovsdb_idl_get_seqno(ovnsb_idl_loop.idl)) {
ovnsb_seqno = ovsdb_idl_get_seqno(ovnsb_idl_loop.idl);
ovsdb_changed = true;
}

const struct ovsrec_bridge *br_int = get_br_int(&ctx);
const char *chassis_id = get_chassis_id(ctx.ovs_idl);

if (chassis_id) {
chassis_run(&ctx, chassis_id);
encaps_run(&ctx, br_int, chassis_id);
binding_run(&ctx, br_int, chassis_id, &ct_zones, ct_zone_bitmap,
&local_datapaths);
}
if (ovsdb_changed) {
const char *chassis_id = get_chassis_id(ctx.ovs_idl);

if (br_int) {
patch_run(&ctx, br_int, &local_datapaths);
if (chassis_id) {
chassis_run(&ctx, chassis_id);
encaps_run(&ctx, br_int, chassis_id);
binding_run(&ctx, br_int, chassis_id, &ct_zones, ct_zone_bitmap,
&local_datapaths);
}

enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
if (br_int) {
patch_run(&ctx, br_int, &local_datapaths);

pinctrl_run(&ctx, br_int);
enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);

struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
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);
pinctrl_run(&ctx, br_int);

struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
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);
}
ofctrl_put(&flow_table);
hmap_destroy(&flow_table);
}
ofctrl_put(&flow_table);
hmap_destroy(&flow_table);
}

unixctl_server_run(unixctl);
Expand Down

0 comments on commit 88f1597

Please sign in to comment.