Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1452504 > unrolled thread
| Started by | Brendan Gregg <bgregg@netflix.com> |
|---|---|
| First post | 2016-07-29 20:10 +0200 |
| Last post | 2016-08-03 05:00 +0200 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH] perf/core: Add a tracepoint for perf sampling Brendan Gregg <bgregg@netflix.com> - 2016-07-29 20:10 +0200
Re: [PATCH] perf/core: Add a tracepoint for perf sampling "Wangnan (F)" <wangnan0@huawei.com> - 2016-07-30 05:50 +0200
Re: [PATCH] perf/core: Add a tracepoint for perf sampling Brendan Gregg <bgregg@netflix.com> - 2016-08-03 05:00 +0200
| From | Brendan Gregg <bgregg@netflix.com> |
|---|---|
| Date | 2016-07-29 20:10 +0200 |
| Subject | Re: [PATCH] perf/core: Add a tracepoint for perf sampling |
| Message-ID | <s0kop-8aN-11@gated-at.bofh.it> |
On Tue, Jul 19, 2016 at 4:20 PM, Brendan Gregg <bgregg@netflix.com> wrote:
> When perf is performing hrtimer-based sampling, this tracepoint can be used
> by BPF to run additional logic on each sample. For example, BPF can fetch
> stack traces and frequency count them in kernel context, for an efficient
> profiler.
Any comments on this patch? Thanks,
Brendan
>
> Signed-off-by: Brendan Gregg <bgregg@netflix.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Wang Nan <wangnan0@huawei.com>
> ---
> include/trace/events/perf.h | 29 +++++++++++++++++++++++++++++
> kernel/events/core.c | 5 +++++
> 2 files changed, 34 insertions(+)
> create mode 100644 include/trace/events/perf.h
>
> diff --git a/include/trace/events/perf.h b/include/trace/events/perf.h
> new file mode 100644
> index 0000000..461770d
> --- /dev/null
> +++ b/include/trace/events/perf.h
> @@ -0,0 +1,29 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM perf
> +
> +#if !defined(_TRACE_PERF_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_PERF_H
> +
> +#include <linux/tracepoint.h>
> +
> +TRACE_EVENT(perf_hrtimer,
> + TP_PROTO(struct pt_regs *regs, struct perf_event *event),
> +
> + TP_ARGS(regs, event),
> +
> + TP_STRUCT__entry(
> + __field(struct pt_regs *, regs)
> + __field(struct perf_event *, event)
> + ),
> +
> + TP_fast_assign(
> + __entry->regs = regs;
> + __entry->event = event;
> + ),
> +
> + TP_printk("regs=%p evt=%p", __entry->regs, __entry->event)
> +);
> +#endif /* _TRACE_PERF_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 79dae18..0d843a7 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -51,6 +51,9 @@
>
> #include <asm/irq_regs.h>
>
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/perf.h>
> +
> typedef int (*remote_function_f)(void *);
>
> struct remote_function_call {
> @@ -8036,6 +8039,8 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
> perf_sample_data_init(&data, 0, event->hw.last_period);
> regs = get_irq_regs();
>
> + trace_perf_hrtimer(regs, event);
> +
> if (regs && !perf_exclude_event(event, regs)) {
> if (!(event->attr.exclude_idle && is_idle_task(current)))
> if (__perf_event_overflow(event, 1, &data, regs))
> --
> 2.7.4
>
[toc] | [next] | [standalone]
| From | "Wangnan (F)" <wangnan0@huawei.com> |
|---|---|
| Date | 2016-07-30 05:50 +0200 |
| Message-ID | <s0trH-5zQ-3@gated-at.bofh.it> |
| In reply to | #1452504 |
On 2016/7/30 2:05, Brendan Gregg wrote: > On Tue, Jul 19, 2016 at 4:20 PM, Brendan Gregg <bgregg@netflix.com> wrote: >> When perf is performing hrtimer-based sampling, this tracepoint can be used >> by BPF to run additional logic on each sample. For example, BPF can fetch >> stack traces and frequency count them in kernel context, for an efficient >> profiler. > Any comments on this patch? Thanks, > > Brendan Sorry for the late. I think it is a useful feature. Could you please provide an example to show how to use it in perf? If I understand correctly, I can have a BPF script run 99 times per second using # perf -e cpu-clock/freq=99/ -e mybpf.c ... And in mybpf.c, attach a BPF script on the new tracepoint. Right? Also, since we already have timer:hrtimer_expire_entry, please provide some further information about why we need a new tracepoint. Thank you.
[toc] | [prev] | [next] | [standalone]
| From | Brendan Gregg <bgregg@netflix.com> |
|---|---|
| Date | 2016-08-03 05:00 +0200 |
| Message-ID | <s1Uzw-4PA-17@gated-at.bofh.it> |
| In reply to | #1452650 |
On Fri, Jul 29, 2016 at 8:34 PM, Wangnan (F) <wangnan0@huawei.com> wrote:
>
>
> On 2016/7/30 2:05, Brendan Gregg wrote:
>>
>> On Tue, Jul 19, 2016 at 4:20 PM, Brendan Gregg <bgregg@netflix.com> wrote:
>>>
>>> When perf is performing hrtimer-based sampling, this tracepoint can be
>>> used
>>> by BPF to run additional logic on each sample. For example, BPF can fetch
>>> stack traces and frequency count them in kernel context, for an efficient
>>> profiler.
>>
>> Any comments on this patch? Thanks,
>>
>> Brendan
>
>
> Sorry for the late.
>
> I think it is a useful feature. Could you please provide an example
> to show how to use it in perf?
Yes, the following example samples at 999 Hertz, and emits the
instruction pointer only when it is within a custom address range, as
checked by BPF. Eg:
# ./perf record -e bpf-output/no-inherit,name=evt/ \
-e ./sampleip_range.c/map:channel.event=evt/ \
-a ./perf record -F 999 -e cpu-clock -N -a -o /dev/null sleep 5
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.000 MB /dev/null ]
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.134 MB perf.data (222 samples) ]
# ./perf script -F comm,pid,time,bpf-output
'bpf-output' not valid for hardware events. Ignoring.
'bpf-output' not valid for unknown events. Ignoring.
'bpf-output' not valid for unknown events. Ignoring.
dd 6501 3058.117379:
BPF output: 0000: 3c 4c 21 81 ff ff ff ff <L!.....
0008: 00 00 00 00 ....
dd 6501 3058.130392:
BPF output: 0000: 55 4c 21 81 ff ff ff ff UL!.....
0008: 00 00 00 00 ....
dd 6501 3058.131393:
BPF output: 0000: 55 4c 21 81 ff ff ff ff UL!.....
0008: 00 00 00 00 ....
dd 6501 3058.149411:
BPF output: 0000: e1 4b 21 81 ff ff ff ff .K!.....
0008: 00 00 00 00 ....
dd 6501 3058.155417:
BPF output: 0000: 76 4c 21 81 ff ff ff ff vL!.....
0008: 00 00 00 00 ....
For that example, perf is running a BPF program to emit filtered
details, and running a second perf to configure sampling. We can
certainly improve how this works. And this will be much more
interesting once perf can emit maps, and a perf BPF program can
populate a map.
Here's sampleip_range.c:
/************************ BEGIN **************************/
#include <uapi/linux/bpf.h>
#include <uapi/linux/ptrace.h>
#define SEC(NAME) __attribute__((section(NAME), used))
/*
* Edit the following to match the instruction address range you want to
* sample. Eg, look in /proc/kallsyms. The addresses will change for each
* kernel version and build.
*/
#define RANGE_START 0xffffffff81214b90
#define RANGE_END 0xffffffff81214cd0
struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
};
static int (*probe_read)(void *dst, int size, void *src) =
(void *)BPF_FUNC_probe_read;
static int (*get_smp_processor_id)(void) =
(void *)BPF_FUNC_get_smp_processor_id;
static int (*perf_event_output)(void *, struct bpf_map_def *, int, void *,
unsigned long) = (void *)BPF_FUNC_perf_event_output;
struct bpf_map_def SEC("maps") channel = {
.type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(u32),
.max_entries = __NR_CPUS__,
};
/* from /sys/kernel/debug/tracing/events/perf/perf_hrtimer/format */
struct perf_hrtimer_args {
unsigned long long pad;
struct pt_regs *regs;
struct perf_event *event;
};
SEC("perf:perf_hrtimer")
int func(struct perf_hrtimer_args *ctx)
{
struct pt_regs regs = {};
probe_read(®s, sizeof(regs), ctx->regs);
if (regs.ip >= RANGE_START && regs.ip < RANGE_END) {
perf_event_output(ctx, &channel, get_smp_processor_id(),
®s.ip, sizeof(regs.ip));
}
return 0;
}
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;
/************************* END ***************************/
>
> If I understand correctly, I can have a BPF script run 99 times per
> second using
>
> # perf -e cpu-clock/freq=99/ -e mybpf.c ...
>
> And in mybpf.c, attach a BPF script on the new tracepoint. Right?
>
> Also, since we already have timer:hrtimer_expire_entry, please provide
> some further information about why we need a new tracepoint.
timer:hrtimer_expire_entry fires for much more than just the perf
timer. The perf:perf_hrtimer tracepoint also has registers and perf
context as arguments, which can be used for profiling programs.
Thanks for the comments,
Brendan
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web