0001
0002 #include <stdarg.h>
0003 #include <stdio.h>
0004 #include <string.h>
0005 #include <linux/perf_event.h>
0006 #include <linux/kernel.h>
0007 #include <perf/cpumap.h>
0008 #include <perf/threadmap.h>
0009 #include <perf/evsel.h>
0010 #include <internal/evsel.h>
0011 #include <internal/tests.h>
0012 #include "tests.h"
0013
0014 static int libperf_print(enum libperf_print_level level,
0015 const char *fmt, va_list ap)
0016 {
0017 return vfprintf(stderr, fmt, ap);
0018 }
0019
0020 static int test_stat_cpu(void)
0021 {
0022 struct perf_cpu_map *cpus;
0023 struct perf_evsel *evsel;
0024 struct perf_event_attr attr = {
0025 .type = PERF_TYPE_SOFTWARE,
0026 .config = PERF_COUNT_SW_CPU_CLOCK,
0027 };
0028 int err, idx;
0029
0030 cpus = perf_cpu_map__new(NULL);
0031 __T("failed to create cpus", cpus);
0032
0033 evsel = perf_evsel__new(&attr);
0034 __T("failed to create evsel", evsel);
0035
0036 err = perf_evsel__open(evsel, cpus, NULL);
0037 __T("failed to open evsel", err == 0);
0038
0039 for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {
0040 struct perf_counts_values counts = { .val = 0 };
0041
0042 perf_evsel__read(evsel, idx, 0, &counts);
0043 __T("failed to read value for evsel", counts.val != 0);
0044 }
0045
0046 perf_evsel__close(evsel);
0047 perf_evsel__delete(evsel);
0048
0049 perf_cpu_map__put(cpus);
0050 return 0;
0051 }
0052
0053 static int test_stat_thread(void)
0054 {
0055 struct perf_counts_values counts = { .val = 0 };
0056 struct perf_thread_map *threads;
0057 struct perf_evsel *evsel;
0058 struct perf_event_attr attr = {
0059 .type = PERF_TYPE_SOFTWARE,
0060 .config = PERF_COUNT_SW_TASK_CLOCK,
0061 };
0062 int err;
0063
0064 threads = perf_thread_map__new_dummy();
0065 __T("failed to create threads", threads);
0066
0067 perf_thread_map__set_pid(threads, 0, 0);
0068
0069 evsel = perf_evsel__new(&attr);
0070 __T("failed to create evsel", evsel);
0071
0072 err = perf_evsel__open(evsel, NULL, threads);
0073 __T("failed to open evsel", err == 0);
0074
0075 perf_evsel__read(evsel, 0, 0, &counts);
0076 __T("failed to read value for evsel", counts.val != 0);
0077
0078 perf_evsel__close(evsel);
0079 perf_evsel__delete(evsel);
0080
0081 perf_thread_map__put(threads);
0082 return 0;
0083 }
0084
0085 static int test_stat_thread_enable(void)
0086 {
0087 struct perf_counts_values counts = { .val = 0 };
0088 struct perf_thread_map *threads;
0089 struct perf_evsel *evsel;
0090 struct perf_event_attr attr = {
0091 .type = PERF_TYPE_SOFTWARE,
0092 .config = PERF_COUNT_SW_TASK_CLOCK,
0093 .disabled = 1,
0094 };
0095 int err;
0096
0097 threads = perf_thread_map__new_dummy();
0098 __T("failed to create threads", threads);
0099
0100 perf_thread_map__set_pid(threads, 0, 0);
0101
0102 evsel = perf_evsel__new(&attr);
0103 __T("failed to create evsel", evsel);
0104
0105 err = perf_evsel__open(evsel, NULL, threads);
0106 __T("failed to open evsel", err == 0);
0107
0108 perf_evsel__read(evsel, 0, 0, &counts);
0109 __T("failed to read value for evsel", counts.val == 0);
0110
0111 err = perf_evsel__enable(evsel);
0112 __T("failed to enable evsel", err == 0);
0113
0114 perf_evsel__read(evsel, 0, 0, &counts);
0115 __T("failed to read value for evsel", counts.val != 0);
0116
0117 err = perf_evsel__disable(evsel);
0118 __T("failed to enable evsel", err == 0);
0119
0120 perf_evsel__close(evsel);
0121 perf_evsel__delete(evsel);
0122
0123 perf_thread_map__put(threads);
0124 return 0;
0125 }
0126
0127 static int test_stat_user_read(int event)
0128 {
0129 struct perf_counts_values counts = { .val = 0 };
0130 struct perf_thread_map *threads;
0131 struct perf_evsel *evsel;
0132 struct perf_event_mmap_page *pc;
0133 struct perf_event_attr attr = {
0134 .type = PERF_TYPE_HARDWARE,
0135 .config = event,
0136 #ifdef __aarch64__
0137 .config1 = 0x2,
0138 #endif
0139 };
0140 int err, i;
0141
0142 threads = perf_thread_map__new_dummy();
0143 __T("failed to create threads", threads);
0144
0145 perf_thread_map__set_pid(threads, 0, 0);
0146
0147 evsel = perf_evsel__new(&attr);
0148 __T("failed to create evsel", evsel);
0149
0150 err = perf_evsel__open(evsel, NULL, threads);
0151 __T("failed to open evsel", err == 0);
0152
0153 err = perf_evsel__mmap(evsel, 0);
0154 __T("failed to mmap evsel", err == 0);
0155
0156 pc = perf_evsel__mmap_base(evsel, 0, 0);
0157 __T("failed to get mmapped address", pc);
0158
0159 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
0160 __T("userspace counter access not supported", pc->cap_user_rdpmc);
0161 __T("userspace counter access not enabled", pc->index);
0162 __T("userspace counter width not set", pc->pmc_width >= 32);
0163 #endif
0164
0165 perf_evsel__read(evsel, 0, 0, &counts);
0166 __T("failed to read value for evsel", counts.val != 0);
0167
0168 for (i = 0; i < 5; i++) {
0169 volatile int count = 0x10000 << i;
0170 __u64 start, end, last = 0;
0171
0172 __T_VERBOSE("\tloop = %u, ", count);
0173
0174 perf_evsel__read(evsel, 0, 0, &counts);
0175 start = counts.val;
0176
0177 while (count--) ;
0178
0179 perf_evsel__read(evsel, 0, 0, &counts);
0180 end = counts.val;
0181
0182 __T("invalid counter data", (end - start) > last);
0183 last = end - start;
0184 __T_VERBOSE("count = %llu\n", end - start);
0185 }
0186
0187 perf_evsel__munmap(evsel);
0188 perf_evsel__close(evsel);
0189 perf_evsel__delete(evsel);
0190
0191 perf_thread_map__put(threads);
0192 return 0;
0193 }
0194
0195 static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)
0196 {
0197 struct perf_evsel *evsel;
0198 struct perf_counts_values counts;
0199 volatile int count = 0x100000;
0200 int err;
0201
0202 evsel = perf_evsel__new(attr);
0203 __T("failed to create evsel", evsel);
0204
0205
0206 err = perf_evsel__open(evsel, NULL, threads);
0207 if (err < 0)
0208 return 0;
0209
0210 while (count--) ;
0211
0212 memset(&counts, -1, sizeof(counts));
0213 perf_evsel__read(evsel, 0, 0, &counts);
0214
0215 __T("failed to read value", counts.val);
0216 if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
0217 __T("failed to read TOTAL_TIME_ENABLED", counts.ena);
0218 if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
0219 __T("failed to read TOTAL_TIME_RUNNING", counts.run);
0220 if (attr->read_format & PERF_FORMAT_ID)
0221 __T("failed to read ID", counts.id);
0222 if (attr->read_format & PERF_FORMAT_LOST)
0223 __T("failed to read LOST", counts.lost == 0);
0224
0225 perf_evsel__close(evsel);
0226 perf_evsel__delete(evsel);
0227 return 0;
0228 }
0229
0230 static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)
0231 {
0232 struct perf_evsel *leader, *member;
0233 struct perf_counts_values counts;
0234 volatile int count = 0x100000;
0235 int err;
0236
0237 attr->read_format |= PERF_FORMAT_GROUP;
0238 leader = perf_evsel__new(attr);
0239 __T("failed to create leader", leader);
0240
0241 attr->read_format &= ~PERF_FORMAT_GROUP;
0242 member = perf_evsel__new(attr);
0243 __T("failed to create member", member);
0244
0245 member->leader = leader;
0246 leader->nr_members = 2;
0247
0248
0249 err = perf_evsel__open(leader, NULL, threads);
0250 if (err < 0)
0251 return 0;
0252 err = perf_evsel__open(member, NULL, threads);
0253 if (err < 0)
0254 return 0;
0255
0256 while (count--) ;
0257
0258 memset(&counts, -1, sizeof(counts));
0259 perf_evsel__read(leader, 0, 0, &counts);
0260
0261 __T("failed to read leader value", counts.val);
0262 if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
0263 __T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);
0264 if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
0265 __T("failed to read leader TOTAL_TIME_RUNNING", counts.run);
0266 if (attr->read_format & PERF_FORMAT_ID)
0267 __T("failed to read leader ID", counts.id);
0268 if (attr->read_format & PERF_FORMAT_LOST)
0269 __T("failed to read leader LOST", counts.lost == 0);
0270
0271 memset(&counts, -1, sizeof(counts));
0272 perf_evsel__read(member, 0, 0, &counts);
0273
0274 __T("failed to read member value", counts.val);
0275 if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
0276 __T("failed to read member TOTAL_TIME_ENABLED", counts.ena);
0277 if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
0278 __T("failed to read member TOTAL_TIME_RUNNING", counts.run);
0279 if (attr->read_format & PERF_FORMAT_ID)
0280 __T("failed to read member ID", counts.id);
0281 if (attr->read_format & PERF_FORMAT_LOST)
0282 __T("failed to read member LOST", counts.lost == 0);
0283
0284 perf_evsel__close(member);
0285 perf_evsel__close(leader);
0286 perf_evsel__delete(member);
0287 perf_evsel__delete(leader);
0288 return 0;
0289 }
0290
0291 static int test_stat_read_format(void)
0292 {
0293 struct perf_thread_map *threads;
0294 struct perf_event_attr attr = {
0295 .type = PERF_TYPE_SOFTWARE,
0296 .config = PERF_COUNT_SW_TASK_CLOCK,
0297 };
0298 int err, i;
0299
0300 #define FMT(_fmt) PERF_FORMAT_ ## _fmt
0301 #define FMT_TIME (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))
0302
0303 uint64_t test_formats [] = {
0304 0,
0305 FMT_TIME,
0306 FMT(ID),
0307 FMT(LOST),
0308 FMT_TIME | FMT(ID),
0309 FMT_TIME | FMT(LOST),
0310 FMT_TIME | FMT(ID) | FMT(LOST),
0311 FMT(ID) | FMT(LOST),
0312 };
0313
0314 #undef FMT
0315 #undef FMT_TIME
0316
0317 threads = perf_thread_map__new_dummy();
0318 __T("failed to create threads", threads);
0319
0320 perf_thread_map__set_pid(threads, 0, 0);
0321
0322 for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
0323 attr.read_format = test_formats[i];
0324 __T_VERBOSE("testing single read with read_format: %lx\n",
0325 (unsigned long)test_formats[i]);
0326
0327 err = test_stat_read_format_single(&attr, threads);
0328 __T("failed to read single format", err == 0);
0329 }
0330
0331 perf_thread_map__put(threads);
0332
0333 threads = perf_thread_map__new_array(2, NULL);
0334 __T("failed to create threads", threads);
0335
0336 perf_thread_map__set_pid(threads, 0, 0);
0337 perf_thread_map__set_pid(threads, 1, 0);
0338
0339 for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {
0340 attr.read_format = test_formats[i];
0341 __T_VERBOSE("testing group read with read_format: %lx\n",
0342 (unsigned long)test_formats[i]);
0343
0344 err = test_stat_read_format_group(&attr, threads);
0345 __T("failed to read group format", err == 0);
0346 }
0347
0348 perf_thread_map__put(threads);
0349 return 0;
0350 }
0351
0352 int test_evsel(int argc, char **argv)
0353 {
0354 __T_START;
0355
0356 libperf_init(libperf_print);
0357
0358 test_stat_cpu();
0359 test_stat_thread();
0360 test_stat_thread_enable();
0361 test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);
0362 test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);
0363 test_stat_read_format();
0364
0365 __T_END;
0366 return tests_failed == 0 ? 0 : -1;
0367 }