Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc96b361 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf tests: Add a test case for checking sw clock event frequency



This test case checks frequency conversion of hrtimer-based software
clock events (cpu-clock, task-clock) have valid (non-1) periods.

Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1363574507-18808-2-git-send-email-namhyung@kernel.org


[ committer note: Moved .sample_freq to outside named init block to cope with some gcc versions ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d134ffb9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -514,6 +514,7 @@ LIB_OBJS += $(OUTPUT)tests/python-use.o
LIB_OBJS += $(OUTPUT)tests/bp_signal.o
LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
LIB_OBJS += $(OUTPUT)tests/task-exit.o
LIB_OBJS += $(OUTPUT)tests/sw-clock.o

BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
+4 −0
Original line number Diff line number Diff line
@@ -89,6 +89,10 @@ static struct test {
		.desc = "Test number of exit event of a simple workload",
		.func = test__task_exit,
	},
	{
		.desc = "Test software clock events have valid period values",
		.func = test__sw_clock_freq,
	},
	{
		.func = NULL,
	},
+119 −0
Original line number Diff line number Diff line
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/mman.h>

#include "tests.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/cpumap.h"
#include "util/thread_map.h"

#define NR_LOOPS  1000000

/*
 * This test will open software clock events (cpu-clock, task-clock)
 * then check their frequency -> period conversion has no artifact of
 * setting period to 1 forcefully.
 */
static int __test__sw_clock_freq(enum perf_sw_ids clock_id)
{
	int i, err = -1;
	volatile int tmp = 0;
	u64 total_periods = 0;
	int nr_samples = 0;
	union perf_event *event;
	struct perf_evsel *evsel;
	struct perf_evlist *evlist;
	struct perf_event_attr attr = {
		.type = PERF_TYPE_SOFTWARE,
		.config = clock_id,
		.sample_type = PERF_SAMPLE_PERIOD,
		.exclude_kernel = 1,
		.disabled = 1,
		.freq = 1,
	};

	attr.sample_freq = 10000;

	evlist = perf_evlist__new();
	if (evlist == NULL) {
		pr_debug("perf_evlist__new\n");
		return -1;
	}

	evsel = perf_evsel__new(&attr, 0);
	if (evsel == NULL) {
		pr_debug("perf_evsel__new\n");
		goto out_free_evlist;
	}
	perf_evlist__add(evlist, evsel);

	evlist->cpus = cpu_map__dummy_new();
	evlist->threads = thread_map__new_by_tid(getpid());
	if (!evlist->cpus || !evlist->threads) {
		err = -ENOMEM;
		pr_debug("Not enough memory to create thread/cpu maps\n");
		goto out_delete_maps;
	}

	perf_evlist__open(evlist);

	err = perf_evlist__mmap(evlist, 128, true);
	if (err < 0) {
		pr_debug("failed to mmap event: %d (%s)\n", errno,
			 strerror(errno));
		goto out_close_evlist;
	}

	perf_evlist__enable(evlist);

	/* collect samples */
	for (i = 0; i < NR_LOOPS; i++)
		tmp++;

	perf_evlist__disable(evlist);

	while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) {
		struct perf_sample sample;

		if (event->header.type != PERF_RECORD_SAMPLE)
			continue;

		err = perf_evlist__parse_sample(evlist, event, &sample);
		if (err < 0) {
			pr_debug("Error during parse sample\n");
			goto out_unmap_evlist;
		}

		total_periods += sample.period;
		nr_samples++;
	}

	if ((u64) nr_samples == total_periods) {
		pr_debug("All (%d) samples have period value of 1!\n",
			 nr_samples);
		err = -1;
	}

out_unmap_evlist:
	perf_evlist__munmap(evlist);
out_close_evlist:
	perf_evlist__close(evlist);
out_delete_maps:
	perf_evlist__delete_maps(evlist);
out_free_evlist:
	perf_evlist__delete(evlist);
	return err;
}

int test__sw_clock_freq(void)
{
	int ret;

	ret = __test__sw_clock_freq(PERF_COUNT_SW_CPU_CLOCK);
	if (!ret)
		ret = __test__sw_clock_freq(PERF_COUNT_SW_TASK_CLOCK);

	return ret;
}
+1 −0
Original line number Diff line number Diff line
@@ -26,5 +26,6 @@ int test__python_use(void);
int test__bp_signal(void);
int test__bp_signal_overflow(void);
int test__task_exit(void);
int test__sw_clock_freq(void);

#endif /* TESTS_H */