From: Francis Deslauriers Date: Mon, 27 Sep 2021 14:56:28 +0000 (-0400) Subject: Enforce documented RCU preconditions with assertions X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=48b7cdc221a445188d6d9bd08fc1686837e71224;p=lttng-tools.git Enforce documented RCU preconditions with assertions Mindlessly add `rcu_read_ongoing()` assertions to functions that are documented as "must be called" within a RCU critical section. Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau Change-Id: I25f9903938123394e6960ab2a338be6abaf2fe72 --- diff --git a/src/bin/lttng-relayd/ctf-trace.cpp b/src/bin/lttng-relayd/ctf-trace.cpp index 7a3cbdea0..861bcfbb3 100644 --- a/src/bin/lttng-relayd/ctf-trace.cpp +++ b/src/bin/lttng-relayd/ctf-trace.cpp @@ -41,6 +41,8 @@ static void ctf_trace_destroy(struct ctf_trace *trace) * control side. */ LTTNG_ASSERT(cds_list_empty(&trace->stream_list)); + ASSERT_RCU_READ_LOCKED(); + session_put(trace->session); trace->session = NULL; free(trace->path); @@ -62,11 +64,26 @@ static void ctf_trace_release(struct urcu_ref *ref) } /* - * Should be called with RCU read-side lock held. + * The caller must either: + * - hold the RCU read side lock, or + * - guarantee the existence of the object by already holding a reference to + * the object. */ bool ctf_trace_get(struct ctf_trace *trace) { - return urcu_ref_get_unless_zero(&trace->ref); + const bool ref = urcu_ref_get_unless_zero(&trace->ref); + + if (!ref) { + /* + * The ref count is already zero. It means the object is being + * torn down concurently. + * This is only acceptable if we hold the RCU read-side lock, + * else it's a logic error. + */ + ASSERT_RCU_READ_LOCKED(); + } + + return ref; } /* diff --git a/src/bin/lttng-relayd/index.cpp b/src/bin/lttng-relayd/index.cpp index f2f102e64..6cf131b25 100644 --- a/src/bin/lttng-relayd/index.cpp +++ b/src/bin/lttng-relayd/index.cpp @@ -67,6 +67,8 @@ static struct relay_index *relay_index_add_unique(struct relay_stream *stream, struct cds_lfht_node *node_ptr; struct relay_index *_index; + ASSERT_RCU_READ_LOCKED(); + DBG2("Adding relay index with stream id %" PRIu64 " and seqnum %" PRIu64, stream->stream_handle, index->index_n.key); @@ -88,6 +90,8 @@ static struct relay_index *relay_index_add_unique(struct relay_stream *stream, */ static bool relay_index_get(struct relay_index *index) { + ASSERT_RCU_READ_LOCKED(); + DBG2("index get for stream id %" PRIu64 " and seqnum %" PRIu64 " refcount %d", index->stream->stream_handle, index->index_n.key, (int) index->ref.refcount); diff --git a/src/bin/lttng-relayd/stream.cpp b/src/bin/lttng-relayd/stream.cpp index b57c061c5..65a8ce11a 100644 --- a/src/bin/lttng-relayd/stream.cpp +++ b/src/bin/lttng-relayd/stream.cpp @@ -31,6 +31,8 @@ /* Should be called with RCU read-side lock held. */ bool stream_get(struct relay_stream *stream) { + ASSERT_RCU_READ_LOCKED(); + return urcu_ref_get_unless_zero(&stream->ref); } diff --git a/src/bin/lttng-sessiond/action-executor.cpp b/src/bin/lttng-sessiond/action-executor.cpp index 032ac11a0..68c9c71cf 100644 --- a/src/bin/lttng-sessiond/action-executor.cpp +++ b/src/bin/lttng-sessiond/action-executor.cpp @@ -872,6 +872,7 @@ enum action_executor_status action_executor_enqueue_trigger( bool signal = false; LTTNG_ASSERT(trigger); + ASSERT_RCU_READ_LOCKED(); pthread_mutex_lock(&executor->work.lock); /* Check for queue overflow. */ diff --git a/src/bin/lttng-sessiond/agent.cpp b/src/bin/lttng-sessiond/agent.cpp index 620ec787f..b0ac94b13 100644 --- a/src/bin/lttng-sessiond/agent.cpp +++ b/src/bin/lttng-sessiond/agent.cpp @@ -1003,6 +1003,7 @@ struct agent_app *agent_find_app_by_sock(int sock) struct agent_app *app; LTTNG_ASSERT(sock >= 0); + ASSERT_RCU_READ_LOCKED(); lttng_ht_lookup(the_agent_apps_ht_by_sock, (void *) ((unsigned long) sock), &iter); @@ -1042,6 +1043,7 @@ void agent_delete_app(struct agent_app *app) struct lttng_ht_iter iter; LTTNG_ASSERT(app); + ASSERT_RCU_READ_LOCKED(); DBG3("Agent deleting app pid: %d and sock: %d", app->pid, app->sock->fd); @@ -1229,6 +1231,7 @@ void agent_find_events_by_name(const char *name, struct agent *agt, LTTNG_ASSERT(agt); LTTNG_ASSERT(agt->events); LTTNG_ASSERT(iter); + ASSERT_RCU_READ_LOCKED(); ht = agt->events; key.name = name; @@ -1264,6 +1267,7 @@ struct agent_event *agent_find_event_by_trigger( LTTNG_ASSERT(agt); LTTNG_ASSERT(agt->events); + ASSERT_RCU_READ_LOCKED(); condition = lttng_trigger_get_const_condition(trigger); @@ -1336,6 +1340,8 @@ void agent_event_next_duplicate(const char *name, { struct agent_ht_key key; + ASSERT_RCU_READ_LOCKED(); + key.name = name; cds_lfht_next_duplicate(agt->events->ht, ht_match_event_by_name, @@ -1364,6 +1370,7 @@ struct agent_event *agent_find_event(const char *name, LTTNG_ASSERT(name); LTTNG_ASSERT(agt); LTTNG_ASSERT(agt->events); + ASSERT_RCU_READ_LOCKED(); ht = agt->events; key.name = name; diff --git a/src/bin/lttng-sessiond/buffer-registry.cpp b/src/bin/lttng-sessiond/buffer-registry.cpp index 3daca3c95..64e98333f 100644 --- a/src/bin/lttng-sessiond/buffer-registry.cpp +++ b/src/bin/lttng-sessiond/buffer-registry.cpp @@ -185,6 +185,8 @@ struct buffer_reg_uid *buffer_reg_uid_find(uint64_t session_id, struct buffer_reg_uid *reg = NULL, key; struct lttng_ht *ht = buffer_registry_uid; + ASSERT_RCU_READ_LOCKED(); + /* Setup key we are looking for. */ key.session_id = session_id; key.bits_per_long = bits_per_long; diff --git a/src/bin/lttng-sessiond/client.cpp b/src/bin/lttng-sessiond/client.cpp index ae5580487..7f3c81782 100644 --- a/src/bin/lttng-sessiond/client.cpp +++ b/src/bin/lttng-sessiond/client.cpp @@ -928,8 +928,6 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, lttcomm_sessiond_command_str((lttcomm_sessiond_command) cmd_ctx->lsm.cmd_type), cmd_ctx->lsm.cmd_type); - LTTNG_ASSERT(!rcu_read_ongoing()); - *sock_error = 0; switch (cmd_ctx->lsm.cmd_type) { diff --git a/src/bin/lttng-sessiond/consumer.cpp b/src/bin/lttng-sessiond/consumer.cpp index 95fc2c348..1a602762c 100644 --- a/src/bin/lttng-sessiond/consumer.cpp +++ b/src/bin/lttng-sessiond/consumer.cpp @@ -367,6 +367,8 @@ struct consumer_socket *consumer_find_socket_by_bitness(int bits, int consumer_fd; struct consumer_socket *socket = NULL; + ASSERT_RCU_READ_LOCKED(); + switch (bits) { case 64: consumer_fd = uatomic_read(&the_ust_consumerd64_fd); @@ -401,6 +403,8 @@ struct consumer_socket *consumer_find_socket(int key, struct lttng_ht_node_ulong *node; struct consumer_socket *socket = NULL; + ASSERT_RCU_READ_LOCKED(); + /* Negative keys are lookup failures */ if (key < 0 || consumer == NULL) { return NULL; @@ -447,6 +451,7 @@ void consumer_add_socket(struct consumer_socket *sock, { LTTNG_ASSERT(sock); LTTNG_ASSERT(consumer); + ASSERT_RCU_READ_LOCKED(); lttng_ht_add_unique_ulong(consumer->socks, &sock->node); } @@ -463,6 +468,7 @@ void consumer_del_socket(struct consumer_socket *sock, LTTNG_ASSERT(sock); LTTNG_ASSERT(consumer); + ASSERT_RCU_READ_LOCKED(); iter.iter.node = &sock->node.node; ret = lttng_ht_del(consumer->socks, &iter); @@ -483,8 +489,10 @@ static void destroy_socket_rcu(struct rcu_head *head) } /* - * Destroy and free socket pointer in a call RCU. Read side lock must be - * acquired before calling this function. + * Destroy and free socket pointer in a call RCU. The call must either: + * - have acquired the read side lock before calling this function, or + * - guarantee the validity of the `struct consumer_socket` object for the + * duration of the call. */ void consumer_destroy_socket(struct consumer_socket *sock) { @@ -1451,6 +1459,7 @@ int consumer_push_metadata(struct consumer_socket *socket, struct lttcomm_consumer_msg msg; LTTNG_ASSERT(socket); + ASSERT_RCU_READ_LOCKED(); DBG2("Consumer push metadata to consumer socket %d", *socket->fd_ptr); diff --git a/src/bin/lttng-sessiond/lttng-syscall.cpp b/src/bin/lttng-sessiond/lttng-syscall.cpp index 7dae12d9f..42e902b5e 100644 --- a/src/bin/lttng-sessiond/lttng-syscall.cpp +++ b/src/bin/lttng-sessiond/lttng-syscall.cpp @@ -156,6 +156,8 @@ static void destroy_syscall_ht(struct lttng_ht *ht) struct lttng_ht_iter iter; struct syscall *ksyscall; + ASSERT_RCU_READ_LOCKED(); + DBG3("Destroying syscall hash table."); if (!ht) { diff --git a/src/bin/lttng-sessiond/notification-thread-events.cpp b/src/bin/lttng-sessiond/notification-thread-events.cpp index 6f449fc63..cf18f63f7 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.cpp +++ b/src/bin/lttng-sessiond/notification-thread-events.cpp @@ -1313,6 +1313,8 @@ struct notification_client *get_client_from_socket(int socket, struct cds_lfht_node *node; struct notification_client *client = NULL; + ASSERT_RCU_READ_LOCKED(); + cds_lfht_lookup(state->client_socket_ht, hash_client_socket(socket), match_client_socket, @@ -1341,6 +1343,8 @@ struct notification_client *get_client_from_id(notification_client_id id, struct cds_lfht_node *node; struct notification_client *client = NULL; + ASSERT_RCU_READ_LOCKED(); + cds_lfht_lookup(state->client_id_ht, hash_client_id(id), match_client_id, @@ -1456,6 +1460,8 @@ struct lttng_session_trigger_list *get_session_trigger_list( struct cds_lfht_node *node; struct cds_lfht_iter iter; + ASSERT_RCU_READ_LOCKED(); + cds_lfht_lookup(state->session_triggers_ht, hash_key_str(session_name, lttng_ht_seed), match_session_trigger_list, @@ -2418,6 +2424,8 @@ int bind_trigger_to_matching_session(struct lttng_trigger *trigger, const char *session_name; struct lttng_session_trigger_list *trigger_list; + ASSERT_RCU_READ_LOCKED(); + condition = lttng_trigger_get_const_condition(trigger); switch (lttng_condition_get_type(condition)) { case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: @@ -2464,6 +2472,8 @@ int bind_trigger_to_matching_channels(struct lttng_trigger *trigger, struct cds_lfht_iter iter; struct channel_info *channel; + ASSERT_RCU_READ_LOCKED(); + cds_lfht_for_each_entry(state->channels_ht, &iter, channel, channels_ht_node) { struct lttng_trigger_list_element *trigger_list_element; @@ -3402,6 +3412,8 @@ int notification_thread_client_disconnect( int ret; struct lttng_condition_list_element *condition_list_element, *tmp; + ASSERT_RCU_READ_LOCKED(); + /* Acquire the client lock to disable its communication atomically. */ pthread_mutex_lock(&client->lock); client->communication.active = false; diff --git a/src/bin/lttng-sessiond/session.cpp b/src/bin/lttng-sessiond/session.cpp index b97f6eb2c..14de5468c 100644 --- a/src/bin/lttng-sessiond/session.cpp +++ b/src/bin/lttng-sessiond/session.cpp @@ -1143,6 +1143,7 @@ struct ltt_session *session_find_by_id(uint64_t id) struct lttng_ht_iter iter; struct ltt_session *ls; + ASSERT_RCU_READ_LOCKED(); ASSERT_LOCKED(ltt_session_list.lock); if (!ltt_sessions_ht_by_id) { diff --git a/src/bin/lttng-sessiond/snapshot.cpp b/src/bin/lttng-sessiond/snapshot.cpp index 44928edb0..727dc5db8 100644 --- a/src/bin/lttng-sessiond/snapshot.cpp +++ b/src/bin/lttng-sessiond/snapshot.cpp @@ -241,6 +241,7 @@ struct snapshot_output *snapshot_find_output_by_name(const char *name, LTTNG_ASSERT(snapshot); LTTNG_ASSERT(name); + ASSERT_RCU_READ_LOCKED(); cds_lfht_for_each_entry(snapshot->output_ht->ht, &iter.iter, output, node.node) { @@ -267,6 +268,7 @@ struct snapshot_output *snapshot_find_output_by_id(uint32_t id, struct snapshot_output *output = NULL; LTTNG_ASSERT(snapshot); + ASSERT_RCU_READ_LOCKED(); lttng_ht_lookup(snapshot->output_ht, (void *)((unsigned long) id), &iter); node = lttng_ht_iter_get_node_ulong(&iter); diff --git a/src/bin/lttng-sessiond/trace-ust.cpp b/src/bin/lttng-sessiond/trace-ust.cpp index 4be27f897..f3303efd7 100644 --- a/src/bin/lttng-sessiond/trace-ust.cpp +++ b/src/bin/lttng-sessiond/trace-ust.cpp @@ -167,6 +167,7 @@ struct ltt_ust_channel *trace_ust_find_channel_by_name(struct lttng_ht *ht, struct lttng_ht_node_str *node; struct lttng_ht_iter iter; + ASSERT_RCU_READ_LOCKED(); /* * If we receive an empty string for channel name, it means the * default channel name is requested. @@ -204,6 +205,7 @@ struct ltt_ust_event *trace_ust_find_event(struct lttng_ht *ht, LTTNG_ASSERT(name); LTTNG_ASSERT(ht); + ASSERT_RCU_READ_LOCKED(); key.name = name; key.filter = filter; diff --git a/src/bin/lttng-sessiond/ust-app.cpp b/src/bin/lttng-sessiond/ust-app.cpp index 08089e77e..62d323ee9 100644 --- a/src/bin/lttng-sessiond/ust-app.cpp +++ b/src/bin/lttng-sessiond/ust-app.cpp @@ -287,6 +287,7 @@ void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx, int ret; LTTNG_ASSERT(ua_ctx); + ASSERT_RCU_READ_LOCKED(); if (ua_ctx->obj) { pthread_mutex_lock(&app->sock_lock); @@ -321,6 +322,7 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event, int ret; LTTNG_ASSERT(ua_event); + ASSERT_RCU_READ_LOCKED(); free(ua_event->filter); if (ua_event->exclusion != NULL) @@ -443,6 +445,7 @@ void delete_ust_app_stream(int sock, struct ust_app_stream *stream, struct ust_app *app) { LTTNG_ASSERT(stream); + ASSERT_RCU_READ_LOCKED(); (void) release_ust_app_stream(sock, stream, app); free(stream); @@ -543,6 +546,7 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan, struct ust_registry_session *registry; LTTNG_ASSERT(ua_chan); + ASSERT_RCU_READ_LOCKED(); DBG3("UST app deleting channel %s", ua_chan->name); @@ -664,6 +668,7 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry, LTTNG_ASSERT(registry); LTTNG_ASSERT(socket); + ASSERT_RCU_READ_LOCKED(); metadata_key = registry->metadata_key; @@ -800,6 +805,7 @@ static int push_metadata(struct ust_registry_session *registry, LTTNG_ASSERT(registry); LTTNG_ASSERT(consumer); + ASSERT_RCU_READ_LOCKED(); pthread_mutex_lock(®istry->lock); if (registry->metadata_closed) { @@ -915,6 +921,7 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess, struct ust_registry_session *registry; LTTNG_ASSERT(ua_sess); + ASSERT_RCU_READ_LOCKED(); pthread_mutex_lock(&ua_sess->lock); @@ -1442,6 +1449,8 @@ struct ust_app *ust_app_find_by_sock(int sock) struct lttng_ht_node_ulong *node; struct lttng_ht_iter iter; + ASSERT_RCU_READ_LOCKED(); + lttng_ht_lookup(ust_app_ht_by_sock, (void *)((unsigned long) sock), &iter); node = lttng_ht_iter_get_node_ulong(&iter); if (node == NULL) { @@ -1464,6 +1473,8 @@ static struct ust_app *find_app_by_notify_sock(int sock) struct lttng_ht_node_ulong *node; struct lttng_ht_iter iter; + ASSERT_RCU_READ_LOCKED(); + lttng_ht_lookup(ust_app_ht_by_notify_sock, (void *)((unsigned long) sock), &iter); node = lttng_ht_iter_get_node_ulong(&iter); @@ -1532,6 +1543,7 @@ static struct ust_app_event_notifier_rule *find_ust_app_event_notifier_rule( struct ust_app_event_notifier_rule *event_notifier_rule = NULL; LTTNG_ASSERT(ht); + ASSERT_RCU_READ_LOCKED(); lttng_ht_lookup(ht, &token, &iter); node = lttng_ht_iter_get_node_u64(&iter); @@ -2809,6 +2821,7 @@ struct ust_app_ctx *find_ust_app_context(struct lttng_ht *ht, LTTNG_ASSERT(uctx); LTTNG_ASSERT(ht); + ASSERT_RCU_READ_LOCKED(); /* Lookup using the lttng_ust_context_type and a custom match fct. */ cds_lfht_lookup(ht->ht, ht->hash_fct((void *) uctx->ctx, lttng_ht_seed), @@ -2837,6 +2850,8 @@ int create_ust_app_channel_context(struct ust_app_channel *ua_chan, int ret = 0; struct ust_app_ctx *ua_ctx; + ASSERT_RCU_READ_LOCKED(); + DBG2("UST app adding context to channel %s", ua_chan->name); ua_ctx = find_ust_app_context(ua_chan->ctx, uctx); @@ -2938,6 +2953,8 @@ static int enable_ust_app_channel(struct ust_app_session *ua_sess, struct lttng_ht_node_str *ua_chan_node; struct ust_app_channel *ua_chan; + ASSERT_RCU_READ_LOCKED(); + lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter); ua_chan_node = lttng_ht_iter_get_node_str(&iter); if (ua_chan_node == NULL) { @@ -3367,6 +3384,7 @@ static int create_channel_per_uid(struct ust_app *app, LTTNG_ASSERT(usess); LTTNG_ASSERT(ua_sess); LTTNG_ASSERT(ua_chan); + ASSERT_RCU_READ_LOCKED(); DBG("UST app creating channel %s with per UID buffers", ua_chan->name); @@ -3587,6 +3605,7 @@ static int ust_app_channel_send(struct ust_app *app, LTTNG_ASSERT(usess->active); LTTNG_ASSERT(ua_sess); LTTNG_ASSERT(ua_chan); + ASSERT_RCU_READ_LOCKED(); /* Handle buffer type before sending the channel to the application. */ switch (usess->buffer_type) { @@ -3645,6 +3664,8 @@ static int ust_app_channel_allocate(struct ust_app_session *ua_sess, struct lttng_ht_node_str *ua_chan_node; struct ust_app_channel *ua_chan; + ASSERT_RCU_READ_LOCKED(); + /* Lookup channel in the ust app session */ lttng_ht_lookup(ua_sess->channels, (void *)uchan->name, &iter); ua_chan_node = lttng_ht_iter_get_node_str(&iter); @@ -3692,6 +3713,8 @@ int create_ust_app_event(struct ust_app_session *ua_sess, int ret = 0; struct ust_app_event *ua_event; + ASSERT_RCU_READ_LOCKED(); + ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr); if (ua_event == NULL) { /* Only failure mode of alloc_ust_app_event(). */ @@ -3746,6 +3769,8 @@ int create_ust_app_event_notifier_rule(struct lttng_trigger *trigger, int ret = 0; struct ust_app_event_notifier_rule *ua_event_notifier_rule; + ASSERT_RCU_READ_LOCKED(); + ua_event_notifier_rule = alloc_ust_app_event_notifier_rule(trigger); if (ua_event_notifier_rule == NULL) { ret = -ENOMEM; @@ -3803,6 +3828,7 @@ static int create_ust_app_metadata(struct ust_app_session *ua_sess, LTTNG_ASSERT(ua_sess); LTTNG_ASSERT(app); LTTNG_ASSERT(consumer); + ASSERT_RCU_READ_LOCKED(); registry = get_session_registry(ua_sess); /* The UST app session is held registry shall not be null. */ @@ -5790,6 +5816,8 @@ void ust_app_synchronize_event_notifier_rules(struct ust_app *app) struct ust_app_event_notifier_rule *event_notifier_rule; unsigned int count, i; + ASSERT_RCU_READ_LOCKED(); + if (!ust_app_supports_notifiers(app)) { goto end; } @@ -5941,6 +5969,7 @@ void ust_app_synchronize_all_channels(struct ltt_ust_session *usess, LTTNG_ASSERT(usess); LTTNG_ASSERT(ua_sess); LTTNG_ASSERT(app); + ASSERT_RCU_READ_LOCKED(); cds_lfht_for_each_entry(usess->domain_global.channels->ht, &uchan_iter, uchan, node.node) { @@ -6070,6 +6099,7 @@ void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app) { LTTNG_ASSERT(usess); LTTNG_ASSERT(usess->active); + ASSERT_RCU_READ_LOCKED(); DBG2("UST app global update for app sock %d for session id %" PRIu64, app->sock, usess->id); @@ -6104,6 +6134,8 @@ void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app) */ void ust_app_global_update_event_notifier_rules(struct ust_app *app) { + ASSERT_RCU_READ_LOCKED(); + DBG2("UST application global event notifier rules update: app = '%s', pid = %d", app->name, app->pid); @@ -6266,6 +6298,7 @@ static struct ust_app_session *find_session_by_objd(struct ust_app *app, struct ust_app_session *ua_sess = NULL; LTTNG_ASSERT(app); + ASSERT_RCU_READ_LOCKED(); lttng_ht_lookup(app->ust_sessions_objd, (void *)((unsigned long) objd), &iter); node = lttng_ht_iter_get_node_ulong(&iter); @@ -6293,6 +6326,7 @@ static struct ust_app_channel *find_channel_by_objd(struct ust_app *app, struct ust_app_channel *ua_chan = NULL; LTTNG_ASSERT(app); + ASSERT_RCU_READ_LOCKED(); lttng_ht_lookup(app->ust_objd, (void *)((unsigned long) objd), &iter); node = lttng_ht_iter_get_node_ulong(&iter); diff --git a/src/bin/lttng-sessiond/ust-registry.cpp b/src/bin/lttng-sessiond/ust-registry.cpp index baa58d731..7de533675 100644 --- a/src/bin/lttng-sessiond/ust-registry.cpp +++ b/src/bin/lttng-sessiond/ust-registry.cpp @@ -315,7 +315,7 @@ error: /* * Free event data structure. This does NOT delete it from any hash table. It's - * safe to pass a NULL pointer. This shoudl be called inside a call RCU if the + * safe to pass a NULL pointer. This should be called inside a call RCU if the * event is previously deleted from a rcu hash table. */ static void destroy_event(struct ust_registry_event *event) @@ -361,6 +361,7 @@ struct ust_registry_event *ust_registry_find_event( LTTNG_ASSERT(chan); LTTNG_ASSERT(name); LTTNG_ASSERT(sig); + ASSERT_RCU_READ_LOCKED(); /* Setup key for the match function. */ strncpy(key.name, name, sizeof(key.name)); @@ -509,6 +510,7 @@ void ust_registry_destroy_event(struct ust_registry_channel *chan, LTTNG_ASSERT(chan); LTTNG_ASSERT(event); + ASSERT_RCU_READ_LOCKED(); /* Delete the node first. */ iter.iter.node = &event->node.node; @@ -549,6 +551,8 @@ static struct ust_registry_enum *ust_registry_lookup_enum( struct lttng_ht_node_str *node; struct lttng_ht_iter iter; + ASSERT_RCU_READ_LOCKED(); + cds_lfht_lookup(session->enums->ht, ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed), ht_match_enum, reg_enum_lookup, &iter.iter); @@ -574,6 +578,8 @@ struct ust_registry_enum * struct lttng_ht_iter iter; struct ust_registry_enum reg_enum_lookup; + ASSERT_RCU_READ_LOCKED(); + memset(®_enum_lookup, 0, sizeof(reg_enum_lookup)); strncpy(reg_enum_lookup.name, enum_name, LTTNG_UST_ABI_SYM_NAME_LEN); reg_enum_lookup.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0'; @@ -681,6 +687,7 @@ static void ust_registry_destroy_enum(struct ust_registry_session *reg_session, LTTNG_ASSERT(reg_session); LTTNG_ASSERT(reg_enum); + ASSERT_RCU_READ_LOCKED(); /* Delete the node first. */ iter.iter.node = ®_enum->node.node; @@ -805,6 +812,7 @@ struct ust_registry_channel *ust_registry_channel_find( LTTNG_ASSERT(session); LTTNG_ASSERT(session->channels); + ASSERT_RCU_READ_LOCKED(); DBG3("UST registry channel finding key %" PRIu64, key); diff --git a/src/common/consumer/consumer.cpp b/src/common/consumer/consumer.cpp index 5730fd45c..0585b7d50 100644 --- a/src/common/consumer/consumer.cpp +++ b/src/common/consumer/consumer.cpp @@ -246,6 +246,8 @@ struct lttng_consumer_channel *consumer_find_channel(uint64_t key) struct lttng_ht_node_u64 *node; struct lttng_consumer_channel *channel = NULL; + ASSERT_RCU_READ_LOCKED(); + /* -1ULL keys are lookup failures */ if (key == (uint64_t) -1ULL) { return NULL; @@ -521,6 +523,7 @@ void lttng_consumer_cleanup_relayd(struct consumer_relayd_sock_pair *relayd) void consumer_flag_relayd_for_destroy(struct consumer_relayd_sock_pair *relayd) { LTTNG_ASSERT(relayd); + ASSERT_RCU_READ_LOCKED(); /* Set destroy flag for this object */ uatomic_set(&relayd->destroy_flag, 1); @@ -633,6 +636,7 @@ static int add_relayd(struct consumer_relayd_sock_pair *relayd) struct lttng_ht_iter iter; LTTNG_ASSERT(relayd); + ASSERT_RCU_READ_LOCKED(); lttng_ht_lookup(the_consumer_data.relayd_ht, &relayd->net_seq_idx, &iter); @@ -690,6 +694,8 @@ struct consumer_relayd_sock_pair *consumer_find_relayd(uint64_t key) struct lttng_ht_node_u64 *node; struct consumer_relayd_sock_pair *relayd = NULL; + ASSERT_RCU_READ_LOCKED(); + /* Negative keys are lookup failures */ if (key == (uint64_t) -1ULL) { goto error; @@ -3570,6 +3576,7 @@ error: LTTNG_ASSERT(ctx); LTTNG_ASSERT(relayd_sock); + ASSERT_RCU_READ_LOCKED(); DBG("Consumer adding relayd socket (idx: %" PRIu64 ")", net_seq_idx); @@ -3749,6 +3756,8 @@ static struct consumer_relayd_sock_pair *find_relayd_by_session_id(uint64_t id) struct lttng_ht_iter iter; struct consumer_relayd_sock_pair *relayd = NULL; + ASSERT_RCU_READ_LOCKED(); + /* Iterate over all relayd since they are indexed by net_seq_idx. */ cds_lfht_for_each_entry(the_consumer_data.relayd_ht->ht, &iter.iter, relayd, node.node) { @@ -4013,6 +4022,8 @@ int lttng_consumer_rotate_channel(struct lttng_consumer_channel *channel, struct lttng_dynamic_pointer_array streams_packet_to_open; size_t stream_idx; + ASSERT_RCU_READ_LOCKED(); + DBG("Consumer sample rotate position for channel %" PRIu64, key); lttng_dynamic_array_init(&stream_rotation_positions, @@ -4672,6 +4683,8 @@ int lttng_consumer_rotate_ready_streams(struct lttng_consumer_channel *channel, struct lttng_ht_iter iter; struct lttng_ht *ht = the_consumer_data.stream_per_chan_id_ht; + ASSERT_RCU_READ_LOCKED(); + rcu_read_lock(); DBG("Consumer rotate ready streams in channel %" PRIu64, key); diff --git a/src/common/macros.h b/src/common/macros.h index 1c131db78..43a4d692b 100644 --- a/src/common/macros.h +++ b/src/common/macros.h @@ -74,6 +74,7 @@ void *zmalloc(size_t len) #define member_sizeof(type, field) sizeof(((type *) 0)->field) #define ASSERT_LOCKED(lock) LTTNG_ASSERT(pthread_mutex_trylock(&lock)) +#define ASSERT_RCU_READ_LOCKED(lock) LTTNG_ASSERT(rcu_read_ongoing()) /* Attribute suitable to tag functions as having printf()-like arguments. */ #define ATTR_FORMAT_PRINTF(_string_index, _first_to_check) \ diff --git a/src/common/ust-consumer/ust-consumer.cpp b/src/common/ust-consumer/ust-consumer.cpp index 591c58fc5..cbfcaa851 100644 --- a/src/common/ust-consumer/ust-consumer.cpp +++ b/src/common/ust-consumer/ust-consumer.cpp @@ -876,6 +876,8 @@ static int setup_metadata(struct lttng_consumer_local_data *ctx, uint64_t key) int ret; struct lttng_consumer_channel *metadata; + ASSERT_RCU_READ_LOCKED(); + DBG("UST consumer setup metadata key %" PRIu64, key); metadata = consumer_find_channel(key); @@ -971,6 +973,7 @@ static int snapshot_metadata(struct lttng_consumer_channel *metadata_channel, LTTNG_ASSERT(path); LTTNG_ASSERT(ctx); + ASSERT_RCU_READ_LOCKED(); DBG("UST consumer snapshot metadata with key %" PRIu64 " at path %s", key, path); @@ -1086,6 +1089,7 @@ static int snapshot_channel(struct lttng_consumer_channel *channel, LTTNG_ASSERT(path); LTTNG_ASSERT(ctx); + ASSERT_RCU_READ_LOCKED(); rcu_read_lock(); @@ -2649,6 +2653,7 @@ enum sync_metadata_status lttng_ustconsumer_sync_metadata( LTTNG_ASSERT(ctx); LTTNG_ASSERT(metadata_stream); + ASSERT_RCU_READ_LOCKED(); metadata_channel = metadata_stream->chan; pthread_mutex_unlock(&metadata_stream->lock);