diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index d875ecc1e6..890c8f988b 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -5458,6 +5458,8 @@ main(int argc, char *argv[]) /* Main loop. */ bool sb_monitor_all = false; while (!exit_args.exiting) { + ovsrcu_quiesce_end(); + memory_run(); if (memory_should_report()) { struct simap usage = SIMAP_INITIALIZER(&usage); @@ -5951,6 +5953,7 @@ main(int argc, char *argv[]) loop_done: memory_wait(); + ovsrcu_quiesce_start(); poll_block(); if (should_service_stop()) { exit_args.exiting = true; diff --git a/controller/ovn-dns.c b/controller/ovn-dns.c index 026d9bc647..bfeef5a747 100644 --- a/controller/ovn-dns.c +++ b/controller/ovn-dns.c @@ -18,6 +18,7 @@ /* OVS includes */ #include "include/openvswitch/shash.h" #include "include/openvswitch/thread.h" +#include "lib/cmap.h" #include "openvswitch/vlog.h" /* OVN includes. */ @@ -28,7 +29,7 @@ VLOG_DEFINE_THIS_MODULE(ovndns); /* Internal DNS cache entry for each SB DNS record. */ struct dns_data { - struct hmap_node hmap_node; + struct cmap_node cmap_node; struct uuid uuid; uint64_t *dps; size_t n_dps; @@ -38,114 +39,87 @@ struct dns_data { }; /* shash of 'struct dns_data'. */ -static struct hmap dns_cache_ = HMAP_INITIALIZER(&dns_cache_); - -/* Mutex to protect dns_cache_. */ -static struct ovs_mutex dns_cache_mutex = OVS_MUTEX_INITIALIZER; +static struct cmap dns_cache_; static void update_cache_with_dns_rec(const struct sbrec_dns *, struct dns_data *, const struct uuid *uuid, - struct hmap *dns_cache); -static struct dns_data *dns_data_find(const struct uuid *uuid); + struct cmap *dns_cache); +static struct dns_data *dns_data_find(const struct uuid *uuid, + const struct cmap *); static struct dns_data *dns_data_alloc(struct uuid uuid); static void dns_data_destroy(struct dns_data *dns_data); +static void destroy_dns_cache(struct cmap *dns_cache); void ovn_dns_cache_init(void) { + cmap_init(&dns_cache_); } void ovn_dns_cache_destroy(void) { - ovs_mutex_lock(&dns_cache_mutex); - struct dns_data *dns_data; - HMAP_FOR_EACH_POP (dns_data, hmap_node, &dns_cache_) { - dns_data_destroy(dns_data); - } - hmap_destroy(&dns_cache_); - ovs_mutex_unlock(&dns_cache_mutex); + destroy_dns_cache(&dns_cache_); + cmap_destroy(&dns_cache_); } void ovn_dns_sync_cache(const struct sbrec_dns_table *dns_table) { - ovs_mutex_lock(&dns_cache_mutex); - struct dns_data *dns_data; - HMAP_FOR_EACH (dns_data, hmap_node, &dns_cache_) { - dns_data->delete = true; + const struct sbrec_dns *sbrec_dns; + struct dns_data *existing; + + CMAP_FOR_EACH (existing, cmap_node, &dns_cache_) { + existing->delete = true; } - const struct sbrec_dns *sbrec_dns; SBREC_DNS_TABLE_FOR_EACH (sbrec_dns, dns_table) { const struct uuid *uuid = &sbrec_dns->header_.uuid; - dns_data = dns_data_find(uuid); - if (!dns_data) { - dns_data = dns_data_alloc(*uuid); - hmap_insert(&dns_cache_, &dns_data->hmap_node, uuid_hash(uuid)); - } else { - free(dns_data->dps); - } - - dns_data->delete = false; - - if (!smap_equal(&dns_data->records, &sbrec_dns->records)) { - smap_destroy(&dns_data->records); - smap_clone(&dns_data->records, &sbrec_dns->records); - } - - if (!smap_equal(&dns_data->options, &sbrec_dns->options)) { - smap_destroy(&dns_data->options); - smap_clone(&dns_data->options, &sbrec_dns->options); - } - - dns_data->n_dps = sbrec_dns->n_datapaths; - dns_data->dps = xcalloc(dns_data->n_dps, sizeof(uint64_t)); - for (size_t i = 0; i < sbrec_dns->n_datapaths; i++) { - dns_data->dps[i] = sbrec_dns->datapaths[i]->tunnel_key; - } + existing = dns_data_find(uuid, &dns_cache_); + update_cache_with_dns_rec(sbrec_dns, existing, uuid, + &dns_cache_); } - HMAP_FOR_EACH_SAFE (dns_data, hmap_node, &dns_cache_) { - if (dns_data->delete) { - hmap_remove(&dns_cache_, &dns_data->hmap_node); - dns_data_destroy(dns_data); + CMAP_FOR_EACH (existing, cmap_node, &dns_cache_) { + if (existing->delete) { + cmap_remove(&dns_cache_, &existing->cmap_node, + uuid_hash(&existing->uuid)); + ovsrcu_postpone(dns_data_destroy, existing); } } - ovs_mutex_unlock(&dns_cache_mutex); } void ovn_dns_update_cache(const struct sbrec_dns_table *dns_table) { - ovs_mutex_lock(&dns_cache_mutex); - const struct sbrec_dns *sbrec_dns; + struct dns_data *existing; + SBREC_DNS_TABLE_FOR_EACH_TRACKED (sbrec_dns, dns_table) { const struct uuid *uuid = &sbrec_dns->header_.uuid; - struct dns_data *dns_data = dns_data_find(uuid); - if (sbrec_dns_is_deleted(sbrec_dns) && dns_data) { - hmap_remove(&dns_cache_, &dns_data->hmap_node); - dns_data_destroy(dns_data); + existing = dns_data_find(uuid, &dns_cache_); + if (sbrec_dns_is_deleted(sbrec_dns) && existing) { + cmap_remove(&dns_cache_, &existing->cmap_node, + uuid_hash(&existing->uuid)); + ovsrcu_postpone(dns_data_destroy, existing); } else { - update_cache_with_dns_rec(sbrec_dns, dns_data, uuid, &dns_cache_); + update_cache_with_dns_rec(sbrec_dns, existing, uuid, + &dns_cache_); } } - - ovs_mutex_unlock(&dns_cache_mutex); } const char * ovn_dns_lookup(const char *query_name, uint64_t dp_key, bool *ovn_owned) { - ovs_mutex_lock(&dns_cache_mutex); + const char *answer_data = NULL; + struct dns_data *dns_data; *ovn_owned = false; - struct dns_data *dns_data; - const char *answer_data = NULL; - HMAP_FOR_EACH (dns_data, hmap_node, &dns_cache_) { + + CMAP_FOR_EACH (dns_data, cmap_node, &dns_cache_) { for (size_t i = 0; i < dns_data->n_dps; i++) { if (dns_data->dps[i] == dp_key) { /* DNS records in SBDB are stored in lowercase. Convert to @@ -167,8 +141,6 @@ ovn_dns_lookup(const char *query_name, uint64_t dp_key, bool *ovn_owned) } } - ovs_mutex_unlock(&dns_cache_mutex); - return answer_data; } @@ -176,40 +148,35 @@ ovn_dns_lookup(const char *query_name, uint64_t dp_key, bool *ovn_owned) /* Static functions. */ static void update_cache_with_dns_rec(const struct sbrec_dns *sbrec_dns, - struct dns_data *dns_data, + struct dns_data *existing, const struct uuid *uuid, - struct hmap *dns_cache) + struct cmap *dns_cache) { - if (!dns_data) { - dns_data = dns_data_alloc(*uuid); - hmap_insert(dns_cache, &dns_data->hmap_node, uuid_hash(uuid)); - } else { - free(dns_data->dps); - } - - if (!smap_equal(&dns_data->records, &sbrec_dns->records)) { - smap_destroy(&dns_data->records); - smap_clone(&dns_data->records, &sbrec_dns->records); - } - - if (!smap_equal(&dns_data->options, &sbrec_dns->options)) { - smap_destroy(&dns_data->options); - smap_clone(&dns_data->options, &sbrec_dns->options); - } + struct dns_data *dns_data = dns_data_alloc(*uuid); + smap_clone(&dns_data->records, &sbrec_dns->records); + smap_clone(&dns_data->options, &sbrec_dns->options); dns_data->n_dps = sbrec_dns->n_datapaths; dns_data->dps = xcalloc(dns_data->n_dps, sizeof(uint64_t)); for (size_t i = 0; i < sbrec_dns->n_datapaths; i++) { dns_data->dps[i] = sbrec_dns->datapaths[i]->tunnel_key; } + + if (!existing) { + cmap_insert(dns_cache, &dns_data->cmap_node, uuid_hash(uuid)); + } else { + cmap_replace(dns_cache, &existing->cmap_node, &dns_data->cmap_node, + uuid_hash(uuid)); + ovsrcu_postpone(dns_data_destroy, existing); + } } static struct dns_data * -dns_data_find(const struct uuid *uuid) +dns_data_find(const struct uuid *uuid, const struct cmap *dns_cache) { struct dns_data *dns_data; size_t hash = uuid_hash(uuid); - HMAP_FOR_EACH_WITH_HASH (dns_data, hmap_node, hash, &dns_cache_) { + CMAP_FOR_EACH_WITH_HASH (dns_data, cmap_node, hash, dns_cache) { if (uuid_equals(&dns_data->uuid, uuid)) { return dns_data; } @@ -240,3 +207,12 @@ dns_data_destroy(struct dns_data *dns_data) free(dns_data->dps); free(dns_data); } + +static void +destroy_dns_cache(struct cmap *dns_cache) +{ + struct dns_data *dns_data; + CMAP_FOR_EACH (dns_data, cmap_node, dns_cache) { + ovsrcu_postpone(dns_data_destroy, dns_data); + } +} diff --git a/controller/pinctrl.c b/controller/pinctrl.c index e1bae61515..eaa0985021 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -3902,6 +3902,8 @@ pinctrl_handler(void *arg_) static long long int send_prefixd_time = LLONG_MAX; while (!latch_is_set(&pctrl->pinctrl_thread_exit)) { + ovsrcu_quiesce_end(); + long long int bfd_time = LLONG_MAX; bool lock_failed = false; @@ -3975,6 +3977,8 @@ pinctrl_handler(void *arg_) latch_wait(&pctrl->pinctrl_thread_exit); } + + ovsrcu_quiesce_start(); poll_block(); }