Commit 3741eb9f authored by Jacob Shin's avatar Jacob Shin Committed by Frederic Weisbecker

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: default avatarJacob Shin <jacob.w.shin@gmail.com>
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Reviewed-by: default avatarOleg 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: default avatarFrederic Weisbecker <fweisbec@gmail.com>
parent d6d55f0b
...@@ -33,12 +33,15 @@ OPTIONS ...@@ -33,12 +33,15 @@ OPTIONS
- a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a
hexadecimal event descriptor. hexadecimal event descriptor.
- a hardware breakpoint event in the form of '\mem:addr[:access]' - a hardware breakpoint event in the form of '\mem:addr[/len][:access]'
where addr is the address in memory you want to break in. where addr is the address in memory you want to break in.
Access is the memory access type (read, write, execute) it can Access is the memory access type (read, write, execute) it can
be passed as follows: '\mem:addr[:[r][w][x]]'. be passed as follows: '\mem:addr[:[r][w][x]]'. len is the range,
number of bytes from specified addr, which the breakpoint will cover.
If you want to profile read-write accesses in 0x1000, just set If you want to profile read-write accesses in 0x1000, just set
'mem:0x1000:rw'. 'mem:0x1000:rw'.
If you want to profile write accesses in [0x1000~1008), just set
'mem:0x1000/8:w'.
--filter=<filter>:: --filter=<filter>::
Event filter. Event filter.
......
...@@ -526,7 +526,7 @@ do { \ ...@@ -526,7 +526,7 @@ do { \
} }
int parse_events_add_breakpoint(struct list_head *list, int *idx, int parse_events_add_breakpoint(struct list_head *list, int *idx,
void *ptr, char *type) void *ptr, char *type, u64 len)
{ {
struct perf_event_attr attr; struct perf_event_attr attr;
...@@ -536,14 +536,15 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx, ...@@ -536,14 +536,15 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
if (parse_breakpoint_type(type, &attr)) if (parse_breakpoint_type(type, &attr))
return -EINVAL; return -EINVAL;
/* /* Provide some defaults if len is not specified */
* We should find a nice way to override the access length if (!len) {
* Provide some defaults for now if (attr.bp_type == HW_BREAKPOINT_X)
*/ len = sizeof(long);
if (attr.bp_type == HW_BREAKPOINT_X) else
attr.bp_len = sizeof(long); len = HW_BREAKPOINT_LEN_4;
else }
attr.bp_len = HW_BREAKPOINT_LEN_4;
attr.bp_len = len;
attr.type = PERF_TYPE_BREAKPOINT; attr.type = PERF_TYPE_BREAKPOINT;
attr.sample_period = 1; attr.sample_period = 1;
...@@ -1364,7 +1365,7 @@ void print_events(const char *event_glob, bool name_only) ...@@ -1364,7 +1365,7 @@ void print_events(const char *event_glob, bool name_only)
printf("\n"); printf("\n");
printf(" %-50s [%s]\n", printf(" %-50s [%s]\n",
"mem:<addr>[:access]", "mem:<addr>[/len][:access]",
event_type_descriptors[PERF_TYPE_BREAKPOINT]); event_type_descriptors[PERF_TYPE_BREAKPOINT]);
printf("\n"); printf("\n");
} }
......
...@@ -104,7 +104,7 @@ int parse_events_add_numeric(struct list_head *list, int *idx, ...@@ -104,7 +104,7 @@ int parse_events_add_numeric(struct list_head *list, int *idx,
int parse_events_add_cache(struct list_head *list, int *idx, int parse_events_add_cache(struct list_head *list, int *idx,
char *type, char *op_result1, char *op_result2); char *type, char *op_result1, char *op_result2);
int parse_events_add_breakpoint(struct list_head *list, int *idx, int parse_events_add_breakpoint(struct list_head *list, int *idx,
void *ptr, char *type); void *ptr, char *type, u64 len);
int parse_events_add_pmu(struct list_head *list, int *idx, int parse_events_add_pmu(struct list_head *list, int *idx,
char *pmu , struct list_head *head_config); char *pmu , struct list_head *head_config);
enum perf_pmu_event_symbol_type enum perf_pmu_event_symbol_type
......
...@@ -159,6 +159,7 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE ...@@ -159,6 +159,7 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE
<mem>{ <mem>{
{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); } {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
: { return ':'; } : { return ':'; }
"/" { return '/'; }
{num_dec} { return value(yyscanner, 10); } {num_dec} { return value(yyscanner, 10); }
{num_hex} { return value(yyscanner, 16); } {num_hex} { return value(yyscanner, 16); }
/* /*
......
...@@ -326,6 +326,28 @@ PE_NAME_CACHE_TYPE ...@@ -326,6 +326,28 @@ PE_NAME_CACHE_TYPE
} }
event_legacy_mem: event_legacy_mem:
PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
{
struct parse_events_evlist *data = _data;
struct list_head *list;
ALLOC_LIST(list);
ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
(void *) $2, $6, $4));
$$ = list;
}
|
PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
{
struct parse_events_evlist *data = _data;
struct list_head *list;
ALLOC_LIST(list);
ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
(void *) $2, NULL, $4));
$$ = list;
}
|
PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
{ {
struct parse_events_evlist *data = _data; struct parse_events_evlist *data = _data;
...@@ -333,7 +355,7 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc ...@@ -333,7 +355,7 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
ALLOC_LIST(list); ALLOC_LIST(list);
ABORT_ON(parse_events_add_breakpoint(list, &data->idx, ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
(void *) $2, $4)); (void *) $2, $4, 0));
$$ = list; $$ = list;
} }
| |
...@@ -344,7 +366,7 @@ PE_PREFIX_MEM PE_VALUE sep_dc ...@@ -344,7 +366,7 @@ PE_PREFIX_MEM PE_VALUE sep_dc
ALLOC_LIST(list); ALLOC_LIST(list);
ABORT_ON(parse_events_add_breakpoint(list, &data->idx, ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
(void *) $2, NULL)); (void *) $2, NULL, 0));
$$ = list; $$ = list;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment