diff --git a/tools/perf/arch/powerpc/util/event.c b/tools/perf/arch/powerpc/util/event.c
index b80fbee83b6e..fddfc288c415 100644
--- a/tools/perf/arch/powerpc/util/event.c
+++ b/tools/perf/arch/powerpc/util/event.c
@@ -44,3 +44,10 @@ const char *arch_perf_header_entry__add(const char *se_header)
return "Dispatch Cyc";
return se_header;
}
+
+int arch_support_dynamic_key(const char *sort_key)
+{
+ if (!strcmp(sort_key, "p_stage_cyc"))
+ return 1;
+ return 0;
+}diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 65f89e80916f..6cd4bf54dbdc 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -429,5 +429,6 @@ 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);
const char *arch_perf_header_entry__add(const char *se_header);
+int arch_support_dynamic_key(const char *sort_key);
#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index cbb3899e7eca..e194b1187db8 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -37,7 +37,7 @@ const char default_parent_pattern[] = "^sys_|^do_page_fault";
const char *parent_pattern = default_parent_pattern;
const char *default_sort_order = "comm,dso,symbol";
const char default_branch_sort_order[] = "comm,dso_from,symbol_from,symbol_to,cycles";
-const char default_mem_sort_order[] = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked,blocked,local_ins_lat,p_stage_cyc";
+const char default_mem_sort_order[] = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked,blocked,local_ins_lat";
const char default_top_sort_order[] = "dso,symbol";
const char default_diff_sort_order[] = "dso,symbol";
const char default_tracepoint_sort_order[] = "trace";
@@ -47,6 +47,7 @@ regex_t ignore_callees_regex;
int have_ignore_callees = 0;
enum sort_mode sort__mode = SORT_MODE__NORMAL;
const char *dynamic_headers[] = {"local_ins_lat", "p_stage_cyc"};
+const char *dynamic_sort_keys_mem[] = {"p_stage_cyc"};
/*
* Replaces all occurrences of a char used with the:@@ -2997,6 +2998,20 @@ static char *prefix_if_not_in(const char *pre, char *str)
return n;
}
+/*
+ * Adds 'suff,' suffix into 'str' if 'suff' is
+ * not already part of 'str'.
+ */
+static char *suffix_if_not_in(const char *suff, char *str)
+{
+ if (!str || strstr(str, suff))
+ return str;
+
+ if (asprintf(&str, "%s,%s", str, suff) < 0)
+ str = NULL;
+ return str;
+}
+
static char *setup_overhead(char *keys)
{
if (sort__mode == SORT_MODE__DIFF)@@ -3010,6 +3025,26 @@ static char *setup_overhead(char *keys)
return keys;
}
+int __weak arch_support_dynamic_key(const char *sort_key __maybe_unused)
+{
+ return 0;
+}
+
+static char *setup_dynamic_sort_keys(char *str)
+{
+ unsigned int j;
+
+ if (sort__mode == SORT_MODE__MEMORY)
+ for (j = 0; j < ARRAY_SIZE(dynamic_sort_keys_mem); j++)
+ if (arch_support_dynamic_key(dynamic_sort_keys_mem[j])) {
+ str = suffix_if_not_in(dynamic_sort_keys_mem[j], str);
+ if (str == NULL)
+ return str;
+ }
+
+ return str;
+}
+
static int __setup_sorting(struct evlist *evlist)
{
char *str;@@ -3050,6 +3085,12 @@ static int __setup_sorting(struct evlist *evlist)
}
}
+ str = setup_dynamic_sort_keys(str);
+ if (str == NULL) {
+ pr_err("Not enough memory to setup dynamic sort keys");
+ return -ENOMEM;
+ }
+
ret = setup_sort_list(&perf_hpp_list, str, evlist);
free(str);--
2.26.2
Thanks,
Athira
>
>> };
>>
>> #undef DIM
>> diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
>> index 63f67a3f3630..23b20cbbc846 100644
>> --- a/tools/perf/util/sort.h
>> +++ b/tools/perf/util/sort.h
>> @@ -51,6 +51,7 @@ struct he_stat {
>> u64 period_guest_us;
>> u64 weight;
>> u64 ins_lat;
>> + u64 p_stage_cyc;
>> u32 nr_events;
>> };
>>
>> @@ -234,6 +235,7 @@ enum sort_type {
>> SORT_CODE_PAGE_SIZE,
>> SORT_LOCAL_INS_LAT,
>> SORT_GLOBAL_INS_LAT,
>> + SORT_P_STAGE_CYC,
>
> we could have the whole 'SORT_PEPELINE_STAGE_CYC',
> so it's more obvious
Ok.
>
> thanks,
> jirka