X-Git-Url: http://git.liburcu.org/?p=lttng-modules.git;a=blobdiff_plain;f=lttng-probes.c;h=f95391fd0c0c3790c58ada4a82a4f8e43065f82a;hp=4a2bb630e8503412c3524ddc468aef749c7f2280;hb=HEAD;hpb=2df37e95fa4303ecc0db41334452665491533641 diff --git a/lttng-probes.c b/lttng-probes.c deleted file mode 100644 index 4a2bb630..00000000 --- a/lttng-probes.c +++ /dev/null @@ -1,324 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) - * - * lttng-probes.c - * - * Holds LTTng probes registry. - * - * Copyright (C) 2010-2012 Mathieu Desnoyers - */ - -#include -#include -#include -#include - -#include - -/* - * probe list is protected by sessions lock. - */ -static LIST_HEAD(_probe_list); - -/* - * List of probes registered by not yet processed. - */ -static LIST_HEAD(lazy_probe_init); - -/* - * lazy_nesting counter ensures we don't trigger lazy probe registration - * fixup while we are performing the fixup. It is protected by the - * sessions lock. - */ -static int lazy_nesting; - -DEFINE_PER_CPU(struct lttng_dynamic_len_stack, lttng_dynamic_len_stack); - -EXPORT_PER_CPU_SYMBOL_GPL(lttng_dynamic_len_stack); - -/* - * Called under sessions lock. - */ -static -int check_event_provider(struct lttng_probe_desc *desc) -{ - int i; - size_t provider_name_len; - - provider_name_len = strnlen(desc->provider, - LTTNG_KERNEL_SYM_NAME_LEN - 1); - for (i = 0; i < desc->nr_events; i++) { - if (strncmp(desc->event_desc[i]->name, - desc->provider, - provider_name_len)) - return 0; /* provider mismatch */ - /* - * The event needs to contain at least provider name + _ + - * one or more letter. - */ - if (strlen(desc->event_desc[i]->name) <= provider_name_len + 1) - return 0; /* provider mismatch */ - if (desc->event_desc[i]->name[provider_name_len] != '_') - return 0; /* provider mismatch */ - } - return 1; -} - -/* - * Called under sessions lock. - */ -static -void lttng_lazy_probe_register(struct lttng_probe_desc *desc) -{ - struct lttng_probe_desc *iter; - struct list_head *probe_list; - - /* - * Each provider enforce that every event name begins with the - * provider name. Check this in an assertion for extra - * carefulness. This ensures we cannot have duplicate event - * names across providers. - */ - WARN_ON_ONCE(!check_event_provider(desc)); - - /* - * The provider ensures there are no duplicate event names. - * Duplicated TRACEPOINT_EVENT event names would generate a - * compile-time error due to duplicated symbol names. - */ - - /* - * We sort the providers by struct lttng_probe_desc pointer - * address. - */ - probe_list = &_probe_list; - list_for_each_entry_reverse(iter, probe_list, head) { - BUG_ON(iter == desc); /* Should never be in the list twice */ - if (iter < desc) { - /* We belong to the location right after iter. */ - list_add(&desc->head, &iter->head); - goto desc_added; - } - } - /* We should be added at the head of the list */ - list_add(&desc->head, probe_list); -desc_added: - pr_debug("LTTng: just registered probe %s containing %u events\n", - desc->provider, desc->nr_events); -} - -/* - * Called under sessions lock. - */ -static -void fixup_lazy_probes(void) -{ - struct lttng_probe_desc *iter, *tmp; - int ret; - - lazy_nesting++; - list_for_each_entry_safe(iter, tmp, - &lazy_probe_init, lazy_init_head) { - lttng_lazy_probe_register(iter); - iter->lazy = 0; - list_del(&iter->lazy_init_head); - } - ret = lttng_fix_pending_events(); - WARN_ON_ONCE(ret); - lazy_nesting--; -} - -/* - * Called under sessions lock. - */ -struct list_head *lttng_get_probe_list_head(void) -{ - if (!lazy_nesting && !list_empty(&lazy_probe_init)) - fixup_lazy_probes(); - return &_probe_list; -} - -static -const struct lttng_probe_desc *find_provider(const char *provider) -{ - struct lttng_probe_desc *iter; - struct list_head *probe_list; - - probe_list = lttng_get_probe_list_head(); - list_for_each_entry(iter, probe_list, head) { - if (!strcmp(iter->provider, provider)) - return iter; - } - return NULL; -} - -int lttng_probe_register(struct lttng_probe_desc *desc) -{ - int ret = 0; - - lttng_lock_sessions(); - - /* - * Check if the provider has already been registered. - */ - if (find_provider(desc->provider)) { - ret = -EEXIST; - goto end; - } - list_add(&desc->lazy_init_head, &lazy_probe_init); - desc->lazy = 1; - pr_debug("LTTng: adding probe %s containing %u events to lazy registration list\n", - desc->provider, desc->nr_events); - /* - * If there is at least one active session, we need to register - * the probe immediately, since we cannot delay event - * registration because they are needed ASAP. - */ - if (lttng_session_active()) - fixup_lazy_probes(); -end: - lttng_unlock_sessions(); - return ret; -} -EXPORT_SYMBOL_GPL(lttng_probe_register); - -void lttng_probe_unregister(struct lttng_probe_desc *desc) -{ - lttng_lock_sessions(); - if (!desc->lazy) - list_del(&desc->head); - else - list_del(&desc->lazy_init_head); - pr_debug("LTTng: just unregistered probe %s\n", desc->provider); - lttng_unlock_sessions(); -} -EXPORT_SYMBOL_GPL(lttng_probe_unregister); - -/* - * TODO: this is O(nr_probes * nb_events), could be faster. - * Called with sessions lock held. - */ -static -const struct lttng_event_desc *find_event(const char *name) -{ - struct lttng_probe_desc *probe_desc; - int i; - - list_for_each_entry(probe_desc, &_probe_list, head) { - for (i = 0; i < probe_desc->nr_events; i++) { - if (!strcmp(probe_desc->event_desc[i]->name, name)) - return probe_desc->event_desc[i]; - } - } - return NULL; -} - -/* - * Called with sessions lock held. - */ -const struct lttng_event_desc *lttng_event_get(const char *name) -{ - const struct lttng_event_desc *event; - int ret; - - event = find_event(name); - if (!event) - return NULL; - ret = try_module_get(event->owner); - WARN_ON_ONCE(!ret); - return event; -} -EXPORT_SYMBOL_GPL(lttng_event_get); - -/* - * Called with sessions lock held. - */ -void lttng_event_put(const struct lttng_event_desc *event) -{ - module_put(event->owner); -} -EXPORT_SYMBOL_GPL(lttng_event_put); - -static -void *tp_list_start(struct seq_file *m, loff_t *pos) -{ - struct lttng_probe_desc *probe_desc; - struct list_head *probe_list; - int iter = 0, i; - - lttng_lock_sessions(); - probe_list = lttng_get_probe_list_head(); - list_for_each_entry(probe_desc, probe_list, head) { - for (i = 0; i < probe_desc->nr_events; i++) { - if (iter++ >= *pos) - return (void *) probe_desc->event_desc[i]; - } - } - /* End of list */ - return NULL; -} - -static -void *tp_list_next(struct seq_file *m, void *p, loff_t *ppos) -{ - struct lttng_probe_desc *probe_desc; - struct list_head *probe_list; - int iter = 0, i; - - (*ppos)++; - probe_list = lttng_get_probe_list_head(); - list_for_each_entry(probe_desc, probe_list, head) { - for (i = 0; i < probe_desc->nr_events; i++) { - if (iter++ >= *ppos) - return (void *) probe_desc->event_desc[i]; - } - } - /* End of list */ - return NULL; -} - -static -void tp_list_stop(struct seq_file *m, void *p) -{ - lttng_unlock_sessions(); -} - -static -int tp_list_show(struct seq_file *m, void *p) -{ - const struct lttng_event_desc *probe_desc = p; - - seq_printf(m, "event { name = %s; };\n", - probe_desc->name); - return 0; -} - -static -const struct seq_operations lttng_tracepoint_list_seq_ops = { - .start = tp_list_start, - .next = tp_list_next, - .stop = tp_list_stop, - .show = tp_list_show, -}; - -static -int lttng_tracepoint_list_open(struct inode *inode, struct file *file) -{ - return seq_open(file, <tng_tracepoint_list_seq_ops); -} - -const struct file_operations lttng_tracepoint_list_fops = { - .owner = THIS_MODULE, - .open = lttng_tracepoint_list_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -int lttng_probes_init(void) -{ - int cpu; - - for_each_possible_cpu(cpu) - per_cpu_ptr(<tng_dynamic_len_stack, cpu)->offset = 0; - return 0; -}