On Mon, Jan 6, 2025 at 9:31 AM Ales Musil <[email protected]> wrote:
>
>
>
> On Mon, Dec 16, 2024 at 7:27 PM <[email protected]> wrote:
>>
>> From: Numan Siddique <[email protected]>
>>
>> Its possible for pinctrl handling for DNS packets to be blocked
>> if the ovn-controller main thread has acquired the dns cache
>> mutex during the recompute.  This patch improves the DNS packet
>> handling by maintaining 2 hmaps for dns cache and acquiring the
>> lock in the main thread only to swap the active cache to the
>> latest one.
>>
>> Signed-off-by: Numan Siddique <[email protected]>
>> ---
>
>
>
> Hi Numan,
>
> would it work in your case if you would replace hmap with cmap
> for the cache? That should effectively get rid of the lock completely
> and will have the same effect that you might get "outdated" version
> in the pinctrl if something is writing into it.

Thanks for the comments.  Your idea makes sense.  I'm working on using cmap
and I'll submit v2 with these changes.

Thanks
Numan

>
>>  controller/ovn-dns.c | 94 +++++++++++++++++++++++---------------------
>>  1 file changed, 50 insertions(+), 44 deletions(-)
>>
>> diff --git a/controller/ovn-dns.c b/controller/ovn-dns.c
>> index 026d9bc64..cf384b043 100644
>> --- a/controller/ovn-dns.c
>> +++ b/controller/ovn-dns.c
>> @@ -38,7 +38,9 @@ struct dns_data {
>>  };
>>
>>  /* shash of 'struct dns_data'. */
>> -static struct hmap dns_cache_ = HMAP_INITIALIZER(&dns_cache_);
>> +static struct hmap dns_caches[2];
>> +static struct hmap *active_dns_cache_;
>> +static uint8_t active_dns_cache_idx;
>>
>>  /* Mutex to protect dns_cache_. */
>>  static struct ovs_mutex dns_cache_mutex = OVS_MUTEX_INITIALIZER;
>> @@ -47,58 +49,49 @@ 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);
>> +static struct dns_data *dns_data_find(const struct uuid *uuid,
>> +                                      const struct hmap *);
>>  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 hmap *dns_cache);
>>
>>  void
>>  ovn_dns_cache_init(void)
>>  {
>> +    hmap_init(&dns_caches[0]);
>> +    hmap_init(&dns_caches[1]);
>> +    active_dns_cache_idx = 0;
>> +    active_dns_cache_ = &dns_caches[0];
>>  }
>>
>>  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_);
>> +    destroy_dns_cache(&dns_caches[0]);
>> +    destroy_dns_cache(&dns_caches[1]);
>> +    hmap_destroy(&dns_caches[0]);
>> +    hmap_destroy(&dns_caches[1]);
>> +    active_dns_cache_ = NULL;
>>      ovs_mutex_unlock(&dns_cache_mutex);
>>  }
>>
>>  void
>>  ovn_dns_sync_cache(const struct sbrec_dns_table *dns_table)
>>  {
>> -    ovs_mutex_lock(&dns_cache_mutex);
>> +    const struct sbrec_dns *sbrec_dns;
>>      struct dns_data *dns_data;
>> -    HMAP_FOR_EACH (dns_data, hmap_node, &dns_cache_) {
>> -        dns_data->delete = true;
>> -    }
>>
>> -    const struct sbrec_dns *sbrec_dns;
>> +    uint8_t next_cache_idx = (active_dns_cache_idx + 1) % 2;
>> +    struct hmap *dns_cache = &dns_caches[next_cache_idx];
>> +    ovs_assert(dns_cache != active_dns_cache_);
>> +
>>      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 = dns_data_alloc(*uuid);
>> +        hmap_insert(dns_cache, &dns_data->hmap_node, uuid_hash(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));
>> @@ -107,30 +100,33 @@ ovn_dns_sync_cache(const struct sbrec_dns_table 
>> *dns_table)
>>          }
>>      }
>>
>> -    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);
>> -        }
>> -    }
>> +    struct hmap *prev_active_cache = active_dns_cache_;
>> +
>> +    ovs_mutex_lock(&dns_cache_mutex);
>> +    active_dns_cache_ = dns_cache;
>> +    active_dns_cache_idx = next_cache_idx;
>>      ovs_mutex_unlock(&dns_cache_mutex);
>> +
>> +    /* Destroy the previous active dns cache. */
>> +    destroy_dns_cache(prev_active_cache);
>>  }
>>
>>  void
>>  ovn_dns_update_cache(const struct sbrec_dns_table *dns_table)
>>  {
>>      ovs_mutex_lock(&dns_cache_mutex);
>> -
>> +    ovs_assert(active_dns_cache_ != NULL);
>>      const struct sbrec_dns *sbrec_dns;
>>      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);
>> +        struct dns_data *dns_data = dns_data_find(uuid, active_dns_cache_);
>>
>>          if (sbrec_dns_is_deleted(sbrec_dns) && dns_data) {
>> -            hmap_remove(&dns_cache_, &dns_data->hmap_node);
>> +            hmap_remove(active_dns_cache_, &dns_data->hmap_node);
>>              dns_data_destroy(dns_data);
>>          } else {
>> -            update_cache_with_dns_rec(sbrec_dns, dns_data, uuid, 
>> &dns_cache_);
>> +            update_cache_with_dns_rec(sbrec_dns, dns_data, uuid,
>> +                                      active_dns_cache_);
>>          }
>>      }
>>
>> @@ -142,10 +138,11 @@ ovn_dns_lookup(const char *query_name, uint64_t 
>> dp_key, bool *ovn_owned)
>>  {
>>      ovs_mutex_lock(&dns_cache_mutex);
>>
>> +    ovs_assert(active_dns_cache_ != NULL);
>>      *ovn_owned = false;
>>      struct dns_data *dns_data;
>>      const char *answer_data = NULL;
>> -    HMAP_FOR_EACH (dns_data, hmap_node, &dns_cache_) {
>> +    HMAP_FOR_EACH (dns_data, hmap_node, active_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
>> @@ -205,11 +202,11 @@ update_cache_with_dns_rec(const struct sbrec_dns 
>> *sbrec_dns,
>>  }
>>
>>  static struct dns_data *
>> -dns_data_find(const struct uuid *uuid)
>> +dns_data_find(const struct uuid *uuid, const struct hmap *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_) {
>> +    HMAP_FOR_EACH_WITH_HASH (dns_data, hmap_node, hash, dns_cache) {
>>          if (uuid_equals(&dns_data->uuid, uuid)) {
>>              return dns_data;
>>          }
>> @@ -240,3 +237,12 @@ dns_data_destroy(struct dns_data *dns_data)
>>      free(dns_data->dps);
>>      free(dns_data);
>>  }
>> +
>> +static void
>> +destroy_dns_cache(struct hmap *dns_cache)
>> +{
>> +    struct dns_data *dns_data;
>> +    HMAP_FOR_EACH_POP (dns_data, hmap_node, dns_cache) {
>> +        dns_data_destroy(dns_data);
>> +    }
>> +}
>> --
>> 2.39.3 (Apple Git-146)
>>
>> _______________________________________________
>> dev mailing list
>> [email protected]
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>
> Thanks,
> Ales
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to