From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751444AbaC1WK3 (ORCPT ); Fri, 28 Mar 2014 18:10:29 -0400 Received: from mail.efficios.com ([78.47.125.74]:59712 "EHLO mail.efficios.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751377AbaC1WKY (ORCPT ); Fri, 28 Mar 2014 18:10:24 -0400 From: Mathieu Desnoyers To: Steven Rostedt Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers , Ingo Molnar , Frederic Weisbecker , Andrew Morton , "Frank Ch. Eigler" , Johannes Berg Subject: [PATCH v8 1/1] Tracepoint: register/unregister struct tracepoint Date: Fri, 28 Mar 2014 15:09:58 -0700 Message-Id: <1396044598-9358-2-git-send-email-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1396044598-9358-1-git-send-email-mathieu.desnoyers@efficios.com> References: <1396044598-9358-1-git-send-email-mathieu.desnoyers@efficios.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Register/unregister tracepoint probes with struct tracepoint pointer rather than tracepoint name. This change, which vastly simplifies tracepoint.c, has been proposed by Steven Rostedt. It also removes 8.8kB (mostly of text) to the vmlinux size. >>From this point on, the tracers need to pass a struct tracepoint pointer to probe register/unregister. A probe can now only be connected to a tracepoint that exists. Moreover, tracers are responsible for unregistering the probe before the module containing its associated tracepoint is unloaded. Signed-off-by: Mathieu Desnoyers CC: Steven Rostedt CC: Ingo Molnar CC: Frederic Weisbecker CC: Andrew Morton CC: Frank Ch. Eigler CC: Johannes Berg --- include/linux/ftrace_event.h | 20 +- include/linux/tracepoint.h | 41 +-- include/trace/ftrace.h | 9 +- kernel/trace/trace_events.c | 51 ++-- kernel/trace/trace_events_trigger.c | 2 +- kernel/trace/trace_export.c | 2 +- kernel/trace/trace_kprobe.c | 29 +- kernel/trace/trace_output.c | 2 +- kernel/trace/trace_uprobe.c | 28 +- kernel/tracepoint.c | 509 +++++++++++++++-------------------- 10 files changed, 336 insertions(+), 357 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index cdc3011..766a14b 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -7,6 +7,7 @@ #include #include #include +#include struct trace_array; struct trace_buffer; @@ -232,6 +233,7 @@ enum { TRACE_EVENT_FL_IGNORE_ENABLE_BIT, TRACE_EVENT_FL_WAS_ENABLED_BIT, TRACE_EVENT_FL_USE_CALL_FILTER_BIT, + TRACE_EVENT_FL_TRACEPOINT_BIT, }; /* @@ -244,6 +246,7 @@ enum { * (used for module unloading, if a module event is enabled, * it is best to clear the buffers that used it). * USE_CALL_FILTER - For ftrace internal events, don't use file filter + * TRACEPOINT - Event is a tracepoint */ enum { TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), @@ -252,12 +255,17 @@ enum { TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT), TRACE_EVENT_FL_WAS_ENABLED = (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT), TRACE_EVENT_FL_USE_CALL_FILTER = (1 << TRACE_EVENT_FL_USE_CALL_FILTER_BIT), + TRACE_EVENT_FL_TRACEPOINT = (1 << TRACE_EVENT_FL_TRACEPOINT_BIT), }; struct ftrace_event_call { struct list_head list; struct ftrace_event_class *class; - char *name; + union { + char *name; + /* Set TRACE_EVENT_FL_TRACEPOINT flag when using "tp" */ + struct tracepoint *tp; + } u; struct trace_event event; const char *print_fmt; struct event_filter *filter; @@ -271,6 +279,7 @@ struct ftrace_event_call { * bit 3: ftrace internal event (do not enable) * bit 4: Event was enabled by module * bit 5: use call filter rather than file filter + * bit 6: Event is a tracepoint */ int flags; /* static flags of different events */ @@ -283,6 +292,15 @@ struct ftrace_event_call { #endif }; +static inline const char * +ftrace_event_get_name(struct ftrace_event_call *call) +{ + if (call->flags & TRACE_EVENT_FL_TRACEPOINT) + return call->u.tp->name; + else + return call->u.name; +} + struct trace_array; struct ftrace_subsystem_dir; diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 812b255..08150e2 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -6,7 +6,7 @@ * * See Documentation/trace/tracepoints.txt. * - * (C) Copyright 2008 Mathieu Desnoyers + * Copyright (C) 2008-2014 Mathieu Desnoyers * * Heavily inspired from the Linux Kernel Markers. * @@ -21,6 +21,7 @@ struct module; struct tracepoint; +struct notifier_block; struct tracepoint_func { void *func; @@ -35,18 +36,13 @@ struct tracepoint { struct tracepoint_func __rcu *funcs; }; -/* - * Connect a probe to a tracepoint. - * Internal API, should not be used directly. - */ -extern int tracepoint_probe_register(const char *name, void *probe, void *data); - -/* - * Disconnect a probe from a tracepoint. - * Internal API, should not be used directly. - */ extern int -tracepoint_probe_unregister(const char *name, void *probe, void *data); +tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); +extern int +tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data); +extern void +for_each_kernel_tracepoint(void (*fct)(struct tracepoint *tp, void *priv), + void *priv); #ifdef CONFIG_MODULES struct tp_module { @@ -54,12 +50,25 @@ struct tp_module { unsigned int num_tracepoints; struct tracepoint * const *tracepoints_ptrs; }; + bool trace_module_has_bad_taint(struct module *mod); +extern int register_tracepoint_module_notifier(struct notifier_block *nb); +extern int unregister_tracepoint_module_notifier(struct notifier_block *nb); #else static inline bool trace_module_has_bad_taint(struct module *mod) { return false; } +static inline +int register_tracepoint_module_notifier(struct notifier_block *nb) +{ + return 0; +} +static inline +int unregister_tracepoint_module_notifier(struct notifier_block *nb) +{ + return 0; +} #endif /* CONFIG_MODULES */ /* @@ -160,14 +169,14 @@ static inline void tracepoint_synchronize_unregister(void) static inline int \ register_trace_##name(void (*probe)(data_proto), void *data) \ { \ - return tracepoint_probe_register(#name, (void *)probe, \ - data); \ + return tracepoint_probe_register(&__tracepoint_##name, \ + (void *)probe, data); \ } \ static inline int \ unregister_trace_##name(void (*probe)(data_proto), void *data) \ { \ - return tracepoint_probe_unregister(#name, (void *)probe, \ - data); \ + return tracepoint_probe_unregister(&__tracepoint_##name,\ + (void *)probe, data); \ } \ static inline void \ check_trace_callback_type_##name(void (*cb)(data_proto)) \ diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 8765126..ef86df1 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -470,10 +470,11 @@ static inline notrace int ftrace_get_offsets_##call( \ * }; * * static struct ftrace_event_call event_ = { - * .name = "", + * .u.tp = &__tracepoint_, * .class = event_class_