[lttng-dev] [PATCH lttng-tools] Fix: take RCU read-side lock within hash table functions

Jérémie Galarneau jeremie.galarneau at efficios.com
Sun Aug 16 20:35:37 EDT 2015


Merged in master, stable-2.7, stable-2.6 and stable-2.5.

Thanks,
Jérémie
On Aug 6, 2015 15:02, "Mathieu Desnoyers" <mathieu.desnoyers at efficios.com>
wrote:

> After review, a great deal of caller sites miss the RCU read-side lock
> when using the hash table modification functions. This is a case where
> having a slight performance degradation might be worthwhile if we can be
> a bit more stability. So instead of playing whack-a-mole, add the RCU
> read-side lock in the hash table modification functions to ensure
> protection from ABA.
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
> ---
>  src/common/hashtable/hashtable.c | 45
> +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/src/common/hashtable/hashtable.c
> b/src/common/hashtable/hashtable.c
> index 3a38cbf..d1049d1 100644
> --- a/src/common/hashtable/hashtable.c
> +++ b/src/common/hashtable/hashtable.c
> @@ -34,6 +34,13 @@ static unsigned long min_hash_alloc_size = 1;
>  static unsigned long max_hash_buckets_size = 0;
>
>  /*
> + * Getter/lookup functions need to be called with RCU read-side lock
> + * held. However, modification functions (add, add_unique, replace, del)
> + * take the RCU lock internally, so it does not matter whether the
> + * caller hold the RCU lock or not.
> + */
> +
> +/*
>   * Match function for string node.
>   */
>  static int match_str(struct cds_lfht_node *node, const void *key)
> @@ -253,8 +260,11 @@ void lttng_ht_add_unique_str(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         node_ptr = cds_lfht_add_unique(ht->ht, ht->hash_fct(node->key,
> lttng_ht_seed),
>                         ht->match_fct, node->key, &node->node);
> +       rcu_read_unlock();
>         assert(node_ptr == &node->node);
>  }
>
> @@ -268,8 +278,11 @@ void lttng_ht_add_str(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         cds_lfht_add(ht->ht, ht->hash_fct(node->key, lttng_ht_seed),
>                         &node->node);
> +       rcu_read_unlock();
>  }
>
>  /*
> @@ -281,8 +294,11 @@ void lttng_ht_add_ulong(struct lttng_ht *ht, struct
> lttng_ht_node_ulong *node)
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         cds_lfht_add(ht->ht, ht->hash_fct((void *) node->key,
> lttng_ht_seed),
>                         &node->node);
> +       rcu_read_unlock();
>  }
>
>  /*
> @@ -295,8 +311,11 @@ void lttng_ht_add_u64(struct lttng_ht *ht, struct
> lttng_ht_node_u64 *node)
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         cds_lfht_add(ht->ht, ht->hash_fct(&node->key, lttng_ht_seed),
>                         &node->node);
> +       rcu_read_unlock();
>  }
>
>  /*
> @@ -310,9 +329,12 @@ void lttng_ht_add_unique_ulong(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         node_ptr = cds_lfht_add_unique(ht->ht,
>                         ht->hash_fct((void *) node->key, lttng_ht_seed),
> ht->match_fct,
>                         (void *) node->key, &node->node);
> +       rcu_read_unlock();
>         assert(node_ptr == &node->node);
>  }
>
> @@ -327,9 +349,12 @@ void lttng_ht_add_unique_u64(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         node_ptr = cds_lfht_add_unique(ht->ht,
>                         ht->hash_fct(&node->key, lttng_ht_seed),
> ht->match_fct,
>                         &node->key, &node->node);
> +       rcu_read_unlock();
>         assert(node_ptr == &node->node);
>  }
>
> @@ -344,9 +369,12 @@ void lttng_ht_add_unique_two_u64(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         node_ptr = cds_lfht_add_unique(ht->ht,
>                         ht->hash_fct((void *) &node->key, lttng_ht_seed),
> ht->match_fct,
>                         (void *) &node->key, &node->node);
> +       rcu_read_unlock();
>         assert(node_ptr == &node->node);
>  }
>
> @@ -361,9 +389,12 @@ struct lttng_ht_node_ulong
> *lttng_ht_add_replace_ulong(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         node_ptr = cds_lfht_add_replace(ht->ht,
>                         ht->hash_fct((void *) node->key, lttng_ht_seed),
> ht->match_fct,
>                         (void *) node->key, &node->node);
> +       rcu_read_unlock();
>         if (!node_ptr) {
>                 return NULL;
>         } else {
> @@ -383,9 +414,12 @@ struct lttng_ht_node_u64
> *lttng_ht_add_replace_u64(struct lttng_ht *ht,
>         assert(ht->ht);
>         assert(node);
>
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
>         node_ptr = cds_lfht_add_replace(ht->ht,
>                         ht->hash_fct(&node->key, lttng_ht_seed),
> ht->match_fct,
>                         &node->key, &node->node);
> +       rcu_read_unlock();
>         if (!node_ptr) {
>                 return NULL;
>         } else {
> @@ -399,11 +433,17 @@ struct lttng_ht_node_u64
> *lttng_ht_add_replace_u64(struct lttng_ht *ht,
>   */
>  int lttng_ht_del(struct lttng_ht *ht, struct lttng_ht_iter *iter)
>  {
> +       int ret;
> +
>         assert(ht);
>         assert(ht->ht);
>         assert(iter);
>
> -       return cds_lfht_del(ht->ht, iter->iter.node);
> +       /* RCU read lock protects from ABA. */
> +       rcu_read_lock();
> +       ret = cds_lfht_del(ht->ht, iter->iter.node);
> +       rcu_read_unlock();
> +       return ret;
>  }
>
>  /*
> @@ -441,7 +481,10 @@ unsigned long lttng_ht_get_count(struct lttng_ht *ht)
>         assert(ht);
>         assert(ht->ht);
>
> +       /* RCU read lock protects from ABA and allows RCU traversal. */
> +       rcu_read_lock();
>         cds_lfht_count_nodes(ht->ht, &scb, &count, &sca);
> +       rcu_read_unlock();
>
>         return count;
>  }
> --
> 2.1.4
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lttng.org/pipermail/lttng-dev/attachments/20150816/730f18f4/attachment.html>


More information about the lttng-dev mailing list