/* list of struct lttng_kernel_bytecode_runtime, sorted by seqnum */
struct list_head filter_bytecode_runtime_head;
- struct hlist_node hlist_node; /* node in events hash table */
+ struct hlist_node hlist_name_node; /* node in events name hash table */
struct list_head node; /* node in event list */
enum lttng_kernel_abi_instrumentation instrumentation;
struct lttng_kernel_event_session_common_private parent;
struct lttng_kernel_event_counter *pub; /* Public event interface */
+ struct hlist_node hlist_key_node; /* node in events key hash table */
char key[LTTNG_KEY_TOKEN_STRING_LEN_MAX];
};
struct list_head enablers_head; /* List of event enablers */
struct lttng_event_ht events_name_ht; /* Hash table of events, indexed by name */
+ struct lttng_event_ht events_key_ht; /* Hash table of events, indexed by key */
struct list_head node; /* Session list */
unsigned int free_chan_id; /* Next chan ID to allocate */
}
}
+static inline
+struct lttng_event_ht *lttng_get_events_key_ht_from_enabler(struct lttng_event_enabler_common *event_enabler)
+{
+ switch (event_enabler->enabler_type) {
+ case LTTNG_EVENT_ENABLER_TYPE_RECORDER:
+ lttng_fallthrough;
+ case LTTNG_EVENT_ENABLER_TYPE_COUNTER:
+ {
+ struct lttng_event_enabler_session_common *event_enabler_session =
+ container_of(event_enabler, struct lttng_event_enabler_session_common, parent);
+ return &event_enabler_session->chan->session->priv->events_key_ht;
+ }
+ case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER:
+ lttng_fallthrough;
+ default:
+ return NULL;
+ }
+}
+
static inline
struct list_head *lttng_get_event_list_head_from_enabler(struct lttng_event_enabler_common *event_enabler)
{
INIT_LIST_HEAD(&session_priv->enablers_head);
for (i = 0; i < LTTNG_EVENT_HT_SIZE; i++)
INIT_HLIST_HEAD(&session_priv->events_name_ht.table[i]);
+ for (i = 0; i < LTTNG_EVENT_HT_SIZE; i++)
+ INIT_HLIST_HEAD(&session_priv->events_key_ht.table[i]);
list_add(&session_priv->node, &sessions);
if (lttng_id_tracker_init(&session->pid_tracker, session, TRACKER_PID))
static
struct lttng_kernel_event_common *lttng_kernel_event_alloc(struct lttng_event_enabler_common *event_enabler,
+ struct hlist_head *key_head,
const char *key_string)
{
struct lttng_kernel_abi_event *event_param = &event_enabler->event_param;
struct lttng_kernel_event_recorder_private *event_recorder_priv;
struct lttng_kernel_channel_buffer *chan = event_recorder_enabler->chan;
+ WARN_ON_ONCE(key_head); /* not implemented. */
event_recorder = kmem_cache_zalloc(event_recorder_cache, GFP_KERNEL);
if (!event_recorder)
return NULL;
struct lttng_kernel_event_notifier *event_notifier;
struct lttng_kernel_event_notifier_private *event_notifier_priv;
+ WARN_ON_ONCE(key_head); /* not implemented. */
event_notifier = kmem_cache_zalloc(event_notifier_cache, GFP_KERNEL);
if (!event_notifier)
return NULL;
struct lttng_kernel_event_counter *event_counter;
struct lttng_kernel_event_counter_private *event_counter_priv;
struct lttng_kernel_channel_counter *chan = event_counter_enabler->chan;
+ bool key_found = false;
event_counter = kmem_cache_zalloc(event_counter_cache, GFP_KERNEL);
if (!event_counter)
if (!chan->priv->parent.coalesce_hits)
event_counter->priv->parent.parent.user_token = event_counter_enabler->parent.parent.user_token;
strcpy(event_counter_priv->key, key_string);
- event_counter->priv->parent.id = chan->priv->free_index++;
+ if (key_head) {
+ struct lttng_kernel_event_counter_private *event_counter_priv_iter;
+
+ lttng_hlist_for_each_entry(event_counter_priv_iter, key_head, hlist_key_node) {
+ if (!strcmp(key_string, event_counter_priv_iter->key)) {
+ /* Same key, use same id. */
+ key_found = true;
+ event_counter->priv->parent.id = event_counter_priv_iter->parent.id;
+ break;
+ }
+ }
+ }
+ if (!key_found)
+ event_counter->priv->parent.id = chan->priv->free_index++;
return &event_counter->parent;
}
default:
const struct lttng_kernel_event_desc *event_desc)
{
char key_string[LTTNG_KEY_TOKEN_STRING_LEN_MAX] = { 0 };
- struct lttng_event_ht *events_ht = lttng_get_events_name_ht_from_enabler(event_enabler);
+ struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(event_enabler);
+ struct lttng_event_ht *events_key_ht = lttng_get_events_key_ht_from_enabler(event_enabler);
struct list_head *event_list_head = lttng_get_event_list_head_from_enabler(event_enabler);
struct lttng_kernel_abi_event *event_param = &event_enabler->event_param;
enum lttng_kernel_abi_instrumentation itype = event_param->instrumentation;
struct lttng_kernel_event_common_private *event_priv_iter;
struct lttng_kernel_event_common *event;
- struct hlist_head *head;
+ struct hlist_head *name_head, *key_head = NULL;
const char *event_name;
int ret;
goto type_error;
}
- head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, event_name);
- lttng_hlist_for_each_entry(event_priv_iter, head, hlist_node) {
+ name_head = utils_borrow_hash_table_bucket(events_name_ht->table, LTTNG_EVENT_HT_SIZE, event_name);
+ lttng_hlist_for_each_entry(event_priv_iter, name_head, hlist_name_node) {
if (lttng_event_enabler_event_name_key_match_event(event_enabler,
event_name, key_string, event_priv_iter->pub)) {
ret = -EEXIST;
}
}
- event = lttng_kernel_event_alloc(event_enabler, key_string);
+ if (key_string[0] != '\0')
+ key_head = utils_borrow_hash_table_bucket(events_key_ht->table, LTTNG_EVENT_HT_SIZE, key_string);
+
+ event = lttng_kernel_event_alloc(event_enabler, key_head, key_string);
if (!event) {
ret = -ENOMEM;
goto alloc_error;
event->enabled = 0;
event->priv->registered = 1;
- event_return = lttng_kernel_event_alloc(event_enabler, key_string);
+ event_return = lttng_kernel_event_alloc(event_enabler, key_head, key_string);
if (!event) {
ret = -ENOMEM;
goto alloc_error;
goto statedump_error;
}
list_add(&event_return->priv->node, event_list_head);
+ if (key_head) {
+ struct lttng_kernel_event_counter_private *event_return_counter_priv =
+ container_of(event_return->priv, struct lttng_kernel_event_counter_private, parent.parent);
+ hlist_add_head(&event_return_counter_priv->hlist_key_node, key_head);
+ }
ret = lttng_append_event_to_channel_map(event_enabler, event, event_name);
WARN_ON_ONCE(ret);
ret = lttng_append_event_to_channel_map(event_enabler, event_return, event_name);
goto register_error;
}
- hlist_add_head(&event->priv->hlist_node, head);
+ hlist_add_head(&event->priv->hlist_name_node, name_head);
+ if (key_head) {
+ struct lttng_kernel_event_counter_private *event_counter_priv =
+ container_of(event->priv, struct lttng_kernel_event_counter_private, parent.parent);
+ hlist_add_head(&event_counter_priv->hlist_key_node, key_head);
+ }
list_add(&event->priv->node, event_list_head);
return event;
/* Remove from event list. */
list_del(&event->priv->node);
/* Remove from event hash table. */
- hlist_del(&event->priv->hlist_node);
+ hlist_del(&event->priv->hlist_name_node);
+
+ switch (event->type) {
+ case LTTNG_KERNEL_EVENT_TYPE_COUNTER:
+ {
+ struct lttng_kernel_event_counter_private *event_counter_priv =
+ container_of(event->priv, struct lttng_kernel_event_counter_private, parent.parent);
+ if (event_counter_priv->key[0] != '\0')
+ hlist_del(&event_counter_priv->hlist_key_node);
+ break;
+ }
+ case LTTNG_KERNEL_EVENT_TYPE_RECORDER:
+ lttng_fallthrough;
+ case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER:
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ }
switch (event->priv->instrumentation) {
case LTTNG_KERNEL_ABI_TRACEPOINT:
void lttng_syscall_event_enabler_create_matching_syscall_table_events(struct lttng_event_enabler_common *syscall_event_enabler_common,
const struct trace_syscall_entry *table, size_t table_len, enum sc_type type)
{
- struct lttng_event_ht *events_ht = lttng_get_events_name_ht_from_enabler(syscall_event_enabler_common);
+ struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(syscall_event_enabler_common);
const struct lttng_kernel_event_desc *desc;
unsigned int i;
/*
* Check if already created.
*/
- head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
- lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
+ head = utils_borrow_hash_table_bucket(events_name_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
+ lttng_hlist_for_each_entry(event_priv, head, hlist_name_node) {
if (lttng_event_enabler_event_name_key_match_event(syscall_event_enabler_common, desc->event_name, key_string, event_priv->pub)) {
found = true;
break;
void create_unknown_syscall_event(struct lttng_event_enabler_common *event_enabler, enum sc_type type)
{
char key_string[LTTNG_KEY_TOKEN_STRING_LEN_MAX] = { 0 };
- struct lttng_event_ht *events_ht = lttng_get_events_name_ht_from_enabler(event_enabler);
+ struct lttng_event_ht *events_name_ht = lttng_get_events_name_ht_from_enabler(event_enabler);
struct lttng_kernel_event_common_private *event_priv;
const struct lttng_kernel_event_desc *desc;
bool found = false;
/*
* Check if already created.
*/
- head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
- lttng_hlist_for_each_entry(event_priv, head, hlist_node) {
+ head = utils_borrow_hash_table_bucket(events_name_ht->table, LTTNG_EVENT_HT_SIZE, desc->event_name);
+ lttng_hlist_for_each_entry(event_priv, head, hlist_name_node) {
if (lttng_event_enabler_event_name_key_match_event(event_enabler, desc->event_name, key_string, event_priv->pub)) {
found = true;
break;