diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-09-26 12:23:10 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-09-26 12:42:01 -0400 |
commit | eb2f270338461a4de659a21946739748160c0816 (patch) | |
tree | 77e330fba386ef9b977afdac6c79fe14fcb19a80 | |
parent | e6b6f6795265ec19ff35572f527bb74c07ff9399 (diff) |
perf test: Add test to check we correctly parse and match syscall open parms
It will set up a syscall open tracepoint event, generate an open with
invalid flags, then check those flags were the ones reported in the
tracepoint fired.
For the filename we need vfs:getname, but that will go thru some more
iterations as the vfs getname codebase is going thru changes lately.
When that is in I'll just check that the perf_evsel__newtp constructor
is not bailing out and then add it to the evlist, catch the event and
check the filename against the one used in the 'open' call used to
trigger the event.
Cc: David Ahern <dsahern@gmail.com>
Cc: Eric Paris <eparis@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jeff Layton <jlayton@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
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-p5w9aq0jcbb91ghzqomowm16@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-test.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 2fd2c031f627..484f26cc0c00 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -1289,6 +1289,118 @@ static int perf_evsel__tp_sched_test(void) | |||
1289 | return ret; | 1289 | return ret; |
1290 | } | 1290 | } |
1291 | 1291 | ||
1292 | static int test__syscall_open_tp_fields(void) | ||
1293 | { | ||
1294 | struct perf_record_opts opts = { | ||
1295 | .target = { | ||
1296 | .uid = UINT_MAX, | ||
1297 | .uses_mmap = true, | ||
1298 | }, | ||
1299 | .no_delay = true, | ||
1300 | .freq = 1, | ||
1301 | .mmap_pages = 256, | ||
1302 | .raw_samples = true, | ||
1303 | }; | ||
1304 | const char *filename = "/etc/passwd"; | ||
1305 | int flags = O_RDONLY | O_DIRECTORY; | ||
1306 | struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); | ||
1307 | struct perf_evsel *evsel; | ||
1308 | int err = -1, i, nr_events = 0, nr_polls = 0; | ||
1309 | |||
1310 | if (evlist == NULL) { | ||
1311 | pr_debug("%s: perf_evlist__new\n", __func__); | ||
1312 | goto out; | ||
1313 | } | ||
1314 | |||
1315 | evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0); | ||
1316 | if (evsel == NULL) { | ||
1317 | pr_debug("%s: perf_evsel__newtp\n", __func__); | ||
1318 | goto out_delete_evlist; | ||
1319 | } | ||
1320 | |||
1321 | perf_evlist__add(evlist, evsel); | ||
1322 | |||
1323 | err = perf_evlist__create_maps(evlist, &opts.target); | ||
1324 | if (err < 0) { | ||
1325 | pr_debug("%s: perf_evlist__create_maps\n", __func__); | ||
1326 | goto out_delete_evlist; | ||
1327 | } | ||
1328 | |||
1329 | perf_evsel__config(evsel, &opts, evsel); | ||
1330 | |||
1331 | evlist->threads->map[0] = getpid(); | ||
1332 | |||
1333 | err = perf_evlist__open(evlist); | ||
1334 | if (err < 0) { | ||
1335 | pr_debug("perf_evlist__open: %s\n", strerror(errno)); | ||
1336 | goto out_delete_evlist; | ||
1337 | } | ||
1338 | |||
1339 | err = perf_evlist__mmap(evlist, UINT_MAX, false); | ||
1340 | if (err < 0) { | ||
1341 | pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); | ||
1342 | goto out_delete_evlist; | ||
1343 | } | ||
1344 | |||
1345 | perf_evlist__enable(evlist); | ||
1346 | |||
1347 | /* | ||
1348 | * Generate the event: | ||
1349 | */ | ||
1350 | open(filename, flags); | ||
1351 | |||
1352 | while (1) { | ||
1353 | int before = nr_events; | ||
1354 | |||
1355 | for (i = 0; i < evlist->nr_mmaps; i++) { | ||
1356 | union perf_event *event; | ||
1357 | |||
1358 | while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { | ||
1359 | const u32 type = event->header.type; | ||
1360 | int tp_flags; | ||
1361 | struct perf_sample sample; | ||
1362 | |||
1363 | ++nr_events; | ||
1364 | |||
1365 | if (type != PERF_RECORD_SAMPLE) | ||
1366 | continue; | ||
1367 | |||
1368 | err = perf_evsel__parse_sample(evsel, event, &sample); | ||
1369 | if (err) { | ||
1370 | pr_err("Can't parse sample, err = %d\n", err); | ||
1371 | goto out_munmap; | ||
1372 | } | ||
1373 | |||
1374 | tp_flags = perf_evsel__intval(evsel, &sample, "flags"); | ||
1375 | |||
1376 | if (flags != tp_flags) { | ||
1377 | pr_debug("%s: Expected flags=%#x, got %#x\n", | ||
1378 | __func__, flags, tp_flags); | ||
1379 | goto out_munmap; | ||
1380 | } | ||
1381 | |||
1382 | goto out_ok; | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1386 | if (nr_events == before) | ||
1387 | poll(evlist->pollfd, evlist->nr_fds, 10); | ||
1388 | |||
1389 | if (++nr_polls > 5) { | ||
1390 | pr_debug("%s: no events!\n", __func__); | ||
1391 | goto out_munmap; | ||
1392 | } | ||
1393 | } | ||
1394 | out_ok: | ||
1395 | err = 0; | ||
1396 | out_munmap: | ||
1397 | perf_evlist__munmap(evlist); | ||
1398 | out_delete_evlist: | ||
1399 | perf_evlist__delete(evlist); | ||
1400 | out: | ||
1401 | return err; | ||
1402 | } | ||
1403 | |||
1292 | static struct test { | 1404 | static struct test { |
1293 | const char *desc; | 1405 | const char *desc; |
1294 | int (*func)(void); | 1406 | int (*func)(void); |
@@ -1340,6 +1452,10 @@ static struct test { | |||
1340 | .func = perf_evsel__tp_sched_test, | 1452 | .func = perf_evsel__tp_sched_test, |
1341 | }, | 1453 | }, |
1342 | { | 1454 | { |
1455 | .desc = "Generate and check syscalls:sys_enter_open event fields", | ||
1456 | .func = test__syscall_open_tp_fields, | ||
1457 | }, | ||
1458 | { | ||
1343 | .func = NULL, | 1459 | .func = NULL, |
1344 | }, | 1460 | }, |
1345 | }; | 1461 | }; |