2012-11-10 08:46:50 +08:00
|
|
|
#include "parse-events.h"
|
|
|
|
#include "pmu.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "tests.h"
|
|
|
|
|
|
|
|
/* Simulated format definitions. */
|
|
|
|
static struct test_format {
|
|
|
|
const char *name;
|
|
|
|
const char *value;
|
|
|
|
} test_formats[] = {
|
|
|
|
{ "krava01", "config:0-1,62-63\n", },
|
|
|
|
{ "krava02", "config:10-17\n", },
|
|
|
|
{ "krava03", "config:5\n", },
|
|
|
|
{ "krava11", "config1:0,2,4,6,8,20-28\n", },
|
|
|
|
{ "krava12", "config1:63\n", },
|
|
|
|
{ "krava13", "config1:45-47\n", },
|
|
|
|
{ "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
|
|
|
|
{ "krava22", "config2:8,18,48,58\n", },
|
|
|
|
{ "krava23", "config2:28-29,38\n", },
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Simulated users input. */
|
2013-01-19 03:29:49 +08:00
|
|
|
static struct parse_events_term test_terms[] = {
|
2012-11-10 08:46:50 +08:00
|
|
|
{
|
|
|
|
.config = (char *) "krava01",
|
|
|
|
.val.num = 15,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava02",
|
|
|
|
.val.num = 170,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava03",
|
|
|
|
.val.num = 1,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava11",
|
|
|
|
.val.num = 27,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava12",
|
|
|
|
.val.num = 1,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava13",
|
|
|
|
.val.num = 2,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava21",
|
|
|
|
.val.num = 119,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava22",
|
|
|
|
.val.num = 11,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
.config = (char *) "krava23",
|
|
|
|
.val.num = 2,
|
|
|
|
.type_val = PARSE_EVENTS__TERM_TYPE_NUM,
|
|
|
|
.type_term = PARSE_EVENTS__TERM_TYPE_USER,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Prepare format directory data, exported by kernel
|
|
|
|
* at /sys/bus/event_source/devices/<dev>/format.
|
|
|
|
*/
|
|
|
|
static char *test_format_dir_get(void)
|
|
|
|
{
|
|
|
|
static char dir[PATH_MAX];
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX");
|
|
|
|
if (!mkdtemp(dir))
|
|
|
|
return NULL;
|
|
|
|
|
2013-01-19 04:03:43 +08:00
|
|
|
for (i = 0; i < ARRAY_SIZE(test_formats); i++) {
|
2012-11-10 08:46:50 +08:00
|
|
|
static char name[PATH_MAX];
|
|
|
|
struct test_format *format = &test_formats[i];
|
|
|
|
FILE *file;
|
|
|
|
|
|
|
|
snprintf(name, PATH_MAX, "%s/%s", dir, format->name);
|
|
|
|
|
|
|
|
file = fopen(name, "w");
|
|
|
|
if (!file)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (1 != fwrite(format->value, strlen(format->value), 1, file))
|
|
|
|
break;
|
|
|
|
|
|
|
|
fclose(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup format directory. */
|
|
|
|
static int test_format_dir_put(char *dir)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir);
|
|
|
|
if (system(buf))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
snprintf(buf, PATH_MAX, "rmdir %s\n", dir);
|
|
|
|
return system(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct list_head *test_terms_list(void)
|
|
|
|
{
|
|
|
|
static LIST_HEAD(terms);
|
|
|
|
unsigned int i;
|
|
|
|
|
2013-01-19 04:03:43 +08:00
|
|
|
for (i = 0; i < ARRAY_SIZE(test_terms); i++)
|
2012-11-10 08:46:50 +08:00
|
|
|
list_add_tail(&test_terms[i].list, &terms);
|
|
|
|
|
|
|
|
return &terms;
|
|
|
|
}
|
|
|
|
|
perf tests: Pass the subtest index to each test routine
Some tests have sub-tests we want to run, so allow passing this.
Wang tried to avoid having to touch all tests, but then, having the
test.func in an anonymous union makes the build fail on older compilers,
like the one in RHEL6, where:
test a = {
.func = foo,
};
fails.
To fix it leave the func pointer in the main structure and pass the subtest
index to all tests, end result function is the same, but we have just one
function pointer, not two, with and without the subtest index as an argument.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-5genj0ficwdmelpoqlds0u4y@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-11-19 23:01:48 +08:00
|
|
|
int test__pmu(int subtest __maybe_unused)
|
2012-11-10 08:46:50 +08:00
|
|
|
{
|
|
|
|
char *format = test_format_dir_get();
|
|
|
|
LIST_HEAD(formats);
|
|
|
|
struct list_head *terms = test_terms_list();
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!format)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
do {
|
|
|
|
struct perf_event_attr attr;
|
|
|
|
|
|
|
|
memset(&attr, 0, sizeof(attr));
|
|
|
|
|
|
|
|
ret = perf_pmu__format_parse(format, &formats);
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
|
perf tools: Add term support for parse_events_error
Allowing event's term processing to report back error, like:
$ perf record -e 'cpu/even=0x1/' ls
event syntax error: 'cpu/even=0x1/'
\___ unknown term
valid terms: pc,any,inv,edge,cmask,event,in_tx,ldlat,umask,in_tx_cp,offcore_rsp,config,config1,config2,name,period,branch_type
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1429729824-13932-7-git-send-email-jolsa@kernel.org
[ Renamed 'error' variables to 'err', not to clash with util.h error() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-04-23 03:10:21 +08:00
|
|
|
ret = perf_pmu__config_terms(&formats, &attr, terms,
|
|
|
|
false, NULL);
|
2012-11-10 08:46:50 +08:00
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
|
|
|
if (attr.config != 0xc00000000002a823)
|
|
|
|
break;
|
|
|
|
if (attr.config1 != 0x8000400000000145)
|
|
|
|
break;
|
|
|
|
if (attr.config2 != 0x0400000020041d07)
|
|
|
|
break;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
test_format_dir_put(format);
|
|
|
|
return ret;
|
|
|
|
}
|