Skip to content

Commit

Permalink
ovn-controller: incremental processing for multicast group changes
Browse files Browse the repository at this point in the history
This patch handles SB Multicast_Group table changes incrementally.
The Multicast_Group table changes can be triggered by creating/deleting
a lport of a lswitch. It can be also triggered indirectly by an
updating of a port-binding which is referenced by the multicast
group.

This patch together with previous incremental processing engine
related changes supports incremental processing for lflow changes
and port-binding changes of lports on other HVs, which are the most
common scenarios in a cloud where workloads come up and down.

In ovn-scale-test env [1], the total execution time of creating and
binding 10k ports on 1k HVs with 40 lswitches and 8 lrouters
(5 lswitches/lrouter), decreased from 3h40m to 1h50m because of the
less CPU on HVs. The CPU time of ovn-controller for additional 500
lports creating and binding (on top of already existed 10k lports)
decreased 90% comparing with master.

Latency for end-to-end operations of one extra port on top of the
10k lports, start from port-creation until all flows installation
on all related HVs is also improved significantly:

before: 20.6s in total
- lsp-add: 0.4s
- wait-until port up=true: 4.8s
- --wait=hv sync: 15.4s

after: 7.3s in total
- lsp-add: 0.4s
- wait-until port up=true: 4.0s
- --wait=hv sync: 2.9s

[1] https://github.com/openvswitch/ovn-scale-test

Signed-off-by: Han Zhou <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
hzhou8 authored and blp committed May 24, 2019
1 parent e35a136 commit c4af630
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
53 changes: 52 additions & 1 deletion ovn/controller/ovn-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,56 @@ flow_output_sb_port_binding_handler(struct engine_node *node)
return true;
}

static bool
flow_output_sb_multicast_group_handler(struct engine_node *node)
{
struct ed_type_runtime_data *data =
(struct ed_type_runtime_data *)engine_get_input(
"runtime_data", node)->data;
struct hmap *local_datapaths = &data->local_datapaths;
struct simap *ct_zones = &data->ct_zones;

struct ed_type_mff_ovn_geneve *ed_mff_ovn_geneve =
(struct ed_type_mff_ovn_geneve *)engine_get_input(
"mff_ovn_geneve", node)->data;
enum mf_field_id mff_ovn_geneve = ed_mff_ovn_geneve->mff_ovn_geneve;

struct ovsrec_open_vswitch_table *ovs_table =
(struct ovsrec_open_vswitch_table *)EN_OVSDB_GET(
engine_get_input("OVS_open_vswitch", node));
struct ovsrec_bridge_table *bridge_table =
(struct ovsrec_bridge_table *)EN_OVSDB_GET(
engine_get_input("OVS_bridge", node));
const struct ovsrec_bridge *br_int = get_br_int(bridge_table, ovs_table);
const char *chassis_id = get_chassis_id(ovs_table);

struct ovsdb_idl_index *sbrec_chassis_by_name =
engine_ovsdb_node_get_index(
engine_get_input("SB_chassis", node),
"name");
const struct sbrec_chassis *chassis = NULL;
if (chassis_id) {
chassis = chassis_lookup_by_name(sbrec_chassis_by_name, chassis_id);
}
ovs_assert(br_int && chassis);

struct ed_type_flow_output *fo =
(struct ed_type_flow_output *)node->data;
struct ovn_desired_flow_table *flow_table = &fo->flow_table;

struct sbrec_multicast_group_table *multicast_group_table =
(struct sbrec_multicast_group_table *)EN_OVSDB_GET(
engine_get_input("SB_multicast_group", node));

physical_handle_mc_group_changes(multicast_group_table,
mff_ovn_geneve, chassis, ct_zones, local_datapaths,
flow_table);

node->changed = true;
return true;

}

struct ovn_controller_exit_args {
bool *exiting;
bool *restart;
Expand Down Expand Up @@ -1356,7 +1406,8 @@ main(int argc, char *argv[])

engine_add_input(&en_flow_output, &en_sb_chassis, NULL);
engine_add_input(&en_flow_output, &en_sb_encap, NULL);
engine_add_input(&en_flow_output, &en_sb_multicast_group, NULL);
engine_add_input(&en_flow_output, &en_sb_multicast_group,
flow_output_sb_multicast_group_handler);
engine_add_input(&en_flow_output, &en_sb_port_binding,
flow_output_sb_port_binding_handler);
engine_add_input(&en_flow_output, &en_sb_mac_binding, NULL);
Expand Down
23 changes: 23 additions & 0 deletions ovn/controller/physical.c
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,29 @@ void physical_handle_port_binding_changes(

}

void
physical_handle_mc_group_changes(
const struct sbrec_multicast_group_table *multicast_group_table,
enum mf_field_id mff_ovn_geneve,
const struct sbrec_chassis *chassis,
const struct simap *ct_zones,
const struct hmap *local_datapaths,
struct ovn_desired_flow_table *flow_table)
{
const struct sbrec_multicast_group *mc;
SBREC_MULTICAST_GROUP_TABLE_FOR_EACH_TRACKED (mc, multicast_group_table) {
if (sbrec_multicast_group_is_deleted(mc)) {
ofctrl_remove_flows(flow_table, &mc->header_.uuid);
} else {
if (!sbrec_multicast_group_is_new(mc)) {
ofctrl_remove_flows(flow_table, &mc->header_.uuid);
}
consider_mc_group(mff_ovn_geneve, ct_zones, local_datapaths,
chassis, mc, flow_table);
}
}
}

void
physical_run(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_multicast_group_table *multicast_group_table,
Expand Down
7 changes: 7 additions & 0 deletions ovn/controller/physical.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,11 @@ void physical_handle_port_binding_changes(
struct sset *active_tunnels,
struct ovn_desired_flow_table *);

void physical_handle_mc_group_changes(
const struct sbrec_multicast_group_table *,
enum mf_field_id mff_ovn_geneve,
const struct sbrec_chassis *,
const struct simap *ct_zones,
const struct hmap *local_datapaths,
struct ovn_desired_flow_table *);
#endif /* ovn/physical.h */

0 comments on commit c4af630

Please sign in to comment.