]>
git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - tools/perf/tests/mmap-basic.c
4d42e455feb70f81777a9ca2f4f58312fb6931b6
1 // SPDX-License-Identifier: GPL-2.0
4 /* For the CLR_() macros */
7 #include <perf/cpumap.h>
12 #include "thread_map.h"
14 #include <linux/err.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <perf/evlist.h>
20 * This test will generate random numbers of calls to some getpid syscalls,
21 * then establish an mmap for a group of events that are created to monitor
24 * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated
25 * sample.id field to map back to its respective perf_evsel instance.
27 * Then it checks if the number of syscalls reported as perf events by
28 * the kernel corresponds to the number of syscalls made.
30 int test__basic_mmap(struct test
*test __maybe_unused
, int subtest __maybe_unused
)
33 union perf_event
*event
;
34 struct perf_thread_map
*threads
;
35 struct perf_cpu_map
*cpus
;
36 struct evlist
*evlist
;
38 const char *syscall_names
[] = { "getsid", "getppid", "getpgid", };
39 pid_t (*syscalls
[])(void) = { (void *)getsid
, getppid
, (void*)getpgid
};
40 #define nsyscalls ARRAY_SIZE(syscall_names)
41 unsigned int nr_events
[nsyscalls
],
42 expected_nr_events
[nsyscalls
], i
, j
;
43 struct evsel
*evsels
[nsyscalls
], *evsel
;
44 char sbuf
[STRERR_BUFSIZE
];
47 threads
= thread_map__new(-1, getpid(), UINT_MAX
);
48 if (threads
== NULL
) {
49 pr_debug("thread_map__new\n");
53 cpus
= perf_cpu_map__new(NULL
);
55 pr_debug("perf_cpu_map__new\n");
56 goto out_free_threads
;
60 CPU_SET(cpus
->map
[0], &cpu_set
);
61 sched_setaffinity(0, sizeof(cpu_set
), &cpu_set
);
62 if (sched_setaffinity(0, sizeof(cpu_set
), &cpu_set
) < 0) {
63 pr_debug("sched_setaffinity() failed on CPU %d: %s ",
64 cpus
->map
[0], str_error_r(errno
, sbuf
, sizeof(sbuf
)));
68 evlist
= evlist__new();
70 pr_debug("perf_evlist__new\n");
74 perf_evlist__set_maps(&evlist
->core
, cpus
, threads
);
76 for (i
= 0; i
< nsyscalls
; ++i
) {
79 snprintf(name
, sizeof(name
), "sys_enter_%s", syscall_names
[i
]);
80 evsels
[i
] = perf_evsel__newtp("syscalls", name
);
81 if (IS_ERR(evsels
[i
])) {
82 pr_debug("perf_evsel__new(%s)\n", name
);
83 goto out_delete_evlist
;
86 evsels
[i
]->core
.attr
.wakeup_events
= 1;
87 perf_evsel__set_sample_id(evsels
[i
], false);
89 evlist__add(evlist
, evsels
[i
]);
91 if (evsel__open(evsels
[i
], cpus
, threads
) < 0) {
92 pr_debug("failed to open counter: %s, "
93 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
94 str_error_r(errno
, sbuf
, sizeof(sbuf
)));
95 goto out_delete_evlist
;
99 expected_nr_events
[i
] = 1 + rand() % 127;
102 if (evlist__mmap(evlist
, 128) < 0) {
103 pr_debug("failed to mmap events: %d (%s)\n", errno
,
104 str_error_r(errno
, sbuf
, sizeof(sbuf
)));
105 goto out_delete_evlist
;
108 for (i
= 0; i
< nsyscalls
; ++i
)
109 for (j
= 0; j
< expected_nr_events
[i
]; ++j
) {
110 int foo
= syscalls
[i
]();
114 md
= &evlist
->mmap
[0];
115 if (perf_mmap__read_init(md
) < 0)
118 while ((event
= perf_mmap__read_event(md
)) != NULL
) {
119 struct perf_sample sample
;
121 if (event
->header
.type
!= PERF_RECORD_SAMPLE
) {
122 pr_debug("unexpected %s event\n",
123 perf_event__name(event
->header
.type
));
124 goto out_delete_evlist
;
127 err
= perf_evlist__parse_sample(evlist
, event
, &sample
);
129 pr_err("Can't parse sample, err = %d\n", err
);
130 goto out_delete_evlist
;
134 evsel
= perf_evlist__id2evsel(evlist
, sample
.id
);
136 pr_debug("event with id %" PRIu64
137 " doesn't map to an evsel\n", sample
.id
);
138 goto out_delete_evlist
;
140 nr_events
[evsel
->idx
]++;
141 perf_mmap__consume(md
);
143 perf_mmap__read_done(md
);
147 evlist__for_each_entry(evlist
, evsel
) {
148 if (nr_events
[evsel
->idx
] != expected_nr_events
[evsel
->idx
]) {
149 pr_debug("expected %d %s events, got %d\n",
150 expected_nr_events
[evsel
->idx
],
151 perf_evsel__name(evsel
), nr_events
[evsel
->idx
]);
153 goto out_delete_evlist
;
158 evlist__delete(evlist
);
162 perf_cpu_map__put(cpus
);
164 perf_thread_map__put(threads
);