perf tools: Support arch specific PERF_SAMPLE_WEIGHT_STRUCT processing
authorKan Liang <kan.liang@linux.intel.com>
Fri, 5 Feb 2021 16:01:52 +0000 (08:01 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 18 Feb 2021 19:07:06 +0000 (16:07 -0300)
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>
tools/perf/arch/x86/util/event.c
tools/perf/util/event.h
tools/perf/util/evsel.c
tools/perf/util/synthetic-events.c

index 047dc00eafa6ec099fda74e794ebcd378525ef2b..9b31734ee9685b014065fe9eddf14203b806301a 100644 (file)
@@ -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);
+       }
+}
index 4a3b5b6478d88b431aad083f37bf9fcd7ca26507..e3150a6287824f60bed11cd97c3f713c7a3aa696 100644 (file)
@@ -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 */
index 844aebd9c306d71b446fc33e3e9987685d68232b..1bf76864c4f26cc61036b5c0f57eda2fd42b5ede 100644 (file)
@@ -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++;
        }
 
index 0b767233ae1f5626d5c907cd119d386910038762..b698046ec2db2ad58ddfa666f64af5dca8a095a3 100644 (file)
@@ -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++;
        }
 
This page took 0.077314 seconds and 4 git commands to generate.