forked from luck/tmp_suning_uos_patched
67c1e4a53b
We were using it at 10 kHz, which doesn't work in machines where somehow the max freq was auto reduced by the kernel: [root@ssdandy ~]# perf test 19 19: Test software clock events have valid period values : FAILED! [root@ssdandy ~]# perf test -v 19 19: Test software clock events have valid period values : --- start --- Couldn't open evlist: Invalid argument ---- end ---- Test software clock events have valid period values: FAILED! [root@ssdandy ~]# [root@ssdandy ~]# cat /proc/sys/kernel/perf_event_max_sample_rate 7000 Reducing it to 500 Hz should be good enough for this test and also shouldn't affect what it is testing. But warn the user if it fails, informing the knob and the freq tried. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-548rhj1uo6xbwnxa95kw3hqe@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
129 lines
2.8 KiB
C
129 lines
2.8 KiB
C
#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 = 500;
|
|
|
|
evlist = perf_evlist__new();
|
|
if (evlist == NULL) {
|
|
pr_debug("perf_evlist__new\n");
|
|
return -1;
|
|
}
|
|
|
|
evsel = perf_evsel__new(&attr);
|
|
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;
|
|
}
|
|
|
|
if (perf_evlist__open(evlist)) {
|
|
const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate";
|
|
|
|
err = -errno;
|
|
pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n",
|
|
strerror(errno), knob, (u64)attr.sample_freq);
|
|
goto out_delete_maps;
|
|
}
|
|
|
|
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)
|
|
goto next_event;
|
|
|
|
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++;
|
|
next_event:
|
|
perf_evlist__mmap_consume(evlist, 0);
|
|
}
|
|
|
|
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;
|
|
}
|