From: Frederic Weisbecker <fweisbec@gmail.com>
To: Jiri Olsa <jolsa@redhat.com>
Cc: rostedt@goodmis.org, mingo@redhat.com, paulus@samba.org,
acme@ghostprotocols.net, a.p.zijlstra@chello.nl,
linux-kernel@vger.kernel.org, aarapov@redhat.com
Subject: Re: [PATCH 5/7] ftrace, perf: Add support to use function tracepoint in perf
Date: Wed, 15 Feb 2012 17:03:02 +0100 [thread overview]
Message-ID: <20120215160259.GA24080@somewhere> (raw)
In-Reply-To: <1329317514-8131-6-git-send-email-jolsa@redhat.com>
On Wed, Feb 15, 2012 at 03:51:52PM +0100, Jiri Olsa wrote:
> Adding perf registration support for the ftrace function event,
> so it is now possible to register it via perf interface.
>
> The perf_event struct statically contains ftrace_ops as a handle
> for function tracer. The function tracer is registered/unregistered
> in open/close actions.
>
> To be efficient, we enable/disable ftrace_ops each time the traced
> process is scheduled in/out (via TRACE_REG_PERF_(ADD|DELL) handlers).
> This way tracing is enabled only when the process is running.
> Intentionally using this way instead of the event's hw state
> PERF_HES_STOPPED, which would not disable the ftrace_ops.
>
> It is now possible to use function trace within perf commands
> like:
>
> perf record -e ftrace:function ls
> perf stat -e ftrace:function ls
>
> Allowed only for root.
>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
> ---
> include/linux/perf_event.h | 3 +
> kernel/trace/trace.h | 11 +++++
> kernel/trace/trace_entries.h | 6 ++-
> kernel/trace/trace_event_perf.c | 86 +++++++++++++++++++++++++++++++++++++++
> kernel/trace/trace_export.c | 5 ++
> 5 files changed, 109 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 412b790..92a056f 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -859,6 +859,9 @@ struct perf_event {
> #ifdef CONFIG_EVENT_TRACING
> struct ftrace_event_call *tp_event;
> struct event_filter *filter;
> +#ifdef CONFIG_FUNCTION_TRACER
> + struct ftrace_ops ftrace_ops;
> +#endif
> #endif
>
> #ifdef CONFIG_CGROUP_PERF
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index 638476a..76a1c50 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -595,6 +595,8 @@ static inline int ftrace_trace_task(struct task_struct *task)
> static inline int ftrace_is_dead(void) { return 0; }
> #endif
>
> +int ftrace_event_is_function(struct ftrace_event_call *call);
> +
> /*
> * struct trace_parser - servers for reading the user input separated by spaces
> * @cont: set if the input is not complete - no final space char was found
> @@ -832,4 +834,13 @@ extern const char *__stop___trace_bprintk_fmt[];
> FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
> #include "trace_entries.h"
>
> +#ifdef CONFIG_PERF_EVENTS
> +#ifdef CONFIG_FUNCTION_TRACER
> +int perf_ftrace_event_register(struct ftrace_event_call *call,
> + enum trace_reg type, void *data);
> +#else
> +#define perf_ftrace_event_register NULL
> +#endif /* CONFIG_FUNCTION_TRACER */
> +#endif /* CONFIG_PERF_EVENTS */
> +
> #endif /* _LINUX_KERNEL_TRACE_H */
> diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
> index 9336590..47db7ed 100644
> --- a/kernel/trace/trace_entries.h
> +++ b/kernel/trace/trace_entries.h
> @@ -55,7 +55,7 @@
> /*
> * Function trace entry - function address and parent function address:
> */
> -FTRACE_ENTRY(function, ftrace_entry,
> +FTRACE_ENTRY_REG(function, ftrace_entry,
>
> TRACE_FN,
>
> @@ -64,7 +64,9 @@ FTRACE_ENTRY(function, ftrace_entry,
> __field( unsigned long, parent_ip )
> ),
>
> - F_printk(" %lx <-- %lx", __entry->ip, __entry->parent_ip)
> + F_printk(" %lx <-- %lx", __entry->ip, __entry->parent_ip),
> +
> + perf_ftrace_event_register
> );
>
> /* Function call entry */
> diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
> index d72af0b..fdeeb5c 100644
> --- a/kernel/trace/trace_event_perf.c
> +++ b/kernel/trace/trace_event_perf.c
> @@ -24,6 +24,11 @@ static int total_ref_count;
> static int perf_trace_event_perm(struct ftrace_event_call *tp_event,
> struct perf_event *p_event)
> {
> + /* The ftrace function trace is allowed only for root. */
> + if (ftrace_event_is_function(tp_event) &&
> + perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> /* No tracing, just counting, so no obvious leak */
> if (!(p_event->attr.sample_type & PERF_SAMPLE_RAW))
> return 0;
> @@ -250,3 +255,84 @@ __kprobes void *perf_trace_buf_prepare(int size, unsigned short type,
> return raw_data;
> }
> EXPORT_SYMBOL_GPL(perf_trace_buf_prepare);
> +
> +#ifdef CONFIG_FUNCTION_TRACER
> +static void
> +perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip)
> +{
> + struct ftrace_entry *entry;
> + struct hlist_head *head;
> + struct pt_regs regs;
> + int rctx;
> +
> +#define ENTRY_SIZE (ALIGN(sizeof(struct ftrace_entry) + sizeof(u32), \
> + sizeof(u64)) - sizeof(u32))
> +
> + BUILD_BUG_ON(ENTRY_SIZE > PERF_MAX_TRACE_SIZE);
> +
> + perf_fetch_caller_regs(®s);
> +
> + entry = perf_trace_buf_prepare(ENTRY_SIZE, TRACE_FN, NULL, &rctx);
> + if (!entry)
> + return;
> +
> + entry->ip = ip;
> + entry->parent_ip = parent_ip;
> +
> + head = this_cpu_ptr(event_function.perf_events);
> + perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, 0,
> + 1, ®s, head);
> +
> +#undef ENTRY_SIZE
> +}
> +
> +static int perf_ftrace_function_register(struct perf_event *event)
> +{
> + struct ftrace_ops *ops = &event->ftrace_ops;
> +
> + ops->flags |= FTRACE_OPS_FL_CONTROL;
> + ops->func = perf_ftrace_function_call;
> + return register_ftrace_function(ops);
> +}
> +
> +static int perf_ftrace_function_unregister(struct perf_event *event)
> +{
> + struct ftrace_ops *ops = &event->ftrace_ops;
> + return unregister_ftrace_function(ops);
> +}
> +
> +static void perf_ftrace_function_enable(struct perf_event *event)
> +{
> + ftrace_function_local_enable(&event->ftrace_ops);
> +}
> +
> +static void perf_ftrace_function_disable(struct perf_event *event)
> +{
> + ftrace_function_local_disable(&event->ftrace_ops);
> +}
> +
> +int perf_ftrace_event_register(struct ftrace_event_call *call,
> + enum trace_reg type, void *data)
> +{
> + switch (type) {
> + case TRACE_REG_REGISTER:
> + case TRACE_REG_UNREGISTER:
> + break;
> + case TRACE_REG_PERF_REGISTER:
> + case TRACE_REG_PERF_UNREGISTER:
> + return 0;
> + case TRACE_REG_PERF_OPEN:
> + return perf_ftrace_function_register(data);
> + case TRACE_REG_PERF_CLOSE:
> + return perf_ftrace_function_unregister(data);
> + case TRACE_REG_PERF_ADD:
> + perf_ftrace_function_enable(data);
> + return 0;
> + case TRACE_REG_PERF_DEL:
> + perf_ftrace_function_disable(data);
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +#endif /* CONFIG_FUNCTION_TRACER */
> diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
> index f74de86..a3dbee6 100644
> --- a/kernel/trace/trace_export.c
> +++ b/kernel/trace/trace_export.c
> @@ -184,4 +184,9 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call;
> FTRACE_ENTRY_REG(call, struct_name, etype, \
> PARAMS(tstruct), PARAMS(print), NULL)
>
> +int ftrace_event_is_function(struct ftrace_event_call *call)
> +{
> + return call == &event_function;
> +}
> +
> #include "trace_entries.h"
> --
> 1.7.1
>
next prev parent reply other threads:[~2012-02-15 16:03 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-15 14:51 [PATCHv9 0/7] ftrace, perf: Adding support to use function trace Jiri Olsa
2012-02-15 14:51 ` [PATCH 1/7] ftrace: Add enable/disable ftrace_ops control interface Jiri Olsa
2012-02-27 9:33 ` [tip:perf/core] ftrace: Add enable/ disable " tip-bot for Jiri Olsa
2012-02-15 14:51 ` [PATCH 2/7] ftrace, perf: Add open/close tracepoint perf registration actions Jiri Olsa
2012-02-27 9:34 ` [tip:perf/core] ftrace, perf: Add open/ close " tip-bot for Jiri Olsa
2012-02-15 14:51 ` [PATCH 3/7] ftrace, perf: Add add/del " Jiri Olsa
2012-02-27 9:34 ` [tip:perf/core] ftrace, perf: Add add/ del " tip-bot for Jiri Olsa
2012-02-15 14:51 ` [PATCH 4/7] ftrace: Add FTRACE_ENTRY_REG macro to allow event registration Jiri Olsa
2012-02-15 15:13 ` Frederic Weisbecker
2012-02-27 9:35 ` [tip:perf/core] " tip-bot for Jiri Olsa
2012-02-15 14:51 ` [PATCH 5/7] ftrace, perf: Add support to use function tracepoint in perf Jiri Olsa
2012-02-15 16:03 ` Frederic Weisbecker [this message]
2012-02-27 9:36 ` [tip:perf/core] " tip-bot for Jiri Olsa
2012-02-15 14:51 ` [PATCH 6/7] ftrace: Allow to specify filter field type for ftrace events Jiri Olsa
2012-02-27 9:37 ` [tip:perf/core] " tip-bot for Jiri Olsa
2012-02-15 14:51 ` [PATCH 7/7] ftrace, perf: Add filter support for function trace event Jiri Olsa
2012-02-27 9:38 ` [tip:perf/core] " tip-bot for Jiri Olsa
-- strict thread matches above, loose matches on Subject: below --
2011-12-21 11:48 [PATCHv3 0/8] ftrace, perf: Adding support to use function trace Jiri Olsa
2011-12-21 18:56 ` [PATCHv4 " Jiri Olsa
2011-12-21 18:56 ` [PATCH 5/7] ftrace, perf: Add support to use function tracepoint in perf Jiri Olsa
2012-01-02 9:04 ` [PATCHv5 0/7] ftrace, perf: Adding support to use function trace Jiri Olsa
2012-01-02 9:04 ` [PATCH 5/7] ftrace, perf: Add support to use function tracepoint in perf Jiri Olsa
2012-01-18 18:44 ` [PATCHv6 0/7] ftrace, perf: Adding support to use function trace Jiri Olsa
2012-01-18 18:44 ` [PATCH 5/7] ftrace, perf: Add support to use function tracepoint in perf Jiri Olsa
2012-01-28 18:43 ` [PATCHv7 0/7] ftrace, perf: Adding support to use function trace Jiri Olsa
2012-01-28 18:43 ` [PATCH 5/7] ftrace, perf: Add support to use function tracepoint in perf Jiri Olsa
2012-02-02 18:14 ` Frederic Weisbecker
2012-02-03 12:54 ` Jiri Olsa
2012-02-03 13:00 ` Jiri Olsa
2012-02-03 14:07 ` Steven Rostedt
2012-02-04 13:21 ` Frederic Weisbecker
2012-02-06 19:35 ` Steven Rostedt
2012-02-03 13:53 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120215160259.GA24080@somewhere \
--to=fweisbec@gmail.com \
--cc=a.p.zijlstra@chello.nl \
--cc=aarapov@redhat.com \
--cc=acme@ghostprotocols.net \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=paulus@samba.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.