forked from Minki/linux
030910c085
Having "test" in almost all test descriptions is redundant, simplify it removing and rewriting tests with such descriptions. End result: # perf test 1: vmlinux symtab matches kallsyms : Ok 2: Detect openat syscall event : Ok 3: Detect openat syscall event on all cpus : Ok 4: Read samples using the mmap interface : Ok 5: Parse event definition strings : Ok 6: PERF_RECORD_* events & perf_sample fields : Ok 7: Parse perf pmu format : Ok 8: DSO data read : Ok 9: DSO data cache : Ok 10: DSO data reopen : Ok 11: Roundtrip evsel->name : Ok 12: Parse sched tracepoints fields : Ok 13: syscalls:sys_enter_openat event fields : Ok 14: Setup struct perf_event_attr : Ok 15: Match and link multiple hists : Ok 16: 'import perf' in python : Ok 17: Breakpoint overflow signal handler : Ok 18: Breakpoint overflow sampling : Ok 19: Number of exit events of a simple workload : Ok 20: Software clock events period values : Ok 21: Object code reading : Ok 22: Sample parsing : Ok 23: Use a dummy software event to keep tracking: Ok 24: Parse with no sample_id_all bit set : Ok 25: Filter hist entries : Ok 26: Lookup mmap thread : Ok 27: Share thread mg : Ok 28: Sort output of hist entries : Ok 29: Cumulate child hist entries : Ok 30: Track with sched_switch : Ok 31: Filter fds with revents mask in a fdarray : Ok 32: Add fd to a fdarray, making it autogrow : Ok 33: kmod_path__parse : Ok 34: Thread map : Ok 35: LLVM search and compile : 35.1: Basic BPF llvm compile : Ok 35.2: kbuild searching : Ok 35.3: Compile source for BPF prologue generation: Ok 35.4: Compile source for BPF relocation : Ok 36: Session topology : Ok 37: BPF filter : 37.1: Basic BPF filtering : Ok 37.2: BPF prologue generation : Ok 37.3: BPF relocation checker : Ok 38: Synthesize thread map : Ok 39: Synthesize cpu map : Ok 40: Synthesize stat config : Ok 41: Synthesize stat : Ok 42: Synthesize stat round : Ok 43: Synthesize attr update : Ok 44: Event times : Ok 45: Read backward ring buffer : Ok 46: Print cpu map : Ok 47: Probe SDT events : Ok 48: is_printable_array : Ok 49: Print bitmap : Ok 50: perf hooks : Ok 51: x86 rdpmc : Ok 52: Convert perf time to TSC : Ok 53: DWARF unwind : Ok 54: x86 instruction decoder - new instructions : Ok 55: Intel cqm nmi context read : Skip # Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-rx2lbfcrrio2yx1fxcljqy0e@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
172 lines
3.9 KiB
C
172 lines
3.9 KiB
C
#include <stdio.h>
|
|
#include <bpf/libbpf.h>
|
|
#include <util/llvm-utils.h>
|
|
#include <util/cache.h>
|
|
#include "llvm.h"
|
|
#include "tests.h"
|
|
#include "debug.h"
|
|
#include "util.h"
|
|
|
|
#ifdef HAVE_LIBBPF_SUPPORT
|
|
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 (IS_ERR(obj))
|
|
return TEST_FAIL;
|
|
bpf_object__close(obj);
|
|
return TEST_OK;
|
|
}
|
|
#else
|
|
static int test__bpf_parsing(void *obj_buf __maybe_unused,
|
|
size_t obj_buf_sz __maybe_unused)
|
|
{
|
|
pr_debug("Skip bpf parsing\n");
|
|
return TEST_OK;
|
|
}
|
|
#endif
|
|
|
|
static struct {
|
|
const char *source;
|
|
const char *desc;
|
|
bool should_load_fail;
|
|
} bpf_source_table[__LLVM_TESTCASE_MAX] = {
|
|
[LLVM_TESTCASE_BASE] = {
|
|
.source = test_llvm__bpf_base_prog,
|
|
.desc = "Basic BPF llvm compile",
|
|
},
|
|
[LLVM_TESTCASE_KBUILD] = {
|
|
.source = test_llvm__bpf_test_kbuild_prog,
|
|
.desc = "kbuild searching",
|
|
},
|
|
[LLVM_TESTCASE_BPF_PROLOGUE] = {
|
|
.source = test_llvm__bpf_test_prologue_prog,
|
|
.desc = "Compile source for BPF prologue generation",
|
|
},
|
|
[LLVM_TESTCASE_BPF_RELOCATION] = {
|
|
.source = test_llvm__bpf_test_relocation,
|
|
.desc = "Compile source for BPF relocation",
|
|
.should_load_fail = true,
|
|
},
|
|
};
|
|
|
|
int
|
|
test_llvm__fetch_bpf_obj(void **p_obj_buf,
|
|
size_t *p_obj_buf_sz,
|
|
enum test_llvm__testcase idx,
|
|
bool force,
|
|
bool *should_load_fail)
|
|
{
|
|
const char *source;
|
|
const char *desc;
|
|
const char *tmpl_old, *clang_opt_old;
|
|
char *tmpl_new = NULL, *clang_opt_new = NULL;
|
|
int err, old_verbose, ret = TEST_FAIL;
|
|
|
|
if (idx >= __LLVM_TESTCASE_MAX)
|
|
return TEST_FAIL;
|
|
|
|
source = bpf_source_table[idx].source;
|
|
desc = bpf_source_table[idx].desc;
|
|
if (should_load_fail)
|
|
*should_load_fail = bpf_source_table[idx].should_load_fail;
|
|
|
|
/*
|
|
* Skip this test if user's .perfconfig doesn't set [llvm] section
|
|
* and clang is not found in $PATH, and this is not perf test -v
|
|
*/
|
|
if (!force && (verbose == 0 &&
|
|
!llvm_param.user_set_param &&
|
|
llvm__search_clang())) {
|
|
pr_debug("No clang and no verbosive, skip this test\n");
|
|
return TEST_SKIP;
|
|
}
|
|
|
|
/*
|
|
* llvm is verbosity when error. Suppress all error output if
|
|
* not 'perf test -v'.
|
|
*/
|
|
old_verbose = verbose;
|
|
if (verbose == 0)
|
|
verbose = -1;
|
|
|
|
*p_obj_buf = NULL;
|
|
*p_obj_buf_sz = 0;
|
|
|
|
if (!llvm_param.clang_bpf_cmd_template)
|
|
goto out;
|
|
|
|
if (!llvm_param.clang_opt)
|
|
llvm_param.clang_opt = strdup("");
|
|
|
|
err = asprintf(&tmpl_new, "echo '%s' | %s%s", source,
|
|
llvm_param.clang_bpf_cmd_template,
|
|
old_verbose ? "" : " 2>/dev/null");
|
|
if (err < 0)
|
|
goto out;
|
|
err = asprintf(&clang_opt_new, "-xc %s", llvm_param.clang_opt);
|
|
if (err < 0)
|
|
goto out;
|
|
|
|
tmpl_old = llvm_param.clang_bpf_cmd_template;
|
|
llvm_param.clang_bpf_cmd_template = tmpl_new;
|
|
clang_opt_old = llvm_param.clang_opt;
|
|
llvm_param.clang_opt = clang_opt_new;
|
|
|
|
err = llvm__compile_bpf("-", p_obj_buf, p_obj_buf_sz);
|
|
|
|
llvm_param.clang_bpf_cmd_template = tmpl_old;
|
|
llvm_param.clang_opt = clang_opt_old;
|
|
|
|
verbose = old_verbose;
|
|
if (err)
|
|
goto out;
|
|
|
|
ret = TEST_OK;
|
|
out:
|
|
free(tmpl_new);
|
|
free(clang_opt_new);
|
|
if (ret != TEST_OK)
|
|
pr_debug("Failed to compile test case: '%s'\n", desc);
|
|
return ret;
|
|
}
|
|
|
|
int test__llvm(int subtest)
|
|
{
|
|
int ret;
|
|
void *obj_buf = NULL;
|
|
size_t obj_buf_sz = 0;
|
|
bool should_load_fail = false;
|
|
|
|
if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
|
|
return TEST_FAIL;
|
|
|
|
ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
|
|
subtest, false, &should_load_fail);
|
|
|
|
if (ret == TEST_OK && !should_load_fail) {
|
|
ret = test__bpf_parsing(obj_buf, obj_buf_sz);
|
|
if (ret != TEST_OK) {
|
|
pr_debug("Failed to parse test case '%s'\n",
|
|
bpf_source_table[subtest].desc);
|
|
}
|
|
}
|
|
free(obj_buf);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int test__llvm_subtest_get_nr(void)
|
|
{
|
|
return __LLVM_TESTCASE_MAX;
|
|
}
|
|
|
|
const char *test__llvm_subtest_get_desc(int subtest)
|
|
{
|
|
if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
|
|
return NULL;
|
|
|
|
return bpf_source_table[subtest].desc;
|
|
}
|