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

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
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -33,12 +33,15 @@ OPTIONS
        - a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a
	  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.
          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
          'mem:0x1000:rw'.
          If you want to profile write accesses in [0x1000~1008), just set
          'mem:0x1000/8:w'.

--filter=<filter>::
        Event filter.
+11 −10
Original line number Diff line number Diff line
@@ -526,7 +526,7 @@ do { \
}

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;

@@ -536,14 +536,15 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
	if (parse_breakpoint_type(type, &attr))
		return -EINVAL;

	/*
	 * We should find a nice way to override the access length
	 * Provide some defaults for now
	 */
	/* Provide some defaults if len is not specified */
	if (!len) {
		if (attr.bp_type == HW_BREAKPOINT_X)
		attr.bp_len = sizeof(long);
			len = sizeof(long);
		else
		attr.bp_len = HW_BREAKPOINT_LEN_4;
			len = HW_BREAKPOINT_LEN_4;
	}

	attr.bp_len = len;

	attr.type = PERF_TYPE_BREAKPOINT;
	attr.sample_period = 1;
@@ -1364,7 +1365,7 @@ void print_events(const char *event_glob, bool name_only)
		printf("\n");

		printf("  %-50s [%s]\n",
		       "mem:<addr>[:access]",
		       "mem:<addr>[/len][:access]",
			event_type_descriptors[PERF_TYPE_BREAKPOINT]);
		printf("\n");
	}
+1 −1
Original line number Diff line number Diff line
@@ -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,
			   char *type, char *op_result1, char *op_result2);
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,
			 char *pmu , struct list_head *head_config);
enum perf_pmu_event_symbol_type
+1 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE
<mem>{
{modifier_bp}		{ return str(yyscanner, PE_MODIFIER_BP); }
:			{ return ':'; }
"/"			{ return '/'; }
{num_dec}		{ return value(yyscanner, 10); }
{num_hex}		{ return value(yyscanner, 16); }
	/*
+24 −2
Original line number Diff line number Diff line
@@ -326,6 +326,28 @@ PE_NAME_CACHE_TYPE
}

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
{
	struct parse_events_evlist *data = _data;
@@ -333,7 +355,7 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc

	ALLOC_LIST(list);
	ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
					     (void *) $2, $4));
					     (void *) $2, $4, 0));
	$$ = list;
}
|
@@ -344,7 +366,7 @@ PE_PREFIX_MEM PE_VALUE sep_dc

	ALLOC_LIST(list);
	ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
					     (void *) $2, NULL));
					     (void *) $2, NULL, 0));
	$$ = list;
}