diff --git a/tools/perf/arch/x86/util/event.c b/tools/perf/arch/x86/util/event.c index 047dc00eafa6e..9b31734ee9685 100644 --- a/tools/perf/arch/x86/util/event.c +++ b/tools/perf/arch/x86/util/event.c @@ -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); + } +} diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 4a3b5b6478d88..e3150a6287824 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -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 */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 844aebd9c306d..1bf76864c4f26 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -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) { @@ -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++; } diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 0b767233ae1f5..b698046ec2db2 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -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) { @@ -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++; }