diff options
author | Wang Nan <wangnan0@huawei.com> | 2015-11-06 13:49:37 +0000 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-11-06 15:52:41 -0300 |
commit | 6371ca3b541c82d8aa6a9002bd52d92bcdda5944 (patch) | |
tree | a5cd09ea0ceb52772570d9ba7d24ccb971ed0c18 /tools/perf | |
parent | 0a62f6869f2768687af2c94d97f3b2fcf5b73367 (diff) | |
download | op-kernel-dev-6371ca3b541c82d8aa6a9002bd52d92bcdda5944.zip op-kernel-dev-6371ca3b541c82d8aa6a9002bd52d92bcdda5944.tar.gz |
bpf tools: Improve libbpf error reporting
In this patch, a series of libbpf specific error numbers and
libbpf_strerror() are introduced to help reporting errors.
Functions are updated to pass correct the error number through the
CHECK_ERR() macro.
All users of bpf_object__open{_buffer}() and bpf_program__title() in
perf are modified accordingly. In addition, due to the error codes
changing, bpf__strerror_load() is also modified to use them.
bpf__strerror_head() is also changed accordingly so it can parse libbpf
errors. bpf_loader_strerror() is introduced for that purpose, and will
be improved by the following patch.
load_program() is improved not to dump log buffer if it is empty. log
buffer is also used to deduce whether the error was caused by an invalid
program or other problem.
v1 -> v2:
- Using macro for error code.
- Fetch error message based on array index, eliminate for-loop.
- Use log buffer to detect the reason of failure. 3 new error code
are introduced to replace LIBBPF_ERRNO__LOAD.
In v1:
# perf record -e ./test_ill_program.o ls
event syntax error: './test_ill_program.o'
\___ Failed to load program: Validate your program and check 'license'/'version' sections in your object
SKIP
# perf record -e ./test_kversion_nomatch_program.o ls
event syntax error: './test_kversion_nomatch_program.o'
\___ Failed to load program: Validate your program and check 'license'/'version' sections in your object
SKIP
# perf record -e ./test_big_program.o ls
event syntax error: './test_big_program.o'
\___ Failed to load program: Validate your program and check 'license'/'version' sections in your object
SKIP
In v2:
# perf record -e ./test_ill_program.o ls
event syntax error: './test_ill_program.o'
\___ Kernel verifier blocks program loading
SKIP
# perf record -e ./test_kversion_nomatch_program.o
event syntax error: './test_kversion_nomatch_program.o'
\___ Incorrect kernel version
SKIP
(Will be further improved by following patches)
# perf record -e ./test_big_program.o
event syntax error: './test_big_program.o'
\___ Program too big
SKIP
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1446817783-86722-2-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/tests/llvm.c | 2 | ||||
-rw-r--r-- | tools/perf/util/bpf-loader.c | 33 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 4 |
3 files changed, 29 insertions, 10 deletions
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 512d362..8f713f6 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -27,7 +27,7 @@ static int test__bpf_parsing(void *obj_buf, size_t obj_buf_sz) struct bpf_object *obj; obj = bpf_object__open_buffer(obj_buf, obj_buf_sz, NULL); - if (!obj) + if (IS_ERR(obj)) return -1; bpf_object__close(obj); return 0; diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 0c5d174..c46256b 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -59,9 +59,9 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source) } else obj = bpf_object__open(filename); - if (!obj) { + if (IS_ERR(obj)) { pr_debug("bpf: failed to load %s\n", filename); - return ERR_PTR(-EINVAL); + return obj; } return obj; @@ -96,9 +96,9 @@ config_bpf_program(struct bpf_program *prog) int err; config_str = bpf_program__title(prog, false); - if (!config_str) { + if (IS_ERR(config_str)) { pr_debug("bpf: unable to get title for program\n"); - return -EINVAL; + return PTR_ERR(config_str); } priv = calloc(sizeof(*priv), 1); @@ -308,13 +308,34 @@ int bpf__foreach_tev(struct bpf_object *obj, return 0; } +static int +bpf_loader_strerror(int err, char *buf, size_t size) +{ + char sbuf[STRERR_BUFSIZE]; + const char *msg; + + if (!buf || !size) + return -1; + + err = err > 0 ? err : -err; + + if (err >= __LIBBPF_ERRNO__START) + return libbpf_strerror(err, buf, size); + + msg = strerror_r(err, sbuf, sizeof(sbuf)); + snprintf(buf, size, "%s", msg); + buf[size - 1] = '\0'; + return 0; +} + #define bpf__strerror_head(err, buf, size) \ char sbuf[STRERR_BUFSIZE], *emsg;\ if (!size)\ return 0;\ if (err < 0)\ err = -err;\ - emsg = strerror_r(err, sbuf, sizeof(sbuf));\ + bpf_loader_strerror(err, sbuf, sizeof(sbuf));\ + emsg = sbuf;\ switch (err) {\ default:\ scnprintf(buf, size, "%s", emsg);\ @@ -345,8 +366,6 @@ int bpf__strerror_load(struct bpf_object *obj __maybe_unused, int err, char *buf, size_t size) { bpf__strerror_head(err, buf, size); - bpf__strerror_entry(EINVAL, "%s: Are you root and runing a CONFIG_BPF_SYSCALL kernel?", - emsg) bpf__strerror_end(buf, size); return 0; } diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index bee6058..c75b25d 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -632,11 +632,11 @@ int parse_events_load_bpf(struct parse_events_evlist *data, struct bpf_object *obj; obj = bpf__prepare_load(bpf_file_name, source); - if (IS_ERR(obj) || !obj) { + if (IS_ERR(obj)) { char errbuf[BUFSIZ]; int err; - err = obj ? PTR_ERR(obj) : -EINVAL; + err = PTR_ERR(obj); if (err == -ENOTSUP) snprintf(errbuf, sizeof(errbuf), |