![Linus Torvalds](/assets/img/avatar_default.png)
Pull perf update from Ingo Molnar: "Lots of changes in this cycle as well, with hundreds of commits from over 30 contributors. Most of the activity was on the tooling side. Higher level changes: - New 'perf kvm' analysis tool, from Xiao Guangrong. - New 'perf trace' system-wide tracing tool - uprobes fixes + cleanups from Oleg Nesterov. - Lots of patches to make perf build on Android out of box, from Irina Tirdea - Extend ftrace function tracing utility to be more dynamic for its users. It allows for data passing to the callback functions, as well as reading regs as if a breakpoint were to trigger at function entry. The main goal of this patch series was to allow kprobes to use ftrace as an optimized probe point when a probe is placed on an ftrace nop. With lots of help from Masami Hiramatsu, and going through lots of iterations, we finally came up with a good solution. - Add cpumask for uncore pmu, use it in 'stat', from Yan, Zheng. - Various tracing updates from Steve Rostedt - Clean up and improve 'perf sched' performance by elliminating lots of needless calls to libtraceevent. - Event group parsing support, from Jiri Olsa - UI/gtk refactorings and improvements from Namhyung Kim - Add support for non-tracepoint events in perf script python, from Feng Tang - Add --symbols to 'script', similar to the one in 'report', from Feng Tang. Infrastructure enhancements and fixes: - Convert the trace builtins to use the growing evsel/evlist tracepoint infrastructure, removing several open coded constructs like switch like series of strcmp to dispatch events, etc. Basically what had already been showcased in 'perf sched'. - Add evsel constructor for tracepoints, that uses libtraceevent just to parse the /format events file, use it in a new 'perf test' to make sure the libtraceevent format parsing regressions can be more readily caught. - Some strange errors were happening in some builds, but not on the next, reported by several people, problem was some parser related files, generated during the build, didn't had proper make deps, fix from Eric Sandeen. - Introduce struct and cache information about the environment where a perf.data file was captured, from Namhyung Kim. - Fix handling of unresolved samples when --symbols is used in 'report', from Feng Tang. - Add union member access support to 'probe', from Hyeoncheol Lee. - Fixups to die() removal, from Namhyung Kim. - Render fixes for the TUI, from Namhyung Kim. - Don't enable annotation in non symbolic view, from Namhyung Kim. - Fix pipe mode in 'report', from Namhyung Kim. - Move related stats code from stat to util/, will be used by the 'stat' kvm tool, from Xiao Guangrong. - Remove die()/exit() calls from several tools. - Resolve vdso callchains, from Jiri Olsa - Don't pass const char pointers to basename, so that we can unconditionally use libgen.h and thus avoid ifdef BIONIC lines, from David Ahern - Refactor hist formatting so that it can be reused with the GTK browser, From Namhyung Kim - Fix build for another rbtree.c change, from Adrian Hunter. - Make 'perf diff' command work with evsel hists, from Jiri Olsa. - Use the only field_sep var that is set up: symbol_conf.field_sep, fix from Jiri Olsa. - .gitignore compiled python binaries, from Namhyung Kim. - Get rid of die() in more libtraceevent places, from Namhyung Kim. - Rename libtraceevent 'private' struct member to 'priv' so that it works in C++, from Steven Rostedt - Remove lots of exit()/die() calls from tools so that the main perf exit routine can take place, from David Ahern - Fix x86 build on x86-64, from David Ahern. - {int,str,rb}list fixes from Suzuki K Poulose - perf.data header fixes from Namhyung Kim - Allow user to indicate objdump path, needed in cross environments, from Maciek Borzecki - Fix hardware cache event name generation, fix from Jiri Olsa - Add round trip test for sw, hw and cache event names, catching the problem Jiri fixed, after Jiri's patch, the test passes successfully. - Clean target should do clean for lib/traceevent too, fix from David Ahern - Check the right variable for allocation failure, fix from Namhyung Kim - Set up evsel->tp_format regardless of evsel->name being set already, fix from Namhyung Kim - Oprofile fixes from Robert Richter. - Remove perf_event_attr needless version inflation, from Jiri Olsa - Introduce libtraceevent strerror like error reporting facility, from Namhyung Kim - Add pmu mappings to perf.data header and use event names from cmd line, from Robert Richter - Fix include order for bison/flex-generated C files, from Ben Hutchings - Build fixes and documentation corrections from David Ahern - Assorted cleanups from Robert Richter - Let O= makes handle relative paths, from Steven Rostedt - perf script python fixes, from Feng Tang. - Initial bash completion support, from Frederic Weisbecker - Allow building without libelf, from Namhyung Kim. - Support DWARF CFI based unwind to have callchains when %bp based unwinding is not possible, from Jiri Olsa. - Symbol resolution fixes, while fixing support PPC64 files with an .opt ELF section was the end goal, several fixes for code that handles all architectures and cleanups are included, from Cody Schafer. - Assorted fixes for Documentation and build in 32 bit, from Robert Richter - Cache the libtraceevent event_format associated to each evsel early, so that we avoid relookups, i.e. calling pevent_find_event repeatedly when processing tracepoint events. [ This is to reduce the surface contact with libtraceevents and make clear what is that the perf tools needs from that lib: so far parsing the common and per event fields. ] - Don't stop the build if the audit libraries are not installed, fix from Namhyung Kim. - Fix bfd.h/libbfd detection with recent binutils, from Markus Trippelsdorf. - Improve warning message when libunwind devel packages not present, from Jiri Olsa" * 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (282 commits) perf trace: Add aliases for some syscalls perf probe: Print an enum type variable in "enum variable-name" format when showing accessible variables perf tools: Check libaudit availability for perf-trace builtin perf hists: Add missing period_* fields when collapsing a hist entry perf trace: New tool perf evsel: Export the event_format constructor perf evsel: Introduce rawptr() method perf tools: Use perf_evsel__newtp in the event parser perf evsel: The tracepoint constructor should store sys:name perf evlist: Introduce set_filter() method perf evlist: Renane set_filters method to apply_filters perf test: Add test to check we correctly parse and match syscall open parms perf evsel: Handle endianity in intval method perf evsel: Know if byte swap is needed perf tools: Allow handling a NULL cpu_map as meaning "all cpus" perf evsel: Improve tracepoint constructor setup tools lib traceevent: Fix error path on pevent_parse_event perf test: Fix build failure trace: Move trace event enable from fs_initcall to core_initcall tracing: Add an option for disabling markers ...
1045 lines
35 KiB
C
1045 lines
35 KiB
C
|
|
#include "parse-events.h"
|
|
#include "evsel.h"
|
|
#include "evlist.h"
|
|
#include "sysfs.h"
|
|
#include "../../../include/linux/hw_breakpoint.h"
|
|
|
|
#define TEST_ASSERT_VAL(text, cond) \
|
|
do { \
|
|
if (!(cond)) { \
|
|
pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \
|
|
return -1; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \
|
|
PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD)
|
|
|
|
static int test__checkevent_tracepoint(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong sample_type",
|
|
PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
|
|
TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
|
|
|
|
list_for_each_entry(evsel, &evlist->entries, node) {
|
|
TEST_ASSERT_VAL("wrong type",
|
|
PERF_TYPE_TRACEPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong sample_type",
|
|
PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
|
|
TEST_ASSERT_VAL("wrong sample_period",
|
|
1 == evsel->attr.sample_period);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_raw(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_numeric(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_symbolic_name(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong period",
|
|
100000 == evsel->attr.sample_period);
|
|
TEST_ASSERT_VAL("wrong config1",
|
|
0 == evsel->attr.config1);
|
|
TEST_ASSERT_VAL("wrong config2",
|
|
1 == evsel->attr.config2);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_symbolic_alias(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_genhw(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_breakpoint(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) ==
|
|
evsel->attr.bp_type);
|
|
TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 ==
|
|
evsel->attr.bp_len);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_x(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong bp_type",
|
|
HW_BREAKPOINT_X == evsel->attr.bp_type);
|
|
TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_r(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type",
|
|
PERF_TYPE_BREAKPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong bp_type",
|
|
HW_BREAKPOINT_R == evsel->attr.bp_type);
|
|
TEST_ASSERT_VAL("wrong bp_len",
|
|
HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_w(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type",
|
|
PERF_TYPE_BREAKPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong bp_type",
|
|
HW_BREAKPOINT_W == evsel->attr.bp_type);
|
|
TEST_ASSERT_VAL("wrong bp_len",
|
|
HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type",
|
|
PERF_TYPE_BREAKPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong bp_type",
|
|
(HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type);
|
|
TEST_ASSERT_VAL("wrong bp_len",
|
|
HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len);
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
|
|
return test__checkevent_tracepoint(evlist);
|
|
}
|
|
|
|
static int
|
|
test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1);
|
|
|
|
list_for_each_entry(evsel, &evlist->entries, node) {
|
|
TEST_ASSERT_VAL("wrong exclude_user",
|
|
!evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel",
|
|
evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
}
|
|
|
|
return test__checkevent_tracepoint_multi(evlist);
|
|
}
|
|
|
|
static int test__checkevent_raw_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
|
|
return test__checkevent_raw(evlist);
|
|
}
|
|
|
|
static int test__checkevent_numeric_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
|
|
return test__checkevent_numeric(evlist);
|
|
}
|
|
|
|
static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
|
|
return test__checkevent_symbolic_name(evlist);
|
|
}
|
|
|
|
static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
|
|
return test__checkevent_symbolic_name(evlist);
|
|
}
|
|
|
|
static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
|
|
return test__checkevent_symbolic_name(evlist);
|
|
}
|
|
|
|
static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
|
|
return test__checkevent_symbolic_alias(evlist);
|
|
}
|
|
|
|
static int test__checkevent_genhw_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
|
|
return test__checkevent_genhw(evlist);
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong name",
|
|
!strcmp(perf_evsel__name(evsel), "mem:0:u"));
|
|
|
|
return test__checkevent_breakpoint(evlist);
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong name",
|
|
!strcmp(perf_evsel__name(evsel), "mem:0:x:k"));
|
|
|
|
return test__checkevent_breakpoint_x(evlist);
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong name",
|
|
!strcmp(perf_evsel__name(evsel), "mem:0:r:hp"));
|
|
|
|
return test__checkevent_breakpoint_r(evlist);
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong name",
|
|
!strcmp(perf_evsel__name(evsel), "mem:0:w:up"));
|
|
|
|
return test__checkevent_breakpoint_w(evlist);
|
|
}
|
|
|
|
static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong name",
|
|
!strcmp(perf_evsel__name(evsel), "mem:0:rw:kp"));
|
|
|
|
return test__checkevent_breakpoint_rw(evlist);
|
|
}
|
|
|
|
static int test__checkevent_pmu(struct perf_evlist *evlist)
|
|
{
|
|
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1);
|
|
TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2);
|
|
TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_list(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries);
|
|
|
|
/* r1 */
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1);
|
|
TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
|
|
/* syscalls:sys_enter_open:k */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong sample_type",
|
|
PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
|
|
TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
|
|
/* 1:1:hp */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkevent_pmu_name(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel = perf_evlist__first(evlist);
|
|
|
|
/* cpu/config=1,name=krava/u */
|
|
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava"));
|
|
|
|
/* cpu/config=2/u" */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong name",
|
|
!strcmp(perf_evsel__name(evsel), "cpu/config=2/u"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__checkterms_simple(struct list_head *terms)
|
|
{
|
|
struct parse_events__term *term;
|
|
|
|
/* config=10 */
|
|
term = list_entry(terms->next, struct parse_events__term, list);
|
|
TEST_ASSERT_VAL("wrong type term",
|
|
term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG);
|
|
TEST_ASSERT_VAL("wrong type val",
|
|
term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
|
|
TEST_ASSERT_VAL("wrong val", term->val.num == 10);
|
|
TEST_ASSERT_VAL("wrong config", !term->config);
|
|
|
|
/* config1 */
|
|
term = list_entry(term->list.next, struct parse_events__term, list);
|
|
TEST_ASSERT_VAL("wrong type term",
|
|
term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1);
|
|
TEST_ASSERT_VAL("wrong type val",
|
|
term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
|
|
TEST_ASSERT_VAL("wrong val", term->val.num == 1);
|
|
TEST_ASSERT_VAL("wrong config", !term->config);
|
|
|
|
/* config2=3 */
|
|
term = list_entry(term->list.next, struct parse_events__term, list);
|
|
TEST_ASSERT_VAL("wrong type term",
|
|
term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2);
|
|
TEST_ASSERT_VAL("wrong type val",
|
|
term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
|
|
TEST_ASSERT_VAL("wrong val", term->val.num == 3);
|
|
TEST_ASSERT_VAL("wrong config", !term->config);
|
|
|
|
/* umask=1*/
|
|
term = list_entry(term->list.next, struct parse_events__term, list);
|
|
TEST_ASSERT_VAL("wrong type term",
|
|
term->type_term == PARSE_EVENTS__TERM_TYPE_USER);
|
|
TEST_ASSERT_VAL("wrong type val",
|
|
term->type_val == PARSE_EVENTS__TERM_TYPE_NUM);
|
|
TEST_ASSERT_VAL("wrong val", term->val.num == 1);
|
|
TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask"));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__group1(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel, *leader;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
|
|
|
|
/* instructions:k */
|
|
evsel = leader = perf_evlist__first(evlist);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
/* cycles:upp */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__group2(struct perf_evlist *evlist)
|
|
{
|
|
struct perf_evsel *evsel, *leader;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries);
|
|
|
|
/* faults + :ku modifier */
|
|
evsel = leader = perf_evlist__first(evlist);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
/* cache-references + :u modifier */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CACHE_REFERENCES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
|
|
/* cycles:k */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__group3(struct perf_evlist *evlist __maybe_unused)
|
|
{
|
|
struct perf_evsel *evsel, *leader;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries);
|
|
|
|
/* group1 syscalls:sys_enter_open:H */
|
|
evsel = leader = perf_evlist__first(evlist);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong sample_type",
|
|
PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type);
|
|
TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
TEST_ASSERT_VAL("wrong group name",
|
|
!strcmp(leader->group_name, "group1"));
|
|
|
|
/* group1 cycles:kppp */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
|
|
|
/* group2 cycles + G modifier */
|
|
evsel = leader = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
TEST_ASSERT_VAL("wrong group name",
|
|
!strcmp(leader->group_name, "group2"));
|
|
|
|
/* group2 1:3 + G modifier */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config", 3 == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
|
|
/* instructions:u */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__group4(struct perf_evlist *evlist __maybe_unused)
|
|
{
|
|
struct perf_evsel *evsel, *leader;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
|
|
|
|
/* cycles:u + p */
|
|
evsel = leader = perf_evlist__first(evlist);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1);
|
|
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
/* instructions:kp + p */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test__group5(struct perf_evlist *evlist __maybe_unused)
|
|
{
|
|
struct perf_evsel *evsel, *leader;
|
|
|
|
TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries);
|
|
|
|
/* cycles + G */
|
|
evsel = leader = perf_evlist__first(evlist);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
/* instructions + G */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
|
|
/* cycles:G */
|
|
evsel = leader = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
/* instructions:G */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
|
|
|
|
/* cycles */
|
|
evsel = perf_evsel__next(evsel);
|
|
TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
|
|
TEST_ASSERT_VAL("wrong config",
|
|
PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
|
|
TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
|
|
TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
|
|
TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
|
|
TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
|
|
TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
|
|
TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
|
|
TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct test__event_st {
|
|
const char *name;
|
|
__u32 type;
|
|
int (*check)(struct perf_evlist *evlist);
|
|
};
|
|
|
|
static struct test__event_st test__events[] = {
|
|
[0] = {
|
|
.name = "syscalls:sys_enter_open",
|
|
.check = test__checkevent_tracepoint,
|
|
},
|
|
[1] = {
|
|
.name = "syscalls:*",
|
|
.check = test__checkevent_tracepoint_multi,
|
|
},
|
|
[2] = {
|
|
.name = "r1a",
|
|
.check = test__checkevent_raw,
|
|
},
|
|
[3] = {
|
|
.name = "1:1",
|
|
.check = test__checkevent_numeric,
|
|
},
|
|
[4] = {
|
|
.name = "instructions",
|
|
.check = test__checkevent_symbolic_name,
|
|
},
|
|
[5] = {
|
|
.name = "cycles/period=100000,config2/",
|
|
.check = test__checkevent_symbolic_name_config,
|
|
},
|
|
[6] = {
|
|
.name = "faults",
|
|
.check = test__checkevent_symbolic_alias,
|
|
},
|
|
[7] = {
|
|
.name = "L1-dcache-load-miss",
|
|
.check = test__checkevent_genhw,
|
|
},
|
|
[8] = {
|
|
.name = "mem:0",
|
|
.check = test__checkevent_breakpoint,
|
|
},
|
|
[9] = {
|
|
.name = "mem:0:x",
|
|
.check = test__checkevent_breakpoint_x,
|
|
},
|
|
[10] = {
|
|
.name = "mem:0:r",
|
|
.check = test__checkevent_breakpoint_r,
|
|
},
|
|
[11] = {
|
|
.name = "mem:0:w",
|
|
.check = test__checkevent_breakpoint_w,
|
|
},
|
|
[12] = {
|
|
.name = "syscalls:sys_enter_open:k",
|
|
.check = test__checkevent_tracepoint_modifier,
|
|
},
|
|
[13] = {
|
|
.name = "syscalls:*:u",
|
|
.check = test__checkevent_tracepoint_multi_modifier,
|
|
},
|
|
[14] = {
|
|
.name = "r1a:kp",
|
|
.check = test__checkevent_raw_modifier,
|
|
},
|
|
[15] = {
|
|
.name = "1:1:hp",
|
|
.check = test__checkevent_numeric_modifier,
|
|
},
|
|
[16] = {
|
|
.name = "instructions:h",
|
|
.check = test__checkevent_symbolic_name_modifier,
|
|
},
|
|
[17] = {
|
|
.name = "faults:u",
|
|
.check = test__checkevent_symbolic_alias_modifier,
|
|
},
|
|
[18] = {
|
|
.name = "L1-dcache-load-miss:kp",
|
|
.check = test__checkevent_genhw_modifier,
|
|
},
|
|
[19] = {
|
|
.name = "mem:0:u",
|
|
.check = test__checkevent_breakpoint_modifier,
|
|
},
|
|
[20] = {
|
|
.name = "mem:0:x:k",
|
|
.check = test__checkevent_breakpoint_x_modifier,
|
|
},
|
|
[21] = {
|
|
.name = "mem:0:r:hp",
|
|
.check = test__checkevent_breakpoint_r_modifier,
|
|
},
|
|
[22] = {
|
|
.name = "mem:0:w:up",
|
|
.check = test__checkevent_breakpoint_w_modifier,
|
|
},
|
|
[23] = {
|
|
.name = "r1,syscalls:sys_enter_open:k,1:1:hp",
|
|
.check = test__checkevent_list,
|
|
},
|
|
[24] = {
|
|
.name = "instructions:G",
|
|
.check = test__checkevent_exclude_host_modifier,
|
|
},
|
|
[25] = {
|
|
.name = "instructions:H",
|
|
.check = test__checkevent_exclude_guest_modifier,
|
|
},
|
|
[26] = {
|
|
.name = "mem:0:rw",
|
|
.check = test__checkevent_breakpoint_rw,
|
|
},
|
|
[27] = {
|
|
.name = "mem:0:rw:kp",
|
|
.check = test__checkevent_breakpoint_rw_modifier,
|
|
},
|
|
[28] = {
|
|
.name = "{instructions:k,cycles:upp}",
|
|
.check = test__group1,
|
|
},
|
|
[29] = {
|
|
.name = "{faults:k,cache-references}:u,cycles:k",
|
|
.check = test__group2,
|
|
},
|
|
[30] = {
|
|
.name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u",
|
|
.check = test__group3,
|
|
},
|
|
[31] = {
|
|
.name = "{cycles:u,instructions:kp}:p",
|
|
.check = test__group4,
|
|
},
|
|
[32] = {
|
|
.name = "{cycles,instructions}:G,{cycles:G,instructions:G},cycles",
|
|
.check = test__group5,
|
|
},
|
|
};
|
|
|
|
static struct test__event_st test__events_pmu[] = {
|
|
[0] = {
|
|
.name = "cpu/config=10,config1,config2=3,period=1000/u",
|
|
.check = test__checkevent_pmu,
|
|
},
|
|
[1] = {
|
|
.name = "cpu/config=1,name=krava/u,cpu/config=2/u",
|
|
.check = test__checkevent_pmu_name,
|
|
},
|
|
};
|
|
|
|
struct test__term {
|
|
const char *str;
|
|
__u32 type;
|
|
int (*check)(struct list_head *terms);
|
|
};
|
|
|
|
static struct test__term test__terms[] = {
|
|
[0] = {
|
|
.str = "config=10,config1,config2=3,umask=1",
|
|
.check = test__checkterms_simple,
|
|
},
|
|
};
|
|
|
|
static int test_event(struct test__event_st *e)
|
|
{
|
|
struct perf_evlist *evlist;
|
|
int ret;
|
|
|
|
evlist = perf_evlist__new(NULL, NULL);
|
|
if (evlist == NULL)
|
|
return -ENOMEM;
|
|
|
|
ret = parse_events(evlist, e->name, 0);
|
|
if (ret) {
|
|
pr_debug("failed to parse event '%s', err %d\n",
|
|
e->name, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = e->check(evlist);
|
|
perf_evlist__delete(evlist);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int test_events(struct test__event_st *events, unsigned cnt)
|
|
{
|
|
int ret1, ret2 = 0;
|
|
unsigned i;
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
struct test__event_st *e = &events[i];
|
|
|
|
pr_debug("running test %d '%s'\n", i, e->name);
|
|
ret1 = test_event(e);
|
|
if (ret1)
|
|
ret2 = ret1;
|
|
}
|
|
|
|
return ret2;
|
|
}
|
|
|
|
static int test_term(struct test__term *t)
|
|
{
|
|
struct list_head *terms;
|
|
int ret;
|
|
|
|
terms = malloc(sizeof(*terms));
|
|
if (!terms)
|
|
return -ENOMEM;
|
|
|
|
INIT_LIST_HEAD(terms);
|
|
|
|
ret = parse_events_terms(terms, t->str);
|
|
if (ret) {
|
|
pr_debug("failed to parse terms '%s', err %d\n",
|
|
t->str , ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = t->check(terms);
|
|
parse_events__free_terms(terms);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int test_terms(struct test__term *terms, unsigned cnt)
|
|
{
|
|
int ret = 0;
|
|
unsigned i;
|
|
|
|
for (i = 0; i < cnt; i++) {
|
|
struct test__term *t = &terms[i];
|
|
|
|
pr_debug("running test %d '%s'\n", i, t->str);
|
|
ret = test_term(t);
|
|
if (ret)
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int test_pmu(void)
|
|
{
|
|
struct stat st;
|
|
char path[PATH_MAX];
|
|
int ret;
|
|
|
|
snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/",
|
|
sysfs_find_mountpoint());
|
|
|
|
ret = stat(path, &st);
|
|
if (ret)
|
|
pr_debug("omitting PMU cpu tests\n");
|
|
return !ret;
|
|
}
|
|
|
|
int parse_events__test(void)
|
|
{
|
|
int ret1, ret2 = 0;
|
|
|
|
#define TEST_EVENTS(tests) \
|
|
do { \
|
|
ret1 = test_events(tests, ARRAY_SIZE(tests)); \
|
|
if (!ret2) \
|
|
ret2 = ret1; \
|
|
} while (0)
|
|
|
|
TEST_EVENTS(test__events);
|
|
|
|
if (test_pmu())
|
|
TEST_EVENTS(test__events_pmu);
|
|
|
|
ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms));
|
|
if (!ret2)
|
|
ret2 = ret1;
|
|
|
|
return ret2;
|
|
}
|