Re: [PATCH 2/5] ftrace perf: Move exclude_kernel tracepoint check to init event

From: Namhyung Kim
Date: Wed Mar 09 2016 - 19:40:06 EST


On Wed, Mar 09, 2016 at 09:46:42PM +0100, Jiri Olsa wrote:
> We suppress events with attr::exclude_kernel set when
> the event is generated, so following capture will
> give no warning but won't produce any data:
>
> $ sudo perf record -e sched:sched_switch:u ls
> $ sudo /perf script | wc -l
> 0
>
> Checking the attr::exclude_(kernel|user) at the event
> init time and failing right away for tracepoints from
> uprobes/kprobes and native ones:
>
> $ sudo perf record -e sched:sched_switch:u ls
> Error:
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (sched:sched_switch).
> /bin/dmesg may provide additional information.
> No CONFIG_PERF_EVENTS=y kernel support configured?
>
> $ sudo perf record -e probe:sys_read:u ls
> Error:
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (probe:sys_read).
> /bin/dmesg may provide additional information.
> No CONFIG_PERF_EVENTS=y kernel support configured?
>
> $ ./perf record -e probe_ex:main:k ./ex
> Error:
> The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (probe_ex:main).
> /bin/dmesg may provide additional information.
> No CONFIG_PERF_EVENTS=y kernel support configured?
>
> Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx>

Acked-by: Namhyung Kim <namhyung@xxxxxxxxxx>

Maybe we need to improve the error message later.

Thanks,
Namhyung


> ---
> kernel/events/core.c | 5 -----
> kernel/trace/trace_event_perf.c | 25 +++++++++++++++++++++++++
> 2 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index c15fd097af93..ca68fdcf47ce 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -6898,11 +6898,6 @@ static int perf_tp_event_match(struct perf_event *event,
> {
> if (event->hw.state & PERF_HES_STOPPED)
> return 0;
> - /*
> - * All tracepoints are from kernel-space.
> - */
> - if (event->attr.exclude_kernel)
> - return 0;
>
> if (!perf_tp_filter_match(event, data))
> return 0;
> diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
> index a7171ec2c1ca..0a3779bd18a1 100644
> --- a/kernel/trace/trace_event_perf.c
> +++ b/kernel/trace/trace_event_perf.c
> @@ -182,11 +182,36 @@ static void perf_trace_event_close(struct perf_event *p_event)
> tp_event->class->reg(tp_event, TRACE_REG_PERF_CLOSE, p_event);
> }
>
> +static int perf_trace_event_attr(struct trace_event_call *tp_event,
> + struct perf_event *event)
> +{
> + /*
> + * All tracepoints and kprobes are from kernel-space.
> + */
> + if (((tp_event->flags & TRACE_EVENT_FL_TRACEPOINT) ||
> + (tp_event->flags & TRACE_EVENT_FL_KPROBE)) &&
> + event->attr.exclude_kernel)
> + return -EINVAL;
> +
> + /*
> + * All uprobes are from user-space.
> + */
> + if ((tp_event->flags & TRACE_EVENT_FL_UPROBE) &&
> + event->attr.exclude_user)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> static int perf_trace_event_init(struct trace_event_call *tp_event,
> struct perf_event *p_event)
> {
> int ret;
>
> + ret = perf_trace_event_attr(tp_event, p_event);
> + if (ret)
> + return ret;
> +
> ret = perf_trace_event_perm(tp_event, p_event);
> if (ret)
> return ret;
> --
> 2.4.3
>