X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flttng-events.c;h=2b4b1039803222cf0e383ad943c6dc991cc1dcb1;hb=6a338ba4d659df6744bf8489f2248fc2021fbc43;hp=981ee30c326cb65be35ff7b6d107d600e09633a4;hpb=c4e310594ea3bd6d5110bcda972c0920e95a6eaf;p=lttng-modules.git diff --git a/src/lttng-events.c b/src/lttng-events.c index 981ee30c..2b4b1039 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -71,7 +71,7 @@ static void lttng_event_enabler_sync(struct lttng_event_enabler_common *event_en static void _lttng_event_destroy(struct lttng_kernel_event_common *event); static void _lttng_channel_destroy(struct lttng_kernel_channel_buffer *chan); -static int _lttng_event_unregister(struct lttng_kernel_event_common *event); +static void _lttng_event_unregister(struct lttng_kernel_event_common *event); static int _lttng_event_recorder_metadata_statedump(struct lttng_kernel_event_common *event); static @@ -360,10 +360,8 @@ void lttng_session_destroy(struct lttng_kernel_session *session) ret = lttng_syscalls_unregister_syscall_table(&chan_priv->parent.syscall_table); WARN_ON(ret); } - list_for_each_entry(event_recorder_priv, &session->priv->events, parent.node) { - ret = _lttng_event_unregister(&event_recorder_priv->pub->parent); - WARN_ON(ret); - } + list_for_each_entry(event_recorder_priv, &session->priv->events, parent.node) + _lttng_event_unregister(&event_recorder_priv->pub->parent); synchronize_trace(); /* Wait for in-flight events to complete */ list_for_each_entry(chan_priv, &session->priv->chan, node) { ret = lttng_syscalls_destroy_syscall_table(&chan_priv->parent.syscall_table); @@ -410,10 +408,8 @@ void lttng_event_notifier_group_destroy( WARN_ON(ret); list_for_each_entry_safe(event_notifier_priv, tmpevent_notifier_priv, - &event_notifier_group->event_notifiers_head, parent.node) { - ret = _lttng_event_unregister(&event_notifier_priv->pub->parent); - WARN_ON(ret); - } + &event_notifier_group->event_notifiers_head, parent.node) + _lttng_event_unregister(&event_notifier_priv->pub->parent); /* Wait for in-flight event notifier to complete */ synchronize_trace(); @@ -1061,22 +1057,20 @@ int lttng_kernel_event_notifier_clear_error_counter(struct lttng_kernel_event_co * Supports event creation while tracing session is active. * Needs to be called with sessions mutex held. */ -static -struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct lttng_event_recorder_enabler *event_enabler, +struct lttng_kernel_event_common *_lttng_kernel_event_create(struct lttng_event_enabler_common *event_enabler, const struct lttng_kernel_event_desc *event_desc) { - struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(&event_enabler->parent); - struct list_head *event_list_head = lttng_get_event_list_head_from_enabler(&event_enabler->parent); - struct lttng_kernel_abi_event *event_param = &event_enabler->parent.event_param; + struct lttng_event_ht *events_ht = lttng_get_event_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; struct lttng_kernel_event_common *event; - struct lttng_kernel_event_recorder *event_recorder; const char *event_name; struct hlist_head *head; int ret; - if (!lttng_kernel_event_id_available(&event_enabler->parent)) { + if (!lttng_kernel_event_id_available(event_enabler)) { ret = -EMFILE; goto full; } @@ -1108,18 +1102,17 @@ struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct l head = utils_borrow_hash_table_bucket(events_ht->table, LTTNG_EVENT_HT_SIZE, event_name); lttng_hlist_for_each_entry(event_priv, head, hlist_node) { - if (lttng_event_enabler_event_name_match_event(&event_enabler->parent, event_name, event_priv->pub)) { + if (lttng_event_enabler_event_name_match_event(event_enabler, event_name, event_priv->pub)) { ret = -EEXIST; goto exist; } } - event = lttng_kernel_event_alloc(&event_enabler->parent); + event = lttng_kernel_event_alloc(event_enabler); if (!event) { ret = -ENOMEM; goto alloc_error; } - event_recorder = container_of(event, struct lttng_kernel_event_recorder, parent); switch (itype) { case LTTNG_KERNEL_ABI_TRACEPOINT: @@ -1172,7 +1165,7 @@ struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct l event->enabled = 0; event->priv->registered = 1; - event_return = lttng_kernel_event_alloc(&event_enabler->parent); + event_return = lttng_kernel_event_alloc(event_enabler); if (!event) { ret = -ENOMEM; goto alloc_error; @@ -1280,240 +1273,33 @@ struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct l ret = -EINVAL; goto register_error; } + ret = _lttng_event_recorder_metadata_statedump(event); WARN_ON_ONCE(ret > 0); if (ret) { goto statedump_error; } - hlist_add_head(&event->priv->hlist_node, head); - list_add(&event->priv->node, event_list_head); - return event_recorder; - -statedump_error: - /* If a statedump error occurs, events will not be readable. */ -register_error: - lttng_kernel_event_free(event); -alloc_error: -exist: -type_error: -full: - return ERR_PTR(ret); -} - -static -struct lttng_kernel_event_notifier *_lttng_kernel_event_notifier_create(struct lttng_event_notifier_enabler *event_enabler, - const struct lttng_kernel_event_desc *event_desc) -{ - struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(&event_enabler->parent); - struct list_head *event_list_head = lttng_get_event_list_head_from_enabler(&event_enabler->parent); - struct lttng_kernel_abi_event *event_param = &event_enabler->parent.event_param; - enum lttng_kernel_abi_instrumentation itype = event_param->instrumentation; - struct lttng_kernel_event_common_private *event_priv; - struct lttng_kernel_event_common *event; - struct lttng_kernel_event_notifier *event_notifier; - const char *event_name; - struct hlist_head *head; - int ret; - - switch (itype) { - case LTTNG_KERNEL_ABI_TRACEPOINT: - event_name = event_desc->event_name; - break; - - case LTTNG_KERNEL_ABI_KPROBE: - lttng_fallthrough; - case LTTNG_KERNEL_ABI_UPROBE: - lttng_fallthrough; - case LTTNG_KERNEL_ABI_SYSCALL: - event_name = event_param->name; - break; - - case LTTNG_KERNEL_ABI_KRETPROBE: - lttng_fallthrough; - case LTTNG_KERNEL_ABI_FUNCTION: - lttng_fallthrough; - case LTTNG_KERNEL_ABI_NOOP: - lttng_fallthrough; - default: - WARN_ON_ONCE(1); - ret = -EINVAL; - 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, head, hlist_node) { - if (lttng_event_enabler_event_name_match_event(&event_enabler->parent, event_name, event_priv->pub)) { - ret = -EEXIST; - goto exist; - } - } - - event = lttng_kernel_event_alloc(&event_enabler->parent); - if (!event) { - ret = -ENOMEM; - goto alloc_error; - } - event_notifier = container_of(event, struct lttng_kernel_event_notifier, parent); - - switch (itype) { - case LTTNG_KERNEL_ABI_TRACEPOINT: - /* Event will be enabled by enabler sync. */ - event->enabled = 0; - event->priv->registered = 0; - event->priv->desc = lttng_event_desc_get(event_name); - if (!event->priv->desc) { - ret = -ENOENT; - goto register_error; - } - /* Populate lttng_event_notifier structure before event registration. */ - smp_wmb(); - break; - - case LTTNG_KERNEL_ABI_KPROBE: - /* - * Needs to be explicitly enabled after creation, since - * we may want to apply filters. - */ - event->enabled = 0; - event->priv->registered = 1; - /* - * Populate lttng_event_notifier structure before event - * registration. - */ - smp_wmb(); - ret = lttng_kprobes_register_event(event_param->u.kprobe.symbol_name, - event_param->u.kprobe.symbol_name, - event_param->u.kprobe.offset, - event_param->u.kprobe.addr, - event); - if (ret) { - ret = -EINVAL; - goto register_error; - } - ret = try_module_get(event->priv->desc->owner); - WARN_ON_ONCE(!ret); - break; - - case LTTNG_KERNEL_ABI_SYSCALL: - /* - * Needs to be explicitly enabled after creation, since - * we may want to apply filters. - */ - event->enabled = 0; - event->priv->registered = 0; - event->priv->desc = event_desc; - switch (event_param->u.syscall.entryexit) { - case LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT: - ret = -EINVAL; - goto register_error; - case LTTNG_KERNEL_ABI_SYSCALL_ENTRY: - event->priv->u.syscall.entryexit = LTTNG_SYSCALL_ENTRY; - break; - case LTTNG_KERNEL_ABI_SYSCALL_EXIT: - event->priv->u.syscall.entryexit = LTTNG_SYSCALL_EXIT; - break; - } - switch (event_param->u.syscall.abi) { - case LTTNG_KERNEL_ABI_SYSCALL_ABI_ALL: - ret = -EINVAL; - goto register_error; - case LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE: - event->priv->u.syscall.abi = LTTNG_SYSCALL_ABI_NATIVE; - break; - case LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT: - event->priv->u.syscall.abi = LTTNG_SYSCALL_ABI_COMPAT; - break; - } - - if (!event->priv->desc) { - ret = -EINVAL; - goto register_error; - } - break; - - case LTTNG_KERNEL_ABI_UPROBE: - /* - * Needs to be explicitly enabled after creation, since - * we may want to apply filters. - */ - event->enabled = 0; - event->priv->registered = 1; - - /* - * Populate lttng_event_notifier structure before - * event_notifier registration. - */ - smp_wmb(); - - ret = lttng_uprobes_register_event(event_param->name, - event_param->u.uprobe.fd, - event); - if (ret) - goto register_error; - ret = try_module_get(event->priv->desc->owner); - WARN_ON_ONCE(!ret); - break; - - case LTTNG_KERNEL_ABI_KRETPROBE: - lttng_fallthrough; - case LTTNG_KERNEL_ABI_FUNCTION: - lttng_fallthrough; - case LTTNG_KERNEL_ABI_NOOP: - lttng_fallthrough; - default: - WARN_ON_ONCE(1); - ret = -EINVAL; - goto register_error; - } ret = lttng_kernel_event_notifier_clear_error_counter(event); if (ret) goto register_error; - list_add(&event->priv->node, event_list_head); hlist_add_head(&event->priv->hlist_node, head); + list_add(&event->priv->node, event_list_head); - return event_notifier; + return event; +statedump_error: + /* If a statedump error occurs, events will not be readable. */ register_error: lttng_kernel_event_free(event); alloc_error: exist: type_error: +full: return ERR_PTR(ret); } -struct lttng_kernel_event_common *_lttng_kernel_event_create(struct lttng_event_enabler_common *event_enabler, - const struct lttng_kernel_event_desc *event_desc) -{ - switch (event_enabler->enabler_type) { - case LTTNG_EVENT_ENABLER_TYPE_RECORDER: - { - struct lttng_event_recorder_enabler *event_recorder_enabler = - container_of(event_enabler, struct lttng_event_recorder_enabler, parent); - struct lttng_kernel_event_recorder *event_recorder; - - event_recorder = _lttng_kernel_event_recorder_create(event_recorder_enabler, event_desc); - if (!event_recorder) - return NULL; - return &event_recorder->parent; - } - case LTTNG_EVENT_ENABLER_TYPE_NOTIFIER: - { - struct lttng_event_notifier_enabler *event_notifier_enabler = - container_of(event_enabler, struct lttng_event_notifier_enabler, parent); - struct lttng_kernel_event_notifier *event_notifier; - - event_notifier = _lttng_kernel_event_notifier_create(event_notifier_enabler, event_desc); - if (!event_notifier) - return NULL; - return &event_notifier->parent; - } - default: - return NULL; - } -} - struct lttng_kernel_event_common *lttng_kernel_event_create(struct lttng_event_enabler_common *event_enabler, const struct lttng_kernel_event_desc *event_desc) { @@ -1525,8 +1311,6 @@ struct lttng_kernel_event_common *lttng_kernel_event_create(struct lttng_event_e return event; } - - int lttng_kernel_counter_read(struct lttng_counter *counter, const size_t *dim_indexes, int32_t cpu, int64_t *val, bool *overflow, bool *underflow) @@ -1549,15 +1333,14 @@ int lttng_kernel_counter_clear(struct lttng_counter *counter, return counter->ops->counter_clear(counter->counter, dim_indexes); } -/* Only used for tracepoints for now. */ +/* Only used for tracepoints and system calls for now. */ static void register_event(struct lttng_kernel_event_common *event) { const struct lttng_kernel_event_desc *desc; int ret = -EINVAL; - if (event->priv->registered) - return; + WARN_ON_ONCE(event->priv->registered); desc = event->priv->desc; switch (event->priv->instrumentation) { @@ -1595,18 +1378,19 @@ void register_event(struct lttng_kernel_event_common *event) default: WARN_ON_ONCE(1); } + WARN_ON_ONCE(ret); if (!ret) event->priv->registered = 1; } -int _lttng_event_unregister(struct lttng_kernel_event_common *event) +static +void unregister_event(struct lttng_kernel_event_common *event) { struct lttng_kernel_event_common_private *event_priv = event->priv; const struct lttng_kernel_event_desc *desc; int ret = -EINVAL; - if (!event_priv->registered) - return 0; + WARN_ON_ONCE(!event->priv->registered); desc = event_priv->desc; switch (event_priv->instrumentation) { @@ -1658,9 +1442,16 @@ int _lttng_event_unregister(struct lttng_kernel_event_common *event) default: WARN_ON_ONCE(1); } + WARN_ON_ONCE(ret); if (!ret) event_priv->registered = 0; - return ret; +} + +static +void _lttng_event_unregister(struct lttng_kernel_event_common *event) +{ + if (event->priv->registered) + unregister_event(event); } /* @@ -2275,7 +2066,7 @@ struct lttng_enabler_ref *lttng_enabler_ref( } static -void lttng_create_tracepoint_event_if_missing(struct lttng_event_enabler_common *event_enabler) +void lttng_event_enabler_create_tracepoint_events_if_missing(struct lttng_event_enabler_common *event_enabler) { struct lttng_event_ht *events_ht = lttng_get_event_ht_from_enabler(event_enabler); struct lttng_kernel_probe_desc *probe_desc; @@ -2291,7 +2082,7 @@ void lttng_create_tracepoint_event_if_missing(struct lttng_event_enabler_common */ list_for_each_entry(probe_desc, probe_list, head) { for (i = 0; i < probe_desc->nr_events; i++) { - int found = 0; + bool found = false; struct hlist_head *head; struct lttng_kernel_event_common *event; struct lttng_kernel_event_common_private *event_priv; @@ -2305,8 +2096,10 @@ void lttng_create_tracepoint_event_if_missing(struct lttng_event_enabler_common */ 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) { - if (lttng_event_enabler_desc_match_event(event_enabler, desc, event_priv->pub)) - found = 1; + if (lttng_event_enabler_desc_match_event(event_enabler, desc, event_priv->pub)) { + found = true; + break; + } } if (found) continue; @@ -2315,7 +2108,7 @@ void lttng_create_tracepoint_event_if_missing(struct lttng_event_enabler_common * We need to create an event for this event probe. */ event = _lttng_kernel_event_create(event_enabler, desc); - if (!event) { + if (IS_ERR(event)) { printk(KERN_INFO "LTTng: Unable to create event %s\n", probe_desc->event_desc[i]->event_name); } @@ -2323,29 +2116,23 @@ void lttng_create_tracepoint_event_if_missing(struct lttng_event_enabler_common } } -static -void lttng_create_syscall_event_if_missing(struct lttng_event_enabler_common *event_enabler) -{ - int ret; - - ret = lttng_syscalls_register_event(event_enabler); - WARN_ON_ONCE(ret); -} - /* * Create event if it is missing and present in the list of tracepoint probes. * Should be called with sessions mutex held. */ static -void lttng_create_event_if_missing(struct lttng_event_enabler_common *event_enabler) +void lttng_event_enabler_create_events_if_missing(struct lttng_event_enabler_common *event_enabler) { + int ret; + switch (event_enabler->event_param.instrumentation) { case LTTNG_KERNEL_ABI_TRACEPOINT: - lttng_create_tracepoint_event_if_missing(event_enabler); + lttng_event_enabler_create_tracepoint_events_if_missing(event_enabler); break; case LTTNG_KERNEL_ABI_SYSCALL: - lttng_create_syscall_event_if_missing(event_enabler); + ret = lttng_event_enabler_create_syscall_events_if_missing(event_enabler); + WARN_ON_ONCE(ret); break; default: @@ -2403,7 +2190,7 @@ int lttng_event_enabler_ref_events(struct lttng_event_enabler_common *event_enab lttng_syscall_table_set_wildcard_all(event_enabler); /* First ensure that probe events are created for this enabler. */ - lttng_create_event_if_missing(event_enabler); + lttng_event_enabler_create_events_if_missing(event_enabler); /* Link the created event with its associated enabler. */ list_for_each_entry(event_priv, event_list_head, node) { @@ -2868,9 +2655,11 @@ void lttng_sync_event_list(struct list_head *event_enabler_list, * Sync tracepoint registration with event enabled state. */ if (enabled) { - register_event(event); + if (!event_priv->registered) + register_event(event); } else { - _lttng_event_unregister(event); + if (event_priv->registered) + unregister_event(event); } lttng_event_sync_filter_state(event);