X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-registry.c;h=7250dd12d751b0edcce93ffd4b886f8bdd7c7395;hp=19cff09fcd9d26aedb4a79194d10f7875e5fc810;hb=36b588eddce05ef840bd247f6a58316925b9a0a2;hpb=7972aab22f74b18faa168c0482216a3dd711a075 diff --git a/src/bin/lttng-sessiond/ust-registry.c b/src/bin/lttng-sessiond/ust-registry.c index 19cff09fc..7250dd12d 100644 --- a/src/bin/lttng-sessiond/ust-registry.c +++ b/src/bin/lttng-sessiond/ust-registry.c @@ -308,12 +308,26 @@ void ust_registry_destroy_event(struct ust_registry_channel *chan, return; } +/* + * We need to execute ht_destroy outside of RCU read-side critical + * section, so we postpone its execution using call_rcu. It is simpler + * than to change the semantic of the many callers of + * destroy_channel(). + */ +static +void destroy_channel_rcu(struct rcu_head *head) +{ + struct ust_registry_channel *chan = + caa_container_of(head, struct ust_registry_channel, rcu_head); + + lttng_ht_destroy(chan->ht); + free(chan); +} + /* * Destroy every element of the registry and free the memory. This does NOT * 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. */ static void destroy_channel(struct ust_registry_channel *chan) { @@ -322,14 +336,14 @@ 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); - - free(chan); + rcu_read_unlock(); + call_rcu(&chan->rcu_head, destroy_channel_rcu); } /* @@ -418,22 +432,24 @@ 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(); destroy_channel(chan); end: - rcu_read_unlock(); return; } @@ -452,13 +468,14 @@ int ust_registry_session_init(struct ust_registry_session **sessionp, uint32_t uint32_t_alignment, uint32_t uint64_t_alignment, uint32_t long_alignment, - int byte_order) + int byte_order, + uint32_t major, + uint32_t minor) { int ret; struct ust_registry_session *session; assert(sessionp); - assert(app); session = zmalloc(sizeof(*session)); if (!session) { @@ -487,7 +504,7 @@ int ust_registry_session_init(struct ust_registry_session **sessionp, } pthread_mutex_lock(&session->lock); - ret = ust_metadata_session_statedump(session, app); + ret = ust_metadata_session_statedump(session, app, major, minor); pthread_mutex_unlock(&session->lock); if (ret) { ERR("Failed to generate session metadata (errno = %d)", ret); @@ -524,8 +541,8 @@ void ust_registry_session_destroy(struct ust_registry_session *reg) assert(!ret); destroy_channel(chan); } - lttng_ht_destroy(reg->channels); rcu_read_unlock(); + lttng_ht_destroy(reg->channels); free(reg->metadata); }