Introduce trigger hash table with tracer token as key
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Mon, 13 Jan 2020 18:52:51 +0000 (13:52 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 17 Dec 2020 22:41:58 +0000 (17:41 -0500)
This will allow easy lookup on reception of the tracer token coming
from the tracer.

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: Iee42539f0a664ead5ca03534549c6bbd5e505953

src/bin/lttng-sessiond/notification-thread-events.c
src/bin/lttng-sessiond/notification-thread.c
src/bin/lttng-sessiond/notification-thread.h

index 9bf146d3773ce6c4cb5a9ee894fbad6cdb481630..81fba4e6912253c7daf8b825594bf3106cc93361 100644 (file)
@@ -281,6 +281,17 @@ int match_trigger(struct cds_lfht_node *node, const void *key)
        return !!lttng_trigger_is_equal(trigger_key, trigger_ht_element->trigger);
 }
 
+static
+int match_trigger_token(struct cds_lfht_node *node, const void *key)
+{
+       const uint64_t *_key = key;
+       struct notification_trigger_tokens_ht_element *element;
+
+       element = caa_container_of(node,
+                       struct notification_trigger_tokens_ht_element, node);
+       return *_key == element->token;
+}
+
 static
 int match_client_list_condition(struct cds_lfht_node *node, const void *key)
 {
@@ -2322,6 +2333,7 @@ int handle_notification_thread_command_register_trigger(
        struct notification_client_list *client_list = NULL;
        struct lttng_trigger_ht_element *trigger_ht_element = NULL;
        struct notification_client_list_element *client_list_element;
+       struct notification_trigger_tokens_ht_element *trigger_tokens_ht_element = NULL;
        struct cds_lfht_node *node;
        struct cds_lfht_iter iter;
        const char* trigger_name;
@@ -2400,10 +2412,47 @@ int handle_notification_thread_command_register_trigger(
                goto error_free_ht_element;
        }
 
+       if (lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_EVENT_RULE_HIT) {
+               trigger_tokens_ht_element = zmalloc(sizeof(*trigger_tokens_ht_element));
+               if (!trigger_tokens_ht_element) {
+                       /* Fatal error. */
+                       ret = -1;
+                       cds_lfht_del(state->triggers_ht,
+                                       &trigger_ht_element->node);
+                       cds_lfht_del(state->triggers_by_name_uid_ht,
+                                       &trigger_ht_element->node_by_name_uid);
+                       goto error_free_ht_element;
+               }
+
+               /* Add trigger token to the trigger_tokens_ht. */
+               cds_lfht_node_init(&trigger_tokens_ht_element->node);
+               trigger_tokens_ht_element->token =
+                               LTTNG_OPTIONAL_GET(trigger->tracer_token);
+               trigger_tokens_ht_element->trigger = trigger;
+
+               node = cds_lfht_add_unique(state->trigger_tokens_ht,
+                               hash_key_u64(&trigger_tokens_ht_element->token,
+                                               lttng_ht_seed),
+                               match_trigger_token,
+                               &trigger_tokens_ht_element->token,
+                               &trigger_tokens_ht_element->node);
+               if (node != &trigger_tokens_ht_element->node) {
+                       /* Internal corruption, fatal error. */
+                       ret = -1;
+                       *cmd_result = LTTNG_ERR_TRIGGER_EXISTS;
+                       cds_lfht_del(state->triggers_ht,
+                                       &trigger_ht_element->node);
+                       cds_lfht_del(state->triggers_by_name_uid_ht,
+                                       &trigger_ht_element->node_by_name_uid);
+                       goto error_free_ht_element;
+               }
+       }
+
        /*
         * Ownership of the trigger and of its wrapper was transfered to
-        * the triggers_ht.
+        * the triggers_ht. Same for token ht element if necessary.
         */
+       trigger_tokens_ht_element = NULL;
        trigger_ht_element = NULL;
        free_trigger = false;
 
@@ -2585,6 +2634,7 @@ error_free_ht_element:
                                free_lttng_trigger_ht_element_rcu);
        }
 
+       free(trigger_tokens_ht_element);
 error:
        if (free_trigger) {
                lttng_trigger_destroy(trigger);
@@ -2600,6 +2650,13 @@ void free_lttng_trigger_ht_element_rcu(struct rcu_head *node)
                        rcu_node));
 }
 
+static
+void free_notification_trigger_tokens_ht_element_rcu(struct rcu_head *node)
+{
+       free(caa_container_of(node, struct notification_trigger_tokens_ht_element,
+                       rcu_node));
+}
+
 static
 int handle_notification_thread_command_unregister_trigger(
                struct notification_thread_state *state,
@@ -2648,6 +2705,28 @@ int handle_notification_thread_command_unregister_trigger(
                }
        }
 
+       if (lttng_condition_get_type(condition) ==
+                       LTTNG_CONDITION_TYPE_EVENT_RULE_HIT) {
+               struct notification_trigger_tokens_ht_element
+                               *trigger_tokens_ht_element;
+
+               cds_lfht_for_each_entry (state->trigger_tokens_ht, &iter,
+                               trigger_tokens_ht_element, node) {
+                       if (!lttng_trigger_is_equal(trigger,
+                                           trigger_tokens_ht_element->trigger)) {
+                               continue;
+                       }
+
+                       DBG("[notification-thread] Removed trigger from tokens_ht");
+                       cds_lfht_del(state->trigger_tokens_ht,
+                                       &trigger_tokens_ht_element->node);
+                       call_rcu(&trigger_tokens_ht_element->rcu_node,
+                                       free_notification_trigger_tokens_ht_element_rcu);
+
+                       break;
+               }
+       }
+
        if (is_trigger_action_notify(trigger)) {
                /*
                 * Remove and release the client list from
index 917cec5a2500f56f8f12350b74db94e423dc6928..1a7a16119972b3cebc45e7b3098e03a83fc81bef 100644 (file)
@@ -367,6 +367,10 @@ void fini_thread_state(struct notification_thread_state *state)
                ret = cds_lfht_destroy(state->triggers_by_name_uid_ht, NULL);
                assert(!ret);
        }
+       if (state->trigger_tokens_ht) {
+               ret = cds_lfht_destroy(state->trigger_tokens_ht, NULL);
+               assert(!ret);
+       }
        /*
         * Must be destroyed after all channels have been destroyed.
         * See comment in struct lttng_session_trigger_list.
@@ -490,6 +494,12 @@ int init_thread_state(struct notification_thread_handle *handle,
                goto error;
        }
 
+       state->trigger_tokens_ht = cds_lfht_new(DEFAULT_HT_SIZE,
+                       1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
+       if (!state->trigger_tokens_ht) {
+               goto error;
+       }
+
        CDS_INIT_LIST_HEAD(&state->tracer_event_sources_list);
 
        state->executor = action_executor_create(handle);
index bfce4cd3fbb8c8bca208f7b0d753f7e4446a73db..83a5bea79e175240b462e0703c743220ee98ba02 100644 (file)
@@ -47,6 +47,15 @@ struct notification_event_tracer_event_source_element {
        struct cds_list_head node;
 };
 
+struct notification_trigger_tokens_ht_element {
+       uint64_t token;
+       /* Weak reference to the trigger. */
+       struct lttng_trigger *trigger;
+       struct cds_lfht_node node;
+       /* call_rcu delayed reclaim. */
+       struct rcu_head rcu_node;
+};
+
 struct notification_thread_handle {
        /*
         * Queue of struct notification command.
@@ -258,6 +267,7 @@ struct notification_thread_state {
        struct cds_lfht *sessions_ht;
        struct cds_lfht *triggers_ht;
        struct cds_lfht *triggers_by_name_uid_ht;
+       struct cds_lfht *trigger_tokens_ht;
        struct {
                uint64_t next_tracer_token;
                uint64_t name_offset;
This page took 0.029545 seconds and 4 git commands to generate.