diff options
author | Alexei Starovoitov <ast@fb.com> | 2017-06-03 00:03:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-06-04 21:58:01 -0400 |
commit | f91840a32deef5cb1bf73338bc5010f843b01426 (patch) | |
tree | e7a3eec8f6794fda623941afb426db5c1f8472b0 /kernel/bpf/arraymap.c | |
parent | 5071034e4af709d6783b7d105dc296a5cc84739b (diff) |
perf, bpf: Add BPF support to all perf_event types
Allow BPF_PROG_TYPE_PERF_EVENT program types to attach to all
perf_event types, including HW_CACHE, RAW, and dynamic pmu events.
Only tracepoint/kprobe events are treated differently which require
BPF_PROG_TYPE_TRACEPOINT/BPF_PROG_TYPE_KPROBE program types accordingly.
Also add support for reading all event counters using
bpf_perf_event_read() helper.
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r-- | kernel/bpf/arraymap.c | 28 |
1 files changed, 7 insertions, 21 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 172dc8ee0e3b..ecb43542246e 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
@@ -452,38 +452,24 @@ static void bpf_event_entry_free_rcu(struct bpf_event_entry *ee) | |||
452 | static void *perf_event_fd_array_get_ptr(struct bpf_map *map, | 452 | static void *perf_event_fd_array_get_ptr(struct bpf_map *map, |
453 | struct file *map_file, int fd) | 453 | struct file *map_file, int fd) |
454 | { | 454 | { |
455 | const struct perf_event_attr *attr; | ||
456 | struct bpf_event_entry *ee; | 455 | struct bpf_event_entry *ee; |
457 | struct perf_event *event; | 456 | struct perf_event *event; |
458 | struct file *perf_file; | 457 | struct file *perf_file; |
458 | u64 value; | ||
459 | 459 | ||
460 | perf_file = perf_event_get(fd); | 460 | perf_file = perf_event_get(fd); |
461 | if (IS_ERR(perf_file)) | 461 | if (IS_ERR(perf_file)) |
462 | return perf_file; | 462 | return perf_file; |
463 | 463 | ||
464 | ee = ERR_PTR(-EOPNOTSUPP); | ||
464 | event = perf_file->private_data; | 465 | event = perf_file->private_data; |
465 | ee = ERR_PTR(-EINVAL); | 466 | if (perf_event_read_local(event, &value) == -EOPNOTSUPP) |
466 | |||
467 | attr = perf_event_attrs(event); | ||
468 | if (IS_ERR(attr) || attr->inherit) | ||
469 | goto err_out; | 467 | goto err_out; |
470 | 468 | ||
471 | switch (attr->type) { | 469 | ee = bpf_event_entry_gen(perf_file, map_file); |
472 | case PERF_TYPE_SOFTWARE: | 470 | if (ee) |
473 | if (attr->config != PERF_COUNT_SW_BPF_OUTPUT) | 471 | return ee; |
474 | goto err_out; | 472 | ee = ERR_PTR(-ENOMEM); |
475 | /* fall-through */ | ||
476 | case PERF_TYPE_RAW: | ||
477 | case PERF_TYPE_HARDWARE: | ||
478 | ee = bpf_event_entry_gen(perf_file, map_file); | ||
479 | if (ee) | ||
480 | return ee; | ||
481 | ee = ERR_PTR(-ENOMEM); | ||
482 | /* fall-through */ | ||
483 | default: | ||
484 | break; | ||
485 | } | ||
486 | |||
487 | err_out: | 473 | err_out: |
488 | fput(perf_file); | 474 | fput(perf_file); |
489 | return ee; | 475 | return ee; |