diff options
| author | Jacob Shin <jacob.w.shin@gmail.com> | 2014-05-29 11:26:51 -0400 |
|---|---|---|
| committer | Frederic Weisbecker <fweisbec@gmail.com> | 2014-12-03 09:14:29 -0500 |
| commit | 3741eb9f8c3be3ec59583881c1f49980dad844e0 (patch) | |
| tree | e4744f42bbaf21c8ddf623f1b87202c1ae3e1a93 /tools/perf/util | |
| parent | d6d55f0b9d900673548515614b56ab55aa2c51f8 (diff) | |
perf tools: allow user to specify hardware breakpoint bp_len
Currently bp_len is given a default value of 4. Allow user to override it:
$ perf stat -e mem:0x1000/8
^
bp_len
If no value is given, it will default to 4 as it did before.
Signed-off-by: Jacob Shin <jacob.w.shin@gmail.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: xiakaixu <xiakaixu@huawei.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'tools/perf/util')
| -rw-r--r-- | tools/perf/util/parse-events.c | 21 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.h | 2 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.l | 1 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.y | 26 |
4 files changed, 37 insertions, 13 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index c659a3ca1283..efa1ff4cca63 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -526,7 +526,7 @@ do { \ | |||
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | int parse_events_add_breakpoint(struct list_head *list, int *idx, | 528 | int parse_events_add_breakpoint(struct list_head *list, int *idx, |
| 529 | void *ptr, char *type) | 529 | void *ptr, char *type, u64 len) |
| 530 | { | 530 | { |
| 531 | struct perf_event_attr attr; | 531 | struct perf_event_attr attr; |
| 532 | 532 | ||
| @@ -536,14 +536,15 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx, | |||
| 536 | if (parse_breakpoint_type(type, &attr)) | 536 | if (parse_breakpoint_type(type, &attr)) |
| 537 | return -EINVAL; | 537 | return -EINVAL; |
| 538 | 538 | ||
| 539 | /* | 539 | /* Provide some defaults if len is not specified */ |
| 540 | * We should find a nice way to override the access length | 540 | if (!len) { |
| 541 | * Provide some defaults for now | 541 | if (attr.bp_type == HW_BREAKPOINT_X) |
| 542 | */ | 542 | len = sizeof(long); |
| 543 | if (attr.bp_type == HW_BREAKPOINT_X) | 543 | else |
| 544 | attr.bp_len = sizeof(long); | 544 | len = HW_BREAKPOINT_LEN_4; |
| 545 | else | 545 | } |
| 546 | attr.bp_len = HW_BREAKPOINT_LEN_4; | 546 | |
| 547 | attr.bp_len = len; | ||
| 547 | 548 | ||
| 548 | attr.type = PERF_TYPE_BREAKPOINT; | 549 | attr.type = PERF_TYPE_BREAKPOINT; |
| 549 | attr.sample_period = 1; | 550 | attr.sample_period = 1; |
| @@ -1364,7 +1365,7 @@ void print_events(const char *event_glob, bool name_only) | |||
| 1364 | printf("\n"); | 1365 | printf("\n"); |
| 1365 | 1366 | ||
| 1366 | printf(" %-50s [%s]\n", | 1367 | printf(" %-50s [%s]\n", |
| 1367 | "mem:<addr>[:access]", | 1368 | "mem:<addr>[/len][:access]", |
| 1368 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); | 1369 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); |
| 1369 | printf("\n"); | 1370 | printf("\n"); |
| 1370 | } | 1371 | } |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index db2cf78ff0f3..a19fbeb80943 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
| @@ -104,7 +104,7 @@ int parse_events_add_numeric(struct list_head *list, int *idx, | |||
| 104 | int parse_events_add_cache(struct list_head *list, int *idx, | 104 | int parse_events_add_cache(struct list_head *list, int *idx, |
| 105 | char *type, char *op_result1, char *op_result2); | 105 | char *type, char *op_result1, char *op_result2); |
| 106 | int parse_events_add_breakpoint(struct list_head *list, int *idx, | 106 | int parse_events_add_breakpoint(struct list_head *list, int *idx, |
| 107 | void *ptr, char *type); | 107 | void *ptr, char *type, u64 len); |
| 108 | int parse_events_add_pmu(struct list_head *list, int *idx, | 108 | int parse_events_add_pmu(struct list_head *list, int *idx, |
| 109 | char *pmu , struct list_head *head_config); | 109 | char *pmu , struct list_head *head_config); |
| 110 | enum perf_pmu_event_symbol_type | 110 | enum perf_pmu_event_symbol_type |
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 906630bbf8eb..94eacb6c1ef7 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l | |||
| @@ -159,6 +159,7 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE | |||
| 159 | <mem>{ | 159 | <mem>{ |
| 160 | {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } | 160 | {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } |
| 161 | : { return ':'; } | 161 | : { return ':'; } |
| 162 | "/" { return '/'; } | ||
| 162 | {num_dec} { return value(yyscanner, 10); } | 163 | {num_dec} { return value(yyscanner, 10); } |
| 163 | {num_hex} { return value(yyscanner, 16); } | 164 | {num_hex} { return value(yyscanner, 16); } |
| 164 | /* | 165 | /* |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 93c4c9fbc922..72def077dbbf 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
| @@ -326,6 +326,28 @@ PE_NAME_CACHE_TYPE | |||
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | event_legacy_mem: | 328 | event_legacy_mem: |
| 329 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc | ||
| 330 | { | ||
| 331 | struct parse_events_evlist *data = _data; | ||
| 332 | struct list_head *list; | ||
| 333 | |||
| 334 | ALLOC_LIST(list); | ||
| 335 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | ||
| 336 | (void *) $2, $6, $4)); | ||
| 337 | $$ = list; | ||
| 338 | } | ||
| 339 | | | ||
| 340 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc | ||
| 341 | { | ||
| 342 | struct parse_events_evlist *data = _data; | ||
| 343 | struct list_head *list; | ||
| 344 | |||
| 345 | ALLOC_LIST(list); | ||
| 346 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | ||
| 347 | (void *) $2, NULL, $4)); | ||
| 348 | $$ = list; | ||
| 349 | } | ||
| 350 | | | ||
| 329 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc | 351 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc |
| 330 | { | 352 | { |
| 331 | struct parse_events_evlist *data = _data; | 353 | struct parse_events_evlist *data = _data; |
| @@ -333,7 +355,7 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc | |||
| 333 | 355 | ||
| 334 | ALLOC_LIST(list); | 356 | ALLOC_LIST(list); |
| 335 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | 357 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, |
| 336 | (void *) $2, $4)); | 358 | (void *) $2, $4, 0)); |
| 337 | $$ = list; | 359 | $$ = list; |
| 338 | } | 360 | } |
| 339 | | | 361 | | |
| @@ -344,7 +366,7 @@ PE_PREFIX_MEM PE_VALUE sep_dc | |||
| 344 | 366 | ||
| 345 | ALLOC_LIST(list); | 367 | ALLOC_LIST(list); |
| 346 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, | 368 | ABORT_ON(parse_events_add_breakpoint(list, &data->idx, |
| 347 | (void *) $2, NULL)); | 369 | (void *) $2, NULL, 0)); |
| 348 | $$ = list; | 370 | $$ = list; |
| 349 | } | 371 | } |
| 350 | 372 | ||
