diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-06-29 03:22:54 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-06-29 12:28:13 -0400 |
commit | 7582732f57e547929d4c65ad8e38f3446e0538d8 (patch) | |
tree | 1445f53d5e467f8e20da4cb100bc646cd3748336 | |
parent | 50d8f9e393c5a1a8864fda75e3a9f2b800497a61 (diff) |
perf tools: Fix hw breakpoint's type modifier parsing
Fixing the hw breakpoint's type modifier parsing to allow all possible
combinations of 'rwx' characters.
Adding automated tests to the parsing test suite.
Reported-by: Jovi Zhang <bookjovi@gmail.com>
Original-patch-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Jovi Zhang <bookjovi@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/20120629072254.GA940@krava.brq.redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/parse-events-test.c | 37 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 16 | ||||
-rw-r--r-- | tools/perf/util/parse-events.l | 2 |
3 files changed, 51 insertions, 4 deletions
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index a0f61a2a6835..de81fe1f9329 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c | |||
@@ -181,6 +181,22 @@ static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) | |||
181 | return 0; | 181 | return 0; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) | ||
185 | { | ||
186 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
187 | struct perf_evsel, node); | ||
188 | |||
189 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | ||
190 | TEST_ASSERT_VAL("wrong type", | ||
191 | PERF_TYPE_BREAKPOINT == evsel->attr.type); | ||
192 | TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); | ||
193 | TEST_ASSERT_VAL("wrong bp_type", | ||
194 | (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); | ||
195 | TEST_ASSERT_VAL("wrong bp_len", | ||
196 | HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
184 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) | 200 | static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) |
185 | { | 201 | { |
186 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | 202 | struct perf_evsel *evsel = list_entry(evlist->entries.next, |
@@ -352,6 +368,19 @@ static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) | |||
352 | return test__checkevent_breakpoint_w(evlist); | 368 | return test__checkevent_breakpoint_w(evlist); |
353 | } | 369 | } |
354 | 370 | ||
371 | static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) | ||
372 | { | ||
373 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | ||
374 | struct perf_evsel, node); | ||
375 | |||
376 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | ||
377 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | ||
378 | TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); | ||
379 | TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); | ||
380 | |||
381 | return test__checkevent_breakpoint_rw(evlist); | ||
382 | } | ||
383 | |||
355 | static int test__checkevent_pmu(struct perf_evlist *evlist) | 384 | static int test__checkevent_pmu(struct perf_evlist *evlist) |
356 | { | 385 | { |
357 | 386 | ||
@@ -585,6 +614,14 @@ static struct test__event_st test__events[] = { | |||
585 | .name = "instructions:H", | 614 | .name = "instructions:H", |
586 | .check = test__checkevent_exclude_guest_modifier, | 615 | .check = test__checkevent_exclude_guest_modifier, |
587 | }, | 616 | }, |
617 | [26] = { | ||
618 | .name = "mem:0:rw", | ||
619 | .check = test__checkevent_breakpoint_rw, | ||
620 | }, | ||
621 | [27] = { | ||
622 | .name = "mem:0:rw:kp", | ||
623 | .check = test__checkevent_breakpoint_rw_modifier, | ||
624 | }, | ||
588 | }; | 625 | }; |
589 | 626 | ||
590 | #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) | 627 | #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0cc27da30ddb..7ae76af709f1 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -383,21 +383,31 @@ parse_breakpoint_type(const char *type, struct perf_event_attr *attr) | |||
383 | if (!type || !type[i]) | 383 | if (!type || !type[i]) |
384 | break; | 384 | break; |
385 | 385 | ||
386 | #define CHECK_SET_TYPE(bit) \ | ||
387 | do { \ | ||
388 | if (attr->bp_type & bit) \ | ||
389 | return -EINVAL; \ | ||
390 | else \ | ||
391 | attr->bp_type |= bit; \ | ||
392 | } while (0) | ||
393 | |||
386 | switch (type[i]) { | 394 | switch (type[i]) { |
387 | case 'r': | 395 | case 'r': |
388 | attr->bp_type |= HW_BREAKPOINT_R; | 396 | CHECK_SET_TYPE(HW_BREAKPOINT_R); |
389 | break; | 397 | break; |
390 | case 'w': | 398 | case 'w': |
391 | attr->bp_type |= HW_BREAKPOINT_W; | 399 | CHECK_SET_TYPE(HW_BREAKPOINT_W); |
392 | break; | 400 | break; |
393 | case 'x': | 401 | case 'x': |
394 | attr->bp_type |= HW_BREAKPOINT_X; | 402 | CHECK_SET_TYPE(HW_BREAKPOINT_X); |
395 | break; | 403 | break; |
396 | default: | 404 | default: |
397 | return -EINVAL; | 405 | return -EINVAL; |
398 | } | 406 | } |
399 | } | 407 | } |
400 | 408 | ||
409 | #undef CHECK_SET_TYPE | ||
410 | |||
401 | if (!attr->bp_type) /* Default */ | 411 | if (!attr->bp_type) /* Default */ |
402 | attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; | 412 | attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W; |
403 | 413 | ||
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 488362e14133..a06689474210 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l | |||
@@ -76,7 +76,7 @@ num_hex 0x[a-fA-F0-9]+ | |||
76 | num_raw_hex [a-fA-F0-9]+ | 76 | num_raw_hex [a-fA-F0-9]+ |
77 | name [a-zA-Z_*?][a-zA-Z0-9_*?]* | 77 | name [a-zA-Z_*?][a-zA-Z0-9_*?]* |
78 | modifier_event [ukhpGH]{1,8} | 78 | modifier_event [ukhpGH]{1,8} |
79 | modifier_bp [rwx] | 79 | modifier_bp [rwx]{1,3} |
80 | 80 | ||
81 | %% | 81 | %% |
82 | 82 | ||