brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · 2907167 Raw
149 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <errno.h>3#include <inttypes.h>4#include <unistd.h>5#include <stdlib.h>6#include <signal.h>7#include <sys/mman.h>8#include <linux/string.h>9 10#include "tests.h"11#include "util/debug.h"12#include "util/evsel.h"13#include "util/evlist.h"14#include "util/cpumap.h"15#include "util/mmap.h"16#include "util/sample.h"17#include "util/thread_map.h"18#include <perf/evlist.h>19#include <perf/mmap.h>20 21#define NR_LOOPS  1000000022 23/*24 * This test will open software clock events (cpu-clock, task-clock)25 * then check their frequency -> period conversion has no artifact of26 * setting period to 1 forcefully.27 */28static int __test__sw_clock_freq(enum perf_sw_ids clock_id)29{30	int i, err = -1;31	volatile int tmp = 0;32	u64 total_periods = 0;33	int nr_samples = 0;34	char sbuf[STRERR_BUFSIZE];35	union perf_event *event;36	struct evsel *evsel;37	struct evlist *evlist;38	struct perf_event_attr attr = {39		.type = PERF_TYPE_SOFTWARE,40		.config = clock_id,41		.sample_type = PERF_SAMPLE_PERIOD,42		.exclude_kernel = 1,43		.disabled = 1,44		.freq = 1,45	};46	struct perf_cpu_map *cpus = NULL;47	struct perf_thread_map *threads = NULL;48	struct mmap *md;49 50	attr.sample_freq = 500;51 52	evlist = evlist__new();53	if (evlist == NULL) {54		pr_debug("evlist__new\n");55		return -1;56	}57 58	evsel = evsel__new(&attr);59	if (evsel == NULL) {60		pr_debug("evsel__new\n");61		goto out_delete_evlist;62	}63	evlist__add(evlist, evsel);64 65	cpus = perf_cpu_map__new_any_cpu();66	threads = thread_map__new_by_tid(getpid());67	if (!cpus || !threads) {68		err = -ENOMEM;69		pr_debug("Not enough memory to create thread/cpu maps\n");70		goto out_delete_evlist;71	}72 73	perf_evlist__set_maps(&evlist->core, cpus, threads);74 75	if (evlist__open(evlist)) {76		const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";77 78		err = -errno;79		pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",80			 str_error_r(errno, sbuf, sizeof(sbuf)),81			 knob, (u64)attr.sample_freq);82		goto out_delete_evlist;83	}84 85	err = evlist__mmap(evlist, 128);86	if (err < 0) {87		pr_debug("failed to mmap event: %d (%s)\n", errno,88			 str_error_r(errno, sbuf, sizeof(sbuf)));89		goto out_delete_evlist;90	}91 92	evlist__enable(evlist);93 94	/* collect samples */95	for (i = 0; i < NR_LOOPS; i++)96		tmp++;97 98	evlist__disable(evlist);99 100	md = &evlist->mmap[0];101	if (perf_mmap__read_init(&md->core) < 0)102		goto out_init;103 104	while ((event = perf_mmap__read_event(&md->core)) != NULL) {105		struct perf_sample sample;106 107		if (event->header.type != PERF_RECORD_SAMPLE)108			goto next_event;109 110		err = evlist__parse_sample(evlist, event, &sample);111		if (err < 0) {112			pr_debug("Error during parse sample\n");113			goto out_delete_evlist;114		}115 116		total_periods += sample.period;117		nr_samples++;118next_event:119		perf_mmap__consume(&md->core);120	}121	perf_mmap__read_done(&md->core);122 123out_init:124	if ((u64) nr_samples == total_periods) {125		pr_debug("All (%d) samples have period value of 1!\n",126			 nr_samples);127		err = -1;128	}129 130out_delete_evlist:131	perf_cpu_map__put(cpus);132	perf_thread_map__put(threads);133	evlist__delete(evlist);134	return err;135}136 137static int test__sw_clock_freq(struct test_suite *test __maybe_unused, int subtest __maybe_unused)138{139	int ret;140 141	ret = __test__sw_clock_freq(PERF_COUNT_SW_CPU_CLOCK);142	if (!ret)143		ret = __test__sw_clock_freq(PERF_COUNT_SW_TASK_CLOCK);144 145	return ret;146}147 148DEFINE_SUITE("Software clock events period values", sw_clock_freq);149