Skip to content

Commit

Permalink
perf tools: Support arch specific PERF_SAMPLE_WEIGHT_STRUCT processing
Browse files Browse the repository at this point in the history
For X86, the var2_w field of PERF_SAMPLE_WEIGHT_STRUCT stands for the
instruction latency. Current perf forces the var2_w to the data->ins_lat
in the generic code. It works well for now because X86 is the only
architecture that supports the PERF_SAMPLE_WEIGHT_STRUCT, but it may
bring problems once other architectures support the sample type.  For
example, the var2_w may be used to capture something else on PowerPC.

Create two architecture specific functions to parse and synthesize the
weight related samples. Move the X86 specific codes to the X86 version
functions. Other architectures can implement their own functions later
separately.

Signed-off-by: Kan Liang <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Athira Jajeev <[email protected]>
Cc: Jin Yao <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Madhavan Srinivasan <[email protected]>
Cc: Namhyung Kim <[email protected]>
Link: http://lore.kernel.org/lkml/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
Kan Liang authored and acmel committed Feb 18, 2021
1 parent c840cbf commit fbefe9c
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 14 deletions.
25 changes: 25 additions & 0 deletions tools/perf/arch/x86/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,28 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool,
}

#endif

void arch_perf_parse_sample_weight(struct perf_sample *data,
const __u64 *array, u64 type)
{
union perf_sample_weight weight;

weight.full = *array;
if (type & PERF_SAMPLE_WEIGHT)
data->weight = weight.full;
else {
data->weight = weight.var1_dw;
data->ins_lat = weight.var2_w;
}
}

void arch_perf_synthesize_sample_weight(const struct perf_sample *data,
__u64 *array, u64 type)
{
*array = data->weight;

if (type & PERF_SAMPLE_WEIGHT_STRUCT) {
*array &= 0xffffffff;
*array |= ((u64)data->ins_lat << 32);
}
}
3 changes: 3 additions & 0 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,7 @@ extern unsigned int proc_map_timeout;
#define PAGE_SIZE_NAME_LEN 32
char *get_page_size_name(u64 size, char *str);

void arch_perf_parse_sample_weight(struct perf_sample *data, const __u64 *array, u64 type);
void arch_perf_synthesize_sample_weight(const struct perf_sample *data, __u64 *array, u64 type);

#endif /* __PERF_RECORD_H */
17 changes: 8 additions & 9 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,6 +2105,13 @@ perf_event__check_size(union perf_event *event, unsigned int sample_size)
return 0;
}

void __weak arch_perf_parse_sample_weight(struct perf_sample *data,
const __u64 *array,
u64 type __maybe_unused)
{
data->weight = *array;
}

int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
struct perf_sample *data)
{
Expand Down Expand Up @@ -2346,16 +2353,8 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
}

if (type & PERF_SAMPLE_WEIGHT_TYPE) {
union perf_sample_weight weight;

OVERFLOW_CHECK_u64(array);
weight.full = *array;
if (type & PERF_SAMPLE_WEIGHT)
data->weight = weight.full;
else {
data->weight = weight.var1_dw;
data->ins_lat = weight.var2_w;
}
arch_perf_parse_sample_weight(data, array, type);
array++;
}

Expand Down
12 changes: 7 additions & 5 deletions tools/perf/util/synthetic-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,12 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
return result;
}

void __weak arch_perf_synthesize_sample_weight(const struct perf_sample *data,
__u64 *array, u64 type __maybe_unused)
{
*array = data->weight;
}

int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
const struct perf_sample *sample)
{
Expand Down Expand Up @@ -1642,11 +1648,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
}

if (type & PERF_SAMPLE_WEIGHT_TYPE) {
*array = sample->weight;
if (type & PERF_SAMPLE_WEIGHT_STRUCT) {
*array &= 0xffffffff;
*array |= ((u64)sample->ins_lat << 32);
}
arch_perf_synthesize_sample_weight(sample, array, type);
array++;
}

Expand Down

0 comments on commit fbefe9c

Please sign in to comment.