aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2019-05-08 09:20:02 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-05-28 17:37:44 -0400
commit6c398d723a6a6d27485e701ae21e50304ec95595 (patch)
tree47ad84386fb01fa0b00c48787d35c41ded16dd44 /tools/perf
parentcacddfe7b0804752528e8100461266ec33dc6b64 (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.c49
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
711static 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
735static 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
709static void 749static void
710dso_cache__free(struct dso *dso) 750dso_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