brintos

brintos / linux-shallow public Read only

0
0
Text · 9.3 KiB · 545ec31 Raw
368 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <stdarg.h>3#include <stdio.h>4#include <string.h>5#include <linux/perf_event.h>6#include <linux/kernel.h>7#include <perf/cpumap.h>8#include <perf/threadmap.h>9#include <perf/evsel.h>10#include <internal/evsel.h>11#include <internal/tests.h>12#include "tests.h"13 14static int libperf_print(enum libperf_print_level level,15			 const char *fmt, va_list ap)16{17	return vfprintf(stderr, fmt, ap);18}19 20static int test_stat_cpu(void)21{22	struct perf_cpu_map *cpus;23	struct perf_evsel *evsel;24	struct perf_event_attr attr = {25		.type	= PERF_TYPE_SOFTWARE,26		.config	= PERF_COUNT_SW_CPU_CLOCK,27	};28	int err, idx;29 30	cpus = perf_cpu_map__new_online_cpus();31	__T("failed to create cpus", cpus);32 33	evsel = perf_evsel__new(&attr);34	__T("failed to create evsel", evsel);35 36	err = perf_evsel__open(evsel, cpus, NULL);37	__T("failed to open evsel", err == 0);38 39	for (idx = 0; idx < perf_cpu_map__nr(cpus); idx++) {40		struct perf_counts_values counts = { .val = 0 };41 42		perf_evsel__read(evsel, idx, 0, &counts);43		__T("failed to read value for evsel", counts.val != 0);44	}45 46	perf_evsel__close(evsel);47	perf_evsel__delete(evsel);48 49	perf_cpu_map__put(cpus);50	return 0;51}52 53static int test_stat_thread(void)54{55	struct perf_counts_values counts = { .val = 0 };56	struct perf_thread_map *threads;57	struct perf_evsel *evsel;58	struct perf_event_attr attr = {59		.type	= PERF_TYPE_SOFTWARE,60		.config	= PERF_COUNT_SW_TASK_CLOCK,61	};62	int err;63 64	threads = perf_thread_map__new_dummy();65	__T("failed to create threads", threads);66 67	perf_thread_map__set_pid(threads, 0, 0);68 69	evsel = perf_evsel__new(&attr);70	__T("failed to create evsel", evsel);71 72	err = perf_evsel__open(evsel, NULL, threads);73	__T("failed to open evsel", err == 0);74 75	perf_evsel__read(evsel, 0, 0, &counts);76	__T("failed to read value for evsel", counts.val != 0);77 78	perf_evsel__close(evsel);79	perf_evsel__delete(evsel);80 81	perf_thread_map__put(threads);82	return 0;83}84 85static int test_stat_thread_enable(void)86{87	struct perf_counts_values counts = { .val = 0 };88	struct perf_thread_map *threads;89	struct perf_evsel *evsel;90	struct perf_event_attr attr = {91		.type	  = PERF_TYPE_SOFTWARE,92		.config	  = PERF_COUNT_SW_TASK_CLOCK,93		.disabled = 1,94	};95	int err;96 97	threads = perf_thread_map__new_dummy();98	__T("failed to create threads", threads);99 100	perf_thread_map__set_pid(threads, 0, 0);101 102	evsel = perf_evsel__new(&attr);103	__T("failed to create evsel", evsel);104 105	err = perf_evsel__open(evsel, NULL, threads);106	__T("failed to open evsel", err == 0);107 108	perf_evsel__read(evsel, 0, 0, &counts);109	__T("failed to read value for evsel", counts.val == 0);110 111	err = perf_evsel__enable(evsel);112	__T("failed to enable evsel", err == 0);113 114	perf_evsel__read(evsel, 0, 0, &counts);115	__T("failed to read value for evsel", counts.val != 0);116 117	err = perf_evsel__disable(evsel);118	__T("failed to enable evsel", err == 0);119 120	perf_evsel__close(evsel);121	perf_evsel__delete(evsel);122 123	perf_thread_map__put(threads);124	return 0;125}126 127static int test_stat_user_read(int event)128{129	struct perf_counts_values counts = { .val = 0 };130	struct perf_thread_map *threads;131	struct perf_evsel *evsel;132	struct perf_event_mmap_page *pc;133	struct perf_event_attr attr = {134		.type	= PERF_TYPE_HARDWARE,135		.config	= event,136#ifdef __aarch64__137		.config1 = 0x2,		/* Request user access */138#endif139	};140	int err, i;141 142	threads = perf_thread_map__new_dummy();143	__T("failed to create threads", threads);144 145	perf_thread_map__set_pid(threads, 0, 0);146 147	evsel = perf_evsel__new(&attr);148	__T("failed to create evsel", evsel);149 150	err = perf_evsel__open(evsel, NULL, threads);151	__T("failed to open evsel", err == 0);152 153	err = perf_evsel__mmap(evsel, 0);154	__T("failed to mmap evsel", err == 0);155 156	pc = perf_evsel__mmap_base(evsel, 0, 0);157	__T("failed to get mmapped address", pc);158 159#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)160	__T("userspace counter access not supported", pc->cap_user_rdpmc);161	__T("userspace counter access not enabled", pc->index);162	__T("userspace counter width not set", pc->pmc_width >= 32);163#endif164 165	perf_evsel__read(evsel, 0, 0, &counts);166	__T("failed to read value for evsel", counts.val != 0);167 168	for (i = 0; i < 5; i++) {169		volatile int count = 0x10000 << i;170		__u64 start, end, last = 0;171 172		__T_VERBOSE("\tloop = %u, ", count);173 174		perf_evsel__read(evsel, 0, 0, &counts);175		start = counts.val;176 177		while (count--) ;178 179		perf_evsel__read(evsel, 0, 0, &counts);180		end = counts.val;181 182		__T("invalid counter data", (end - start) > last);183		last = end - start;184		__T_VERBOSE("count = %llu\n", end - start);185	}186 187	perf_evsel__munmap(evsel);188	perf_evsel__close(evsel);189	perf_evsel__delete(evsel);190 191	perf_thread_map__put(threads);192	return 0;193}194 195static int test_stat_read_format_single(struct perf_event_attr *attr, struct perf_thread_map *threads)196{197	struct perf_evsel *evsel;198	struct perf_counts_values counts;199	volatile int count = 0x100000;200	int err;201 202	evsel = perf_evsel__new(attr);203	__T("failed to create evsel", evsel);204 205	/* skip old kernels that don't support the format */206	err = perf_evsel__open(evsel, NULL, threads);207	if (err < 0)208		return 0;209 210	while (count--) ;211 212	memset(&counts, -1, sizeof(counts));213	perf_evsel__read(evsel, 0, 0, &counts);214 215	__T("failed to read value", counts.val);216	if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)217		__T("failed to read TOTAL_TIME_ENABLED", counts.ena);218	if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)219		__T("failed to read TOTAL_TIME_RUNNING", counts.run);220	if (attr->read_format & PERF_FORMAT_ID)221		__T("failed to read ID", counts.id);222	if (attr->read_format & PERF_FORMAT_LOST)223		__T("failed to read LOST", counts.lost == 0);224 225	perf_evsel__close(evsel);226	perf_evsel__delete(evsel);227	return 0;228}229 230static int test_stat_read_format_group(struct perf_event_attr *attr, struct perf_thread_map *threads)231{232	struct perf_evsel *leader, *member;233	struct perf_counts_values counts;234	volatile int count = 0x100000;235	int err;236 237	attr->read_format |= PERF_FORMAT_GROUP;238	leader = perf_evsel__new(attr);239	__T("failed to create leader", leader);240 241	attr->read_format &= ~PERF_FORMAT_GROUP;242	member = perf_evsel__new(attr);243	__T("failed to create member", member);244 245	member->leader = leader;246	leader->nr_members = 2;247 248	/* skip old kernels that don't support the format */249	err = perf_evsel__open(leader, NULL, threads);250	if (err < 0)251		return 0;252	err = perf_evsel__open(member, NULL, threads);253	if (err < 0)254		return 0;255 256	while (count--) ;257 258	memset(&counts, -1, sizeof(counts));259	perf_evsel__read(leader, 0, 0, &counts);260 261	__T("failed to read leader value", counts.val);262	if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)263		__T("failed to read leader TOTAL_TIME_ENABLED", counts.ena);264	if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)265		__T("failed to read leader TOTAL_TIME_RUNNING", counts.run);266	if (attr->read_format & PERF_FORMAT_ID)267		__T("failed to read leader ID", counts.id);268	if (attr->read_format & PERF_FORMAT_LOST)269		__T("failed to read leader LOST", counts.lost == 0);270 271	memset(&counts, -1, sizeof(counts));272	perf_evsel__read(member, 0, 0, &counts);273 274	__T("failed to read member value", counts.val);275	if (attr->read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)276		__T("failed to read member TOTAL_TIME_ENABLED", counts.ena);277	if (attr->read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)278		__T("failed to read member TOTAL_TIME_RUNNING", counts.run);279	if (attr->read_format & PERF_FORMAT_ID)280		__T("failed to read member ID", counts.id);281	if (attr->read_format & PERF_FORMAT_LOST)282		__T("failed to read member LOST", counts.lost == 0);283 284	perf_evsel__close(member);285	perf_evsel__close(leader);286	perf_evsel__delete(member);287	perf_evsel__delete(leader);288	return 0;289}290 291static int test_stat_read_format(void)292{293	struct perf_thread_map *threads;294	struct perf_event_attr attr = {295		.type	= PERF_TYPE_SOFTWARE,296		.config	= PERF_COUNT_SW_TASK_CLOCK,297	};298	int err, i;299 300#define FMT(_fmt)  PERF_FORMAT_ ## _fmt301#define FMT_TIME  (FMT(TOTAL_TIME_ENABLED) | FMT(TOTAL_TIME_RUNNING))302 303	uint64_t test_formats [] = {304		0,305		FMT_TIME,306		FMT(ID),307		FMT(LOST),308		FMT_TIME | FMT(ID),309		FMT_TIME | FMT(LOST),310		FMT_TIME | FMT(ID) | FMT(LOST),311		FMT(ID) | FMT(LOST),312	};313 314#undef FMT315#undef FMT_TIME316 317	threads = perf_thread_map__new_dummy();318	__T("failed to create threads", threads);319 320	perf_thread_map__set_pid(threads, 0, 0);321 322	for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {323		attr.read_format = test_formats[i];324		__T_VERBOSE("testing single read with read_format: %lx\n",325			    (unsigned long)test_formats[i]);326 327		err = test_stat_read_format_single(&attr, threads);328		__T("failed to read single format", err == 0);329	}330 331	perf_thread_map__put(threads);332 333	threads = perf_thread_map__new_array(2, NULL);334	__T("failed to create threads", threads);335 336	perf_thread_map__set_pid(threads, 0, 0);337	perf_thread_map__set_pid(threads, 1, 0);338 339	for (i = 0; i < (int)ARRAY_SIZE(test_formats); i++) {340		attr.read_format = test_formats[i];341		__T_VERBOSE("testing group read with read_format: %lx\n",342			    (unsigned long)test_formats[i]);343 344		err = test_stat_read_format_group(&attr, threads);345		__T("failed to read group format", err == 0);346	}347 348	perf_thread_map__put(threads);349	return 0;350}351 352int test_evsel(int argc, char **argv)353{354	__T_START;355 356	libperf_init(libperf_print);357 358	test_stat_cpu();359	test_stat_thread();360	test_stat_thread_enable();361	test_stat_user_read(PERF_COUNT_HW_INSTRUCTIONS);362	test_stat_user_read(PERF_COUNT_HW_CPU_CYCLES);363	test_stat_read_format();364 365	__T_END;366	return tests_failed == 0 ? 0 : -1;367}368