Skip to content

Commit a65b9c6

Browse files
Jiri Olsaacmel
authored andcommitted
perf tests: Move test__basic_mmap into separate object
Separating test__basic_mmap test from the builtin-test into mmap-basic object. Signed-off-by: Jiri Olsa <[email protected]> Cc: Corey Ashford <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent bd90517 commit a65b9c6

File tree

4 files changed

+164
-157
lines changed

4 files changed

+164
-157
lines changed

tools/perf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ LIB_OBJS += $(OUTPUT)tests/attr.o
434434
LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o
435435
LIB_OBJS += $(OUTPUT)tests/open-syscall.o
436436
LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
437+
LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
437438
LIB_OBJS += $(OUTPUT)tests/util.o
438439

439440
BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o

tools/perf/tests/builtin-test.c

Lines changed: 0 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -30,163 +30,6 @@
3030
#include <sched.h>
3131

3232

33-
/*
34-
* This test will generate random numbers of calls to some getpid syscalls,
35-
* then establish an mmap for a group of events that are created to monitor
36-
* the syscalls.
37-
*
38-
* It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
39-
* sample.id field to map back to its respective perf_evsel instance.
40-
*
41-
* Then it checks if the number of syscalls reported as perf events by
42-
* the kernel corresponds to the number of syscalls made.
43-
*/
44-
static int test__basic_mmap(void)
45-
{
46-
int err = -1;
47-
union perf_event *event;
48-
struct thread_map *threads;
49-
struct cpu_map *cpus;
50-
struct perf_evlist *evlist;
51-
struct perf_event_attr attr = {
52-
.type = PERF_TYPE_TRACEPOINT,
53-
.read_format = PERF_FORMAT_ID,
54-
.sample_type = PERF_SAMPLE_ID,
55-
.watermark = 0,
56-
};
57-
cpu_set_t cpu_set;
58-
const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
59-
"getpgid", };
60-
pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
61-
(void*)getpgid };
62-
#define nsyscalls ARRAY_SIZE(syscall_names)
63-
int ids[nsyscalls];
64-
unsigned int nr_events[nsyscalls],
65-
expected_nr_events[nsyscalls], i, j;
66-
struct perf_evsel *evsels[nsyscalls], *evsel;
67-
68-
for (i = 0; i < nsyscalls; ++i) {
69-
char name[64];
70-
71-
snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
72-
ids[i] = trace_event__id(name);
73-
if (ids[i] < 0) {
74-
pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
75-
return -1;
76-
}
77-
nr_events[i] = 0;
78-
expected_nr_events[i] = random() % 257;
79-
}
80-
81-
threads = thread_map__new(-1, getpid(), UINT_MAX);
82-
if (threads == NULL) {
83-
pr_debug("thread_map__new\n");
84-
return -1;
85-
}
86-
87-
cpus = cpu_map__new(NULL);
88-
if (cpus == NULL) {
89-
pr_debug("cpu_map__new\n");
90-
goto out_free_threads;
91-
}
92-
93-
CPU_ZERO(&cpu_set);
94-
CPU_SET(cpus->map[0], &cpu_set);
95-
sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
96-
if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
97-
pr_debug("sched_setaffinity() failed on CPU %d: %s ",
98-
cpus->map[0], strerror(errno));
99-
goto out_free_cpus;
100-
}
101-
102-
evlist = perf_evlist__new(cpus, threads);
103-
if (evlist == NULL) {
104-
pr_debug("perf_evlist__new\n");
105-
goto out_free_cpus;
106-
}
107-
108-
/* anonymous union fields, can't be initialized above */
109-
attr.wakeup_events = 1;
110-
attr.sample_period = 1;
111-
112-
for (i = 0; i < nsyscalls; ++i) {
113-
attr.config = ids[i];
114-
evsels[i] = perf_evsel__new(&attr, i);
115-
if (evsels[i] == NULL) {
116-
pr_debug("perf_evsel__new\n");
117-
goto out_free_evlist;
118-
}
119-
120-
perf_evlist__add(evlist, evsels[i]);
121-
122-
if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
123-
pr_debug("failed to open counter: %s, "
124-
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
125-
strerror(errno));
126-
goto out_close_fd;
127-
}
128-
}
129-
130-
if (perf_evlist__mmap(evlist, 128, true) < 0) {
131-
pr_debug("failed to mmap events: %d (%s)\n", errno,
132-
strerror(errno));
133-
goto out_close_fd;
134-
}
135-
136-
for (i = 0; i < nsyscalls; ++i)
137-
for (j = 0; j < expected_nr_events[i]; ++j) {
138-
int foo = syscalls[i]();
139-
++foo;
140-
}
141-
142-
while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
143-
struct perf_sample sample;
144-
145-
if (event->header.type != PERF_RECORD_SAMPLE) {
146-
pr_debug("unexpected %s event\n",
147-
perf_event__name(event->header.type));
148-
goto out_munmap;
149-
}
150-
151-
err = perf_evlist__parse_sample(evlist, event, &sample);
152-
if (err) {
153-
pr_err("Can't parse sample, err = %d\n", err);
154-
goto out_munmap;
155-
}
156-
157-
evsel = perf_evlist__id2evsel(evlist, sample.id);
158-
if (evsel == NULL) {
159-
pr_debug("event with id %" PRIu64
160-
" doesn't map to an evsel\n", sample.id);
161-
goto out_munmap;
162-
}
163-
nr_events[evsel->idx]++;
164-
}
165-
166-
list_for_each_entry(evsel, &evlist->entries, node) {
167-
if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
168-
pr_debug("expected %d %s events, got %d\n",
169-
expected_nr_events[evsel->idx],
170-
perf_evsel__name(evsel), nr_events[evsel->idx]);
171-
goto out_munmap;
172-
}
173-
}
174-
175-
err = 0;
176-
out_munmap:
177-
perf_evlist__munmap(evlist);
178-
out_close_fd:
179-
for (i = 0; i < nsyscalls; ++i)
180-
perf_evsel__close_fd(evsels[i], 1, threads->nr);
181-
out_free_evlist:
182-
perf_evlist__delete(evlist);
183-
out_free_cpus:
184-
cpu_map__delete(cpus);
185-
out_free_threads:
186-
thread_map__delete(threads);
187-
return err;
188-
#undef nsyscalls
189-
}
19033

19134
static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp)
19235
{

tools/perf/tests/mmap-basic.c

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#include "evlist.h"
2+
#include "evsel.h"
3+
#include "thread_map.h"
4+
#include "cpumap.h"
5+
#include "tests.h"
6+
7+
/*
8+
* This test will generate random numbers of calls to some getpid syscalls,
9+
* then establish an mmap for a group of events that are created to monitor
10+
* the syscalls.
11+
*
12+
* It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
13+
* sample.id field to map back to its respective perf_evsel instance.
14+
*
15+
* Then it checks if the number of syscalls reported as perf events by
16+
* the kernel corresponds to the number of syscalls made.
17+
*/
18+
int test__basic_mmap(void)
19+
{
20+
int err = -1;
21+
union perf_event *event;
22+
struct thread_map *threads;
23+
struct cpu_map *cpus;
24+
struct perf_evlist *evlist;
25+
struct perf_event_attr attr = {
26+
.type = PERF_TYPE_TRACEPOINT,
27+
.read_format = PERF_FORMAT_ID,
28+
.sample_type = PERF_SAMPLE_ID,
29+
.watermark = 0,
30+
};
31+
cpu_set_t cpu_set;
32+
const char *syscall_names[] = { "getsid", "getppid", "getpgrp",
33+
"getpgid", };
34+
pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp,
35+
(void*)getpgid };
36+
#define nsyscalls ARRAY_SIZE(syscall_names)
37+
int ids[nsyscalls];
38+
unsigned int nr_events[nsyscalls],
39+
expected_nr_events[nsyscalls], i, j;
40+
struct perf_evsel *evsels[nsyscalls], *evsel;
41+
42+
for (i = 0; i < nsyscalls; ++i) {
43+
char name[64];
44+
45+
snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
46+
ids[i] = trace_event__id(name);
47+
if (ids[i] < 0) {
48+
pr_debug("Is debugfs mounted on /sys/kernel/debug?\n");
49+
return -1;
50+
}
51+
nr_events[i] = 0;
52+
expected_nr_events[i] = random() % 257;
53+
}
54+
55+
threads = thread_map__new(-1, getpid(), UINT_MAX);
56+
if (threads == NULL) {
57+
pr_debug("thread_map__new\n");
58+
return -1;
59+
}
60+
61+
cpus = cpu_map__new(NULL);
62+
if (cpus == NULL) {
63+
pr_debug("cpu_map__new\n");
64+
goto out_free_threads;
65+
}
66+
67+
CPU_ZERO(&cpu_set);
68+
CPU_SET(cpus->map[0], &cpu_set);
69+
sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
70+
if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
71+
pr_debug("sched_setaffinity() failed on CPU %d: %s ",
72+
cpus->map[0], strerror(errno));
73+
goto out_free_cpus;
74+
}
75+
76+
evlist = perf_evlist__new(cpus, threads);
77+
if (evlist == NULL) {
78+
pr_debug("perf_evlist__new\n");
79+
goto out_free_cpus;
80+
}
81+
82+
/* anonymous union fields, can't be initialized above */
83+
attr.wakeup_events = 1;
84+
attr.sample_period = 1;
85+
86+
for (i = 0; i < nsyscalls; ++i) {
87+
attr.config = ids[i];
88+
evsels[i] = perf_evsel__new(&attr, i);
89+
if (evsels[i] == NULL) {
90+
pr_debug("perf_evsel__new\n");
91+
goto out_free_evlist;
92+
}
93+
94+
perf_evlist__add(evlist, evsels[i]);
95+
96+
if (perf_evsel__open(evsels[i], cpus, threads) < 0) {
97+
pr_debug("failed to open counter: %s, "
98+
"tweak /proc/sys/kernel/perf_event_paranoid?\n",
99+
strerror(errno));
100+
goto out_close_fd;
101+
}
102+
}
103+
104+
if (perf_evlist__mmap(evlist, 128, true) < 0) {
105+
pr_debug("failed to mmap events: %d (%s)\n", errno,
106+
strerror(errno));
107+
goto out_close_fd;
108+
}
109+
110+
for (i = 0; i < nsyscalls; ++i)
111+
for (j = 0; j < expected_nr_events[i]; ++j) {
112+
int foo = syscalls[i]();
113+
++foo;
114+
}
115+
116+
while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
117+
struct perf_sample sample;
118+
119+
if (event->header.type != PERF_RECORD_SAMPLE) {
120+
pr_debug("unexpected %s event\n",
121+
perf_event__name(event->header.type));
122+
goto out_munmap;
123+
}
124+
125+
err = perf_evlist__parse_sample(evlist, event, &sample);
126+
if (err) {
127+
pr_err("Can't parse sample, err = %d\n", err);
128+
goto out_munmap;
129+
}
130+
131+
evsel = perf_evlist__id2evsel(evlist, sample.id);
132+
if (evsel == NULL) {
133+
pr_debug("event with id %" PRIu64
134+
" doesn't map to an evsel\n", sample.id);
135+
goto out_munmap;
136+
}
137+
nr_events[evsel->idx]++;
138+
}
139+
140+
list_for_each_entry(evsel, &evlist->entries, node) {
141+
if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) {
142+
pr_debug("expected %d %s events, got %d\n",
143+
expected_nr_events[evsel->idx],
144+
perf_evsel__name(evsel), nr_events[evsel->idx]);
145+
goto out_munmap;
146+
}
147+
}
148+
149+
err = 0;
150+
out_munmap:
151+
perf_evlist__munmap(evlist);
152+
out_close_fd:
153+
for (i = 0; i < nsyscalls; ++i)
154+
perf_evsel__close_fd(evsels[i], 1, threads->nr);
155+
out_free_evlist:
156+
perf_evlist__delete(evlist);
157+
out_free_cpus:
158+
cpu_map__delete(cpus);
159+
out_free_threads:
160+
thread_map__delete(threads);
161+
return err;
162+
}

tools/perf/tests/tests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
int test__vmlinux_matches_kallsyms(void);
66
int test__open_syscall_event(void);
77
int test__open_syscall_event_on_all_cpus(void);
8+
int test__basic_mmap(void);
89

910
/* Util */
1011
int trace_event__id(const char *evname);

0 commit comments

Comments
 (0)