diff options
| author | Jiri Olsa <jolsa@kernel.org> | 2019-05-08 09:20:02 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2019-05-28 17:37:44 -0400 |
| commit | 6c398d723a6a6d27485e701ae21e50304ec95595 (patch) | |
| tree | 47ad84386fb01fa0b00c48787d35c41ded16dd44 /tools/perf | |
| parent | cacddfe7b0804752528e8100461266ec33dc6b64 (diff) | |
perf dso: Add BPF DSO read and size hooks
Add BPF related code into DSO reading paths to return size (bpf_size)
and read the BPF code (bpf_read).
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stanislav Fomichev <sdf@google.com>
Link: http://lkml.kernel.org/r/20190508132010.14512-5-jolsa@kernel.org
[ Use uintptr_t when casting from u64 to u8 pointers ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/util/dso.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 1e6a045adb8c..1fb18292c2d3 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c | |||
| @@ -9,6 +9,8 @@ | |||
| 9 | #include <errno.h> | 9 | #include <errno.h> |
| 10 | #include <fcntl.h> | 10 | #include <fcntl.h> |
| 11 | #include <libgen.h> | 11 | #include <libgen.h> |
| 12 | #include <bpf/libbpf.h> | ||
| 13 | #include "bpf-event.h" | ||
| 12 | #include "compress.h" | 14 | #include "compress.h" |
| 13 | #include "namespaces.h" | 15 | #include "namespaces.h" |
| 14 | #include "path.h" | 16 | #include "path.h" |
| @@ -706,6 +708,44 @@ bool dso__data_status_seen(struct dso *dso, enum dso_data_status_seen by) | |||
| 706 | return false; | 708 | return false; |
| 707 | } | 709 | } |
| 708 | 710 | ||
| 711 | static ssize_t bpf_read(struct dso *dso, u64 offset, char *data) | ||
| 712 | { | ||
| 713 | struct bpf_prog_info_node *node; | ||
| 714 | ssize_t size = DSO__DATA_CACHE_SIZE; | ||
| 715 | u64 len; | ||
| 716 | u8 *buf; | ||
| 717 | |||
| 718 | node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); | ||
| 719 | if (!node || !node->info_linear) { | ||
| 720 | dso->data.status = DSO_DATA_STATUS_ERROR; | ||
| 721 | return -1; | ||
| 722 | } | ||
| 723 | |||
| 724 | len = node->info_linear->info.jited_prog_len; | ||
| 725 | buf = (u8 *)(uintptr_t)node->info_linear->info.jited_prog_insns; | ||
| 726 | |||
| 727 | if (offset >= len) | ||
| 728 | return -1; | ||
| 729 | |||
| 730 | size = (ssize_t)min(len - offset, (u64)size); | ||
| 731 | memcpy(data, buf + offset, size); | ||
| 732 | return size; | ||
| 733 | } | ||
| 734 | |||
| 735 | static int bpf_size(struct dso *dso) | ||
| 736 | { | ||
| 737 | struct bpf_prog_info_node *node; | ||
| 738 | |||
| 739 | node = perf_env__find_bpf_prog_info(dso->bpf_prog.env, dso->bpf_prog.id); | ||
| 740 | if (!node || !node->info_linear) { | ||
| 741 | dso->data.status = DSO_DATA_STATUS_ERROR; | ||
| 742 | return -1; | ||
| 743 | } | ||
| 744 | |||
| 745 | dso->data.file_size = node->info_linear->info.jited_prog_len; | ||
| 746 | return 0; | ||
| 747 | } | ||
| 748 | |||
| 709 | static void | 749 | static void |
| 710 | dso_cache__free(struct dso *dso) | 750 | dso_cache__free(struct dso *dso) |
| 711 | { | 751 | { |
| @@ -832,7 +872,11 @@ dso_cache__read(struct dso *dso, struct machine *machine, | |||
| 832 | if (!cache) | 872 | if (!cache) |
| 833 | return -ENOMEM; | 873 | return -ENOMEM; |
| 834 | 874 | ||
| 835 | ret = file_read(dso, machine, cache_offset, cache->data); | 875 | if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) |
| 876 | ret = bpf_read(dso, cache_offset, cache->data); | ||
| 877 | else | ||
| 878 | ret = file_read(dso, machine, cache_offset, cache->data); | ||
| 879 | |||
| 836 | if (ret > 0) { | 880 | if (ret > 0) { |
| 837 | cache->offset = cache_offset; | 881 | cache->offset = cache_offset; |
| 838 | cache->size = ret; | 882 | cache->size = ret; |
| @@ -941,6 +985,9 @@ int dso__data_file_size(struct dso *dso, struct machine *machine) | |||
| 941 | if (dso->data.status == DSO_DATA_STATUS_ERROR) | 985 | if (dso->data.status == DSO_DATA_STATUS_ERROR) |
| 942 | return -1; | 986 | return -1; |
| 943 | 987 | ||
| 988 | if (dso->binary_type == DSO_BINARY_TYPE__BPF_PROG_INFO) | ||
| 989 | return bpf_size(dso); | ||
| 990 | |||
| 944 | return file_size(dso, machine); | 991 | return file_size(dso, machine); |
| 945 | } | 992 | } |
| 946 | 993 | ||
