From: Mathieu Desnoyers Date: Fri, 22 Oct 2021 19:17:25 +0000 (-0400) Subject: Use event enabler for event recorder creation for all instrumentation types X-Git-Url: http://git.liburcu.org/?p=lttng-modules.git;a=commitdiff_plain;h=def1e3046bc419e2a7dae84bc6abc1ea20cf1343 Use event enabler for event recorder creation for all instrumentation types Remove special-cases for uprobes, kprobes, kretprobes and use a temporary event enabler to hold relevant information for event recorder creation. Signed-off-by: Mathieu Desnoyers Change-Id: Ib353a67d1554c345ba71d31c5632ded3b33b2a92 --- diff --git a/include/lttng/events-internal.h b/include/lttng/events-internal.h index ca2190c4..cfbde70f 100644 --- a/include/lttng/events-internal.h +++ b/include/lttng/events-internal.h @@ -221,7 +221,8 @@ struct lttng_enabler { struct lttng_event_enabler { struct lttng_enabler base; - struct list_head node; /* per-session list of enablers */ + struct list_head node; /* per-session list of enablers */ + bool published; /* published in per-session list. */ struct lttng_kernel_channel_buffer *chan; }; @@ -779,6 +780,9 @@ struct lttng_event_enabler *lttng_event_enabler_create( enum lttng_enabler_format_type format_type, struct lttng_kernel_abi_event *event_param, struct lttng_kernel_channel_buffer *chan); +void lttng_event_enabler_session_add(struct lttng_kernel_session *session, + struct lttng_event_enabler *event_enabler); +void lttng_event_enabler_destroy(struct lttng_event_enabler *event_enabler); int lttng_event_enabler_enable(struct lttng_event_enabler *event_enabler); int lttng_event_enabler_disable(struct lttng_event_enabler *event_enabler); @@ -1096,14 +1100,10 @@ struct lttng_kernel_channel_buffer *lttng_global_channel_create(struct lttng_ker unsigned int read_timer_interval); void lttng_metadata_channel_destroy(struct lttng_kernel_channel_buffer *chan); -struct lttng_kernel_event_recorder *lttng_kernel_event_recorder_create(struct lttng_kernel_channel_buffer *chan, - struct lttng_kernel_abi_event *event_param, - const struct lttng_kernel_event_desc *event_desc, - enum lttng_kernel_abi_instrumentation itype); -struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct lttng_kernel_channel_buffer *chan, - struct lttng_kernel_abi_event *event_param, - const struct lttng_kernel_event_desc *event_desc, - enum lttng_kernel_abi_instrumentation itype); +struct lttng_kernel_event_recorder *lttng_kernel_event_recorder_create(struct lttng_event_enabler *event_enabler, + const struct lttng_kernel_event_desc *event_desc); +struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct lttng_event_enabler *event_enabler, + const struct lttng_kernel_event_desc *event_desc); struct lttng_kernel_event_recorder *lttng_event_compat_old_create(struct lttng_kernel_channel_buffer *chan, struct lttng_kernel_abi_old_event *old_event_param, const struct lttng_kernel_event_desc *internal_desc); diff --git a/src/lttng-abi.c b/src/lttng-abi.c index eac1afd1..72dc0603 100644 --- a/src/lttng-abi.c +++ b/src/lttng-abi.c @@ -1900,6 +1900,8 @@ int lttng_abi_create_event(struct file *channel_file, event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, event_param, channel); } + if (event_enabler) + lttng_event_enabler_session_add(channel->parent.session, event_enabler); priv = event_enabler; break; } @@ -1911,14 +1913,21 @@ int lttng_abi_create_event(struct file *channel_file, case LTTNG_KERNEL_ABI_UPROBE: { struct lttng_kernel_event_recorder *event; + struct lttng_event_enabler *event_enabler; + event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, + event_param, channel); + if (!event_enabler) { + ret = -ENOMEM; + goto event_error; + } /* * We tolerate no failure path after event creation. It * will stay invariant for the rest of the session. */ - event = lttng_kernel_event_recorder_create(channel, event_param, - NULL, event_param->instrumentation); + event = lttng_kernel_event_recorder_create(event_enabler, NULL); WARN_ON_ONCE(!event); + lttng_event_enabler_destroy(event_enabler); if (IS_ERR(event)) { ret = PTR_ERR(event); goto event_error; diff --git a/src/lttng-events.c b/src/lttng-events.c index 230e3934..02c62b0c 100644 --- a/src/lttng-events.c +++ b/src/lttng-events.c @@ -66,7 +66,6 @@ static struct kmem_cache *event_notifier_private_cache; static void lttng_session_lazy_sync_event_enablers(struct lttng_kernel_session *session); static void lttng_session_sync_event_enablers(struct lttng_kernel_session *session); -static void lttng_event_enabler_destroy(struct lttng_event_enabler *event_enabler); static void lttng_event_notifier_enabler_destroy(struct lttng_event_notifier_enabler *event_notifier_enabler); static void lttng_event_notifier_group_sync_enablers(struct lttng_event_notifier_group *event_notifier_group); @@ -860,11 +859,12 @@ void _lttng_metadata_channel_hangup(struct lttng_metadata_stream *stream) * Supports event creation while tracing session is active. * Needs to be called with sessions mutex held. */ -struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct lttng_kernel_channel_buffer *chan, - struct lttng_kernel_abi_event *event_param, - const struct lttng_kernel_event_desc *event_desc, - enum lttng_kernel_abi_instrumentation itype) +struct lttng_kernel_event_recorder *_lttng_kernel_event_recorder_create(struct lttng_event_enabler *event_enabler, + const struct lttng_kernel_event_desc *event_desc) { + struct lttng_kernel_channel_buffer *chan = event_enabler->chan; + struct lttng_kernel_abi_event *event_param = &event_enabler->base.event_param; + enum lttng_kernel_abi_instrumentation itype = event_param->instrumentation; struct lttng_kernel_session *session = chan->parent.session; struct lttng_kernel_event_recorder *event_recorder; struct lttng_kernel_event_recorder_private *event_recorder_priv; @@ -1395,15 +1395,13 @@ int lttng_kernel_counter_clear(struct lttng_counter *counter, return counter->ops->counter_clear(counter->counter, dim_indexes); } -struct lttng_kernel_event_recorder *lttng_kernel_event_recorder_create(struct lttng_kernel_channel_buffer *chan, - struct lttng_kernel_abi_event *event_param, - const struct lttng_kernel_event_desc *event_desc, - enum lttng_kernel_abi_instrumentation itype) +struct lttng_kernel_event_recorder *lttng_kernel_event_recorder_create(struct lttng_event_enabler *event_enabler, + const struct lttng_kernel_event_desc *event_desc) { struct lttng_kernel_event_recorder *event; mutex_lock(&sessions_mutex); - event = _lttng_kernel_event_recorder_create(chan, event_param, event_desc, itype); + event = _lttng_kernel_event_recorder_create(event_enabler, event_desc); mutex_unlock(&sessions_mutex); return event; } @@ -2160,8 +2158,7 @@ void lttng_create_tracepoint_event_if_missing(struct lttng_event_enabler *event_ * We need to create an event for this * event probe. */ - event_recorder = _lttng_kernel_event_recorder_create(event_enabler->chan, - NULL, desc, LTTNG_KERNEL_ABI_TRACEPOINT); + event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc); if (!event_recorder) { printk(KERN_INFO "LTTng: Unable to create event %s\n", probe_desc->event_desc[i]->event_name); @@ -2492,11 +2489,17 @@ struct lttng_event_enabler *lttng_event_enabler_create( event_enabler->chan = chan; /* ctx left NULL */ event_enabler->base.enabled = 0; + return event_enabler; +} + +void lttng_event_enabler_session_add(struct lttng_kernel_session *session, + struct lttng_event_enabler *event_enabler) +{ mutex_lock(&sessions_mutex); - list_add(&event_enabler->node, &event_enabler->chan->parent.session->priv->enablers_head); - lttng_session_lazy_sync_event_enablers(event_enabler->chan->parent.session); + list_add(&event_enabler->node, &session->priv->enablers_head); + event_enabler->published = true; + lttng_session_lazy_sync_event_enablers(session); mutex_unlock(&sessions_mutex); - return event_enabler; } int lttng_event_enabler_enable(struct lttng_event_enabler *event_enabler) @@ -2590,12 +2593,12 @@ void lttng_enabler_destroy(struct lttng_enabler *enabler) } } -static void lttng_event_enabler_destroy(struct lttng_event_enabler *event_enabler) { lttng_enabler_destroy(lttng_event_enabler_as_enabler(event_enabler)); - list_del(&event_enabler->node); + if (event_enabler->published) + list_del(&event_enabler->node); kfree(event_enabler); } diff --git a/src/lttng-syscalls.c b/src/lttng-syscalls.c index bd836c00..25db7f61 100644 --- a/src/lttng-syscalls.c +++ b/src/lttng-syscalls.c @@ -613,16 +613,17 @@ void syscall_exit_event_notifier_probe(void *__data, struct pt_regs *regs, */ static int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *table, size_t table_len, - struct hlist_head *chan_table, struct lttng_event_enabler *event_enabler, + struct hlist_head *chan_table, struct lttng_event_enabler *syscall_event_enabler, enum sc_type type) { - struct lttng_kernel_channel_buffer *chan = event_enabler->chan; + struct lttng_kernel_channel_buffer *chan = syscall_event_enabler->chan; struct lttng_kernel_session *session = chan->parent.session; unsigned int i; /* Allocate events for each syscall matching enabler, insert into table */ for (i = 0; i < table_len; i++) { const struct lttng_kernel_event_desc *desc = table[i].desc; + struct lttng_event_enabler *event_enabler; struct lttng_kernel_abi_event ev; struct lttng_kernel_event_recorder_private *event_recorder_priv; struct lttng_kernel_event_recorder *event_recorder; @@ -634,7 +635,7 @@ int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *tabl continue; } if (lttng_desc_match_enabler(desc, - lttng_event_enabler_as_enabler(event_enabler)) <= 0) + lttng_event_enabler_as_enabler(syscall_event_enabler)) <= 0) continue; /* * Check if already created. @@ -644,7 +645,7 @@ int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *tabl desc->event_name); lttng_hlist_for_each_entry(event_recorder_priv, head, hlist) { if (event_recorder_priv->parent.desc == desc - && event_recorder_priv->pub->chan == event_enabler->chan) + && event_recorder_priv->pub->chan == chan) found = true; } if (found) @@ -673,8 +674,13 @@ int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *tabl strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1); ev.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0'; ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL; - event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, ev.instrumentation); + event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan); + if (!event_enabler) { + return -ENOMEM; + } + event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc); WARN_ON_ONCE(!event_recorder); + lttng_event_enabler_destroy(event_enabler); if (IS_ERR(event_recorder)) { /* * If something goes wrong in event registration @@ -692,9 +698,9 @@ int lttng_create_syscall_event_if_missing(const struct trace_syscall_entry *tabl /* * Should be called with sessions lock held. */ -int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) +int lttng_syscalls_register_event(struct lttng_event_enabler *syscall_event_enabler) { - struct lttng_kernel_channel_buffer *chan = event_enabler->chan; + struct lttng_kernel_channel_buffer *chan = syscall_event_enabler->chan; struct lttng_kernel_abi_event ev; int ret; @@ -737,6 +743,7 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) const struct lttng_kernel_event_desc *desc = &__event_desc___syscall_entry_unknown; struct lttng_kernel_event_recorder *event_recorder; + struct lttng_event_enabler *event_enabler; memset(&ev, 0, sizeof(ev)); strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN); @@ -744,8 +751,12 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL; ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY; ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE; - event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, - ev.instrumentation); + event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan); + if (!event_enabler) { + return -ENOMEM; + } + event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc); + lttng_event_enabler_destroy(event_enabler); WARN_ON_ONCE(!event_recorder); if (IS_ERR(event_recorder)) { return PTR_ERR(event_recorder); @@ -757,6 +768,7 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) const struct lttng_kernel_event_desc *desc = &__event_desc___compat_syscall_entry_unknown; struct lttng_kernel_event_recorder *event_recorder; + struct lttng_event_enabler *event_enabler; memset(&ev, 0, sizeof(ev)); strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN); @@ -764,9 +776,13 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL; ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY; ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT; - event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, - ev.instrumentation); + event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan); + if (!event_enabler) { + return -ENOMEM; + } + event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc); WARN_ON_ONCE(!event_recorder); + lttng_event_enabler_destroy(event_enabler); if (IS_ERR(event_recorder)) { return PTR_ERR(event_recorder); } @@ -777,6 +793,7 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) const struct lttng_kernel_event_desc *desc = &__event_desc___compat_syscall_exit_unknown; struct lttng_kernel_event_recorder *event_recorder; + struct lttng_event_enabler *event_enabler; memset(&ev, 0, sizeof(ev)); strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN); @@ -784,9 +801,13 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL; ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT; ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT; - event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, - ev.instrumentation); + event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan); + if (!event_enabler) { + return -ENOMEM; + } + event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc); WARN_ON_ONCE(!event_recorder); + lttng_event_enabler_destroy(event_enabler); if (IS_ERR(event_recorder)) { return PTR_ERR(event_recorder); } @@ -797,6 +818,7 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) const struct lttng_kernel_event_desc *desc = &__event_desc___syscall_exit_unknown; struct lttng_kernel_event_recorder *event_recorder; + struct lttng_event_enabler *event_enabler; memset(&ev, 0, sizeof(ev)); strncpy(ev.name, desc->event_name, LTTNG_KERNEL_ABI_SYM_NAME_LEN); @@ -804,9 +826,13 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) ev.instrumentation = LTTNG_KERNEL_ABI_SYSCALL; ev.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT; ev.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE; - event_recorder = _lttng_kernel_event_recorder_create(chan, &ev, desc, - ev.instrumentation); + event_enabler = lttng_event_enabler_create(LTTNG_ENABLER_FORMAT_NAME, &ev, chan); + if (!event_enabler) { + return -ENOMEM; + } + event_recorder = _lttng_kernel_event_recorder_create(event_enabler, desc); WARN_ON_ONCE(!event_recorder); + lttng_event_enabler_destroy(event_enabler); if (IS_ERR(event_recorder)) { return PTR_ERR(event_recorder); } @@ -814,21 +840,21 @@ int lttng_syscalls_register_event(struct lttng_event_enabler *event_enabler) } ret = lttng_create_syscall_event_if_missing(sc_table.table, sc_table.len, - chan->priv->parent.sc_table, event_enabler, SC_TYPE_ENTRY); + chan->priv->parent.sc_table, syscall_event_enabler, SC_TYPE_ENTRY); if (ret) return ret; ret = lttng_create_syscall_event_if_missing(sc_exit_table.table, sc_exit_table.len, - chan->priv->parent.sc_exit_table, event_enabler, SC_TYPE_EXIT); + chan->priv->parent.sc_exit_table, syscall_event_enabler, SC_TYPE_EXIT); if (ret) return ret; #ifdef CONFIG_COMPAT ret = lttng_create_syscall_event_if_missing(compat_sc_table.table, compat_sc_table.len, - chan->priv->parent.compat_sc_table, event_enabler, SC_TYPE_COMPAT_ENTRY); + chan->priv->parent.compat_sc_table, syscall_event_enabler, SC_TYPE_COMPAT_ENTRY); if (ret) return ret; ret = lttng_create_syscall_event_if_missing(compat_sc_exit_table.table, compat_sc_exit_table.len, - chan->priv->parent.compat_sc_exit_table, event_enabler, SC_TYPE_COMPAT_EXIT); + chan->priv->parent.compat_sc_exit_table, syscall_event_enabler, SC_TYPE_COMPAT_EXIT); if (ret) return ret; #endif