Skip to content

Commit fbefe9c

Browse files
Kan Liangacmel
authored andcommitted
perf tools: Support arch specific PERF_SAMPLE_WEIGHT_STRUCT processing
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 <kan.liang@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com> Cc: Jin Yao <yao.jin@linux.intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lore.kernel.org/lkml/1612540912-6562-1-git-send-email-kan.liang@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent c840cbf commit fbefe9c

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

tools/perf/arch/x86/util/event.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,28 @@ int perf_event__synthesize_extra_kmaps(struct perf_tool *tool,
7575
}
7676

7777
#endif
78+
79+
void arch_perf_parse_sample_weight(struct perf_sample *data,
80+
const __u64 *array, u64 type)
81+
{
82+
union perf_sample_weight weight;
83+
84+
weight.full = *array;
85+
if (type & PERF_SAMPLE_WEIGHT)
86+
data->weight = weight.full;
87+
else {
88+
data->weight = weight.var1_dw;
89+
data->ins_lat = weight.var2_w;
90+
}
91+
}
92+
93+
void arch_perf_synthesize_sample_weight(const struct perf_sample *data,
94+
__u64 *array, u64 type)
95+
{
96+
*array = data->weight;
97+
98+
if (type & PERF_SAMPLE_WEIGHT_STRUCT) {
99+
*array &= 0xffffffff;
100+
*array |= ((u64)data->ins_lat << 32);
101+
}
102+
}

tools/perf/util/event.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,4 +421,7 @@ extern unsigned int proc_map_timeout;
421421
#define PAGE_SIZE_NAME_LEN 32
422422
char *get_page_size_name(u64 size, char *str);
423423

424+
void arch_perf_parse_sample_weight(struct perf_sample *data, const __u64 *array, u64 type);
425+
void arch_perf_synthesize_sample_weight(const struct perf_sample *data, __u64 *array, u64 type);
426+
424427
#endif /* __PERF_RECORD_H */

tools/perf/util/evsel.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,6 +2105,13 @@ perf_event__check_size(union perf_event *event, unsigned int sample_size)
21052105
return 0;
21062106
}
21072107

2108+
void __weak arch_perf_parse_sample_weight(struct perf_sample *data,
2109+
const __u64 *array,
2110+
u64 type __maybe_unused)
2111+
{
2112+
data->weight = *array;
2113+
}
2114+
21082115
int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
21092116
struct perf_sample *data)
21102117
{
@@ -2346,16 +2353,8 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
23462353
}
23472354

23482355
if (type & PERF_SAMPLE_WEIGHT_TYPE) {
2349-
union perf_sample_weight weight;
2350-
23512356
OVERFLOW_CHECK_u64(array);
2352-
weight.full = *array;
2353-
if (type & PERF_SAMPLE_WEIGHT)
2354-
data->weight = weight.full;
2355-
else {
2356-
data->weight = weight.var1_dw;
2357-
data->ins_lat = weight.var2_w;
2358-
}
2357+
arch_perf_parse_sample_weight(data, array, type);
23592358
array++;
23602359
}
23612360

tools/perf/util/synthetic-events.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,12 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type,
15061506
return result;
15071507
}
15081508

1509+
void __weak arch_perf_synthesize_sample_weight(const struct perf_sample *data,
1510+
__u64 *array, u64 type __maybe_unused)
1511+
{
1512+
*array = data->weight;
1513+
}
1514+
15091515
int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format,
15101516
const struct perf_sample *sample)
15111517
{
@@ -1642,11 +1648,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
16421648
}
16431649

16441650
if (type & PERF_SAMPLE_WEIGHT_TYPE) {
1645-
*array = sample->weight;
1646-
if (type & PERF_SAMPLE_WEIGHT_STRUCT) {
1647-
*array &= 0xffffffff;
1648-
*array |= ((u64)sample->ins_lat << 32);
1649-
}
1651+
arch_perf_synthesize_sample_weight(sample, array, type);
16501652
array++;
16511653
}
16521654

0 commit comments

Comments
 (0)