Fix: don't call hash table destroy under rcu read-side c.s.
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 30 Apr 2013 01:25:39 +0000 (21:25 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 30 Apr 2013 01:27:13 +0000 (21:27 -0400)
Fix
src/bin/lttng-sessiond/ust-registry.c:ust_registry_channel_del_free().

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
src/bin/lttng-sessiond/ust-registry.c

index 6c483e4b71c3107b614cc6201a53719d88307fd9..b538a8fa9f37d6f5108c609a3021a27173cbe9ac 100644 (file)
@@ -313,7 +313,7 @@ void ust_registry_destroy_event(struct ust_registry_channel *chan,
  * free the registry pointer since it might not have been allocated before so
  * it's the caller responsability.
  *
- * This MUST be called within a RCU read side lock section.
+ * This *MUST NOT* be called within a RCU read side lock section.
  */
 static void destroy_channel(struct ust_registry_channel *chan)
 {
@@ -322,13 +322,15 @@ static void destroy_channel(struct ust_registry_channel *chan)
 
        assert(chan);
 
+       rcu_read_lock();
        /* Destroy all event associated with this registry. */
        cds_lfht_for_each_entry(chan->ht->ht, &iter.iter, event, node.node) {
                /* Delete the node from the ht and free it. */
                ust_registry_destroy_event(chan, event);
        }
-       lttng_ht_destroy(chan->ht);
+       rcu_read_unlock();
 
+       lttng_ht_destroy(chan->ht);
        free(chan);
 }
 
@@ -418,22 +420,30 @@ void ust_registry_channel_del_free(struct ust_registry_session *session,
 {
        struct lttng_ht_iter iter;
        struct ust_registry_channel *chan;
+       int ret;
 
        assert(session);
 
        rcu_read_lock();
        chan = ust_registry_channel_find(session, key);
        if (!chan) {
+               rcu_read_unlock();
                goto end;
        }
 
        iter.iter.node = &chan->node.node;
-       lttng_ht_del(session->channels, &iter);
+       ret = lttng_ht_del(session->channels, &iter);
+       assert(!ret);
+       rcu_read_unlock();
 
+       /*
+        * Destroying the hash table should be done without RCU
+        * read-side lock held. Since we own "chan" now, it is OK to use
+        * it outside of RCU read-side critical section.
+        */
        destroy_channel(chan);
 
 end:
-       rcu_read_unlock();
        return;
 }
 
This page took 0.037119 seconds and 4 git commands to generate.