From f781f1bdb099c0bfc45e6bf732940f076f28c026 Mon Sep 17 00:00:00 2001 From: Dumitru Ceara Date: Thu, 12 Sep 2019 16:14:20 +0200 Subject: [PATCH 2/4] ovn-controller: Minimize SB DB port_binding lookups. Instead of storing only peer_ports in struct local_datapath, store both local-remote mappings for patch ports. Also, it's useful to directly store sbrec_port_binding pointers for all datapath ports as we avoid doing costly sbrec_port_binding index lookups by port name. Change-Id: Id8df886cab6bb4a81cd105d2ac52dd7e9aa03326 Acked-by: Mark Michelson Acked-by: Han Zhou Signed-off-by: Dumitru Ceara Signed-off-by: Numan Siddique (cherry-picked from upstream commit 89f5048f960c67e9dac3d45c6a9b25fa260e1a46) --- ovn/controller/binding.c | 19 +++++++++--- ovn/controller/ovn-controller.h | 11 ++++++- ovn/controller/physical.c | 17 ++++++----- ovn/controller/pinctrl.c | 53 ++++++++------------------------- 4 files changed, 48 insertions(+), 52 deletions(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index c71731a1e..1380a3e6e 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -161,13 +161,24 @@ add_local_datapath__(struct ovsdb_idl_index *sbrec_datapath_binding_by_key, peer->datapath, false, depth + 1, local_datapaths); ld->n_peer_ports++; - ld->peer_ports = xrealloc(ld->peer_ports, - ld->n_peer_ports * - sizeof *ld->peer_ports); - ld->peer_ports[ld->n_peer_ports - 1] = peer; + if (ld->n_peer_ports > ld->n_allocated_peer_ports) { + ld->peer_ports = + x2nrealloc(ld->peer_ports, + &ld->n_allocated_peer_ports, + sizeof *ld->peer_ports); + } + ld->peer_ports[ld->n_peer_ports - 1].local = pb; + ld->peer_ports[ld->n_peer_ports - 1].remote = peer; } } } + + ld->n_ports++; + if (ld->n_ports > ld->n_allocated_ports) { + ld->ports = x2nrealloc(ld->ports, &ld->n_allocated_ports, + sizeof *ld->ports); + } + ld->ports[ld->n_ports - 1] = pb; } sbrec_port_binding_index_destroy_row(target); } diff --git a/ovn/controller/ovn-controller.h b/ovn/controller/ovn-controller.h index 078c9eabe..09ef4b632 100644 --- a/ovn/controller/ovn-controller.h +++ b/ovn/controller/ovn-controller.h @@ -60,8 +60,17 @@ struct local_datapath { * hypervisor. */ bool has_local_l3gateway; - const struct sbrec_port_binding **peer_ports; + const struct sbrec_port_binding **ports; + size_t n_ports; + size_t n_allocated_ports; + + struct { + const struct sbrec_port_binding *local; + const struct sbrec_port_binding *remote; + } *peer_ports; + size_t n_peer_ports; + size_t n_allocated_peer_ports; }; struct local_datapath *get_local_datapath(const struct hmap *, diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c index 95cbaba49..b439a4852 100644 --- a/ovn/controller/physical.c +++ b/ovn/controller/physical.c @@ -259,11 +259,12 @@ put_remote_port_redirect_bridged(const struct uint32_t ls_dp_key = 0; for (int i = 0; i < ld->n_peer_ports; i++) { - const struct sbrec_port_binding *sport_binding = ld->peer_ports[i]; - const char *sport_peer_name = smap_get(&sport_binding->options, - "peer"); - const char *distributed_port = smap_get(&binding->options, - "distributed-port"); + const struct sbrec_port_binding *sport_binding = + ld->peer_ports[i].remote; + const char *sport_peer_name = + smap_get(&sport_binding->options, "peer"); + const char *distributed_port = + smap_get(&binding->options, "distributed-port"); if (!strcmp(sport_peer_name, distributed_port)) { ls_dp_key = sport_binding->datapath->tunnel_key; @@ -525,7 +526,8 @@ put_replace_chassis_mac_flows(const struct simap *ct_zones, struct zone_ids zone_ids = get_zone_ids(localnet_port, ct_zones); for (int i = 0; i < ld->n_peer_ports; i++) { - const struct sbrec_port_binding *rport_binding = ld->peer_ports[i]; + const struct sbrec_port_binding *rport_binding = + ld->peer_ports[i].remote; struct eth_addr router_port_mac; char *err_str = NULL; struct match match; @@ -632,7 +634,8 @@ put_replace_router_port_mac_flows(struct ovsdb_idl_index } for (int i = 0; i < ld->n_peer_ports; i++) { - const struct sbrec_port_binding *rport_binding = ld->peer_ports[i]; + const struct sbrec_port_binding *rport_binding = + ld->peer_ports[i].remote; struct eth_addr router_port_mac; struct match match; struct ofpact_mac *replace_mac; diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c index 8bc99df4e..5636fc1e0 100644 --- a/ovn/controller/pinctrl.c +++ b/ovn/controller/pinctrl.c @@ -175,8 +175,7 @@ static struct pinctrl pinctrl; static void init_buffered_packets_map(void); static void destroy_buffered_packets_map(void); static void -run_buffered_binding(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, - struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip, +run_buffered_binding(struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip, const struct hmap *local_datapaths) OVS_REQUIRES(pinctrl_mutex); @@ -240,10 +239,7 @@ static void wait_controller_event(struct ovsdb_idl_txn *ovnsb_idl_txn); static void init_ipv6_ras(void); static void destroy_ipv6_ras(void); static void ipv6_ra_wait(long long int send_ipv6_ra_time); -static void prepare_ipv6_ras( - struct ovsdb_idl_index *sbrec_port_binding_by_datapath, - struct ovsdb_idl_index *sbrec_port_binding_by_name, - const struct hmap *local_datapaths) +static void prepare_ipv6_ras(const struct hmap *local_datapaths) OVS_REQUIRES(pinctrl_mutex); static void send_ipv6_ras(struct rconn *swconn, long long int *send_ipv6_ra_time) @@ -2216,8 +2212,7 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, send_garp_prepare(sbrec_port_binding_by_datapath, sbrec_port_binding_by_name, br_int, chassis, local_datapaths, active_tunnels); - prepare_ipv6_ras(sbrec_port_binding_by_datapath, - sbrec_port_binding_by_name, local_datapaths); + prepare_ipv6_ras(local_datapaths); sync_dns_cache(dns_table); controller_event_run(ovnsb_idl_txn, ce_table, chassis); ip_mcast_sync(ovnsb_idl_txn, chassis, local_datapaths, @@ -2225,8 +2220,7 @@ pinctrl_run(struct ovsdb_idl_txn *ovnsb_idl_txn, sbrec_port_binding_by_key, sbrec_igmp_groups, sbrec_ip_multicast_opts); - run_buffered_binding(sbrec_port_binding_by_datapath, - sbrec_mac_binding_by_lport_ip, + run_buffered_binding(sbrec_mac_binding_by_lport_ip, local_datapaths); sync_svc_monitors(ovnsb_idl_txn, svc_mon_table, sbrec_port_binding_by_name, chassis); @@ -2669,9 +2663,7 @@ send_ipv6_ras(struct rconn *swconn, long long int *send_ipv6_ra_time) /* Called by pinctrl_run(). Runs with in the main ovn-controller * thread context. */ static void -prepare_ipv6_ras(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, - struct ovsdb_idl_index *sbrec_port_binding_by_name, - const struct hmap *local_datapaths) +prepare_ipv6_ras(const struct hmap *local_datapaths) OVS_REQUIRES(pinctrl_mutex) { struct shash_node *iter, *iter_next; @@ -2684,25 +2676,12 @@ prepare_ipv6_ras(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, bool changed = false; const struct local_datapath *ld; HMAP_FOR_EACH (ld, hmap_node, local_datapaths) { - struct sbrec_port_binding *target = sbrec_port_binding_index_init_row( - sbrec_port_binding_by_datapath); - sbrec_port_binding_index_set_datapath(target, ld->datapath); - struct sbrec_port_binding *pb; - SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target, - sbrec_port_binding_by_datapath) { - if (!smap_get_bool(&pb->options, "ipv6_ra_send_periodic", false)) { - continue; - } + for (size_t i = 0; i < ld->n_peer_ports; i++) { + const struct sbrec_port_binding *peer = ld->peer_ports[i].remote; + const struct sbrec_port_binding *pb = ld->peer_ports[i].local; - const char *peer_s = smap_get(&pb->options, "peer"); - if (!peer_s) { - continue; - } - - const struct sbrec_port_binding *peer - = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); - if (!peer) { + if (!smap_get_bool(&pb->options, "ipv6_ra_send_periodic", false)) { continue; } @@ -2741,7 +2720,6 @@ prepare_ipv6_ras(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, /* pinctrl_handler thread will send the IPv6 RAs. */ } - sbrec_port_binding_index_destroy_row(target); } /* Remove those that are no longer in the SB database */ @@ -2987,8 +2965,7 @@ run_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn, } static void -run_buffered_binding(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, - struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip, +run_buffered_binding(struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip, const struct hmap *local_datapaths) OVS_REQUIRES(pinctrl_mutex) { @@ -2996,13 +2973,10 @@ run_buffered_binding(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, bool notify = false; HMAP_FOR_EACH (ld, hmap_node, local_datapaths) { - struct sbrec_port_binding *target = sbrec_port_binding_index_init_row( - sbrec_port_binding_by_datapath); - sbrec_port_binding_index_set_datapath(target, ld->datapath); - const struct sbrec_port_binding *pb; - SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target, - sbrec_port_binding_by_datapath) { + for (size_t i = 0; i < ld->n_ports; i++) { + + const struct sbrec_port_binding *pb = ld->ports[i]; struct buffered_packets *cur_qp, *next_qp; HMAP_FOR_EACH_SAFE (cur_qp, next_qp, hmap_node, &buffered_packets_map) { @@ -3020,7 +2994,6 @@ run_buffered_binding(struct ovsdb_idl_index *sbrec_port_binding_by_datapath, ds_destroy(&ip_s); } } - sbrec_port_binding_index_destroy_row(target); } buffered_packets_map_gc(); -- 2.26.2