hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/tools/perf/util/sort.c
....@@ -2,18 +2,34 @@
22 #include <errno.h>
33 #include <inttypes.h>
44 #include <regex.h>
5
+#include <stdlib.h>
56 #include <linux/mman.h>
7
+#include <linux/time64.h>
8
+#include "debug.h"
9
+#include "dso.h"
610 #include "sort.h"
711 #include "hist.h"
12
+#include "cacheline.h"
813 #include "comm.h"
14
+#include "map.h"
15
+#include "maps.h"
916 #include "symbol.h"
17
+#include "map_symbol.h"
18
+#include "branch.h"
1019 #include "thread.h"
1120 #include "evsel.h"
1221 #include "evlist.h"
22
+#include "srcline.h"
1323 #include "strlist.h"
24
+#include "strbuf.h"
1425 #include <traceevent/event-parse.h>
1526 #include "mem-events.h"
27
+#include "annotate.h"
28
+#include "time-utils.h"
29
+#include "cgroup.h"
30
+#include "machine.h"
1631 #include <linux/kernel.h>
32
+#include <linux/string.h>
1733
1834 regex_t parent_regex;
1935 const char default_parent_pattern[] = "^sys_|^do_page_fault";
....@@ -36,7 +52,7 @@
3652 * -t, --field-separator
3753 *
3854 * option, that uses a special separator character and don't pad with spaces,
39
- * replacing all occurances of this separator in symbol names (and other
55
+ * replacing all occurrences of this separator in symbol names (and other
4056 * output) with a '.' character, that thus it's the only non valid separator.
4157 */
4258 static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...)
....@@ -221,7 +237,7 @@
221237 return (int64_t)(right_ip - left_ip);
222238 }
223239
224
-static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
240
+int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
225241 {
226242 if (!sym_l || !sym_r)
227243 return cmp_null(sym_l, sym_r);
....@@ -274,16 +290,24 @@
274290 return strcmp(right->ms.sym->name, left->ms.sym->name);
275291 }
276292
277
-static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
293
+static int _hist_entry__sym_snprintf(struct map_symbol *ms,
278294 u64 ip, char level, char *bf, size_t size,
279295 unsigned int width)
280296 {
297
+ struct symbol *sym = ms->sym;
298
+ struct map *map = ms->map;
281299 size_t ret = 0;
282300
283301 if (verbose > 0) {
284302 char o = map ? dso__symtab_origin(map->dso) : '!';
303
+ u64 rip = ip;
304
+
305
+ if (map && map->dso && map->dso->kernel
306
+ && map->dso->adjust_symbols)
307
+ rip = map->unmap_ip(map, ip);
308
+
285309 ret += repsep_snprintf(bf, size, "%-#*llx %c ",
286
- BITS_PER_LONG / 4 + 2, ip, o);
310
+ BITS_PER_LONG / 4 + 2, rip, o);
287311 }
288312
289313 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
....@@ -309,10 +333,9 @@
309333 return ret;
310334 }
311335
312
-static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
313
- size_t size, unsigned int width)
336
+int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width)
314337 {
315
- return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
338
+ return _hist_entry__sym_snprintf(&he->ms, he->ip,
316339 he->level, bf, size, width);
317340 }
318341
....@@ -373,7 +396,7 @@
373396
374397 static char *addr_map_symbol__srcline(struct addr_map_symbol *ams)
375398 {
376
- return map__srcline(ams->map, ams->al_addr, ams->sym);
399
+ return map__srcline(ams->ms.map, ams->al_addr, ams->ms.sym);
377400 }
378401
379402 static int64_t
....@@ -426,6 +449,57 @@
426449 .se_cmp = sort__srcline_to_cmp,
427450 .se_snprintf = hist_entry__srcline_to_snprintf,
428451 .se_width_idx = HISTC_SRCLINE_TO,
452
+};
453
+
454
+static int hist_entry__sym_ipc_snprintf(struct hist_entry *he, char *bf,
455
+ size_t size, unsigned int width)
456
+{
457
+
458
+ struct symbol *sym = he->ms.sym;
459
+ struct annotation *notes;
460
+ double ipc = 0.0, coverage = 0.0;
461
+ char tmp[64];
462
+
463
+ if (!sym)
464
+ return repsep_snprintf(bf, size, "%-*s", width, "-");
465
+
466
+ notes = symbol__annotation(sym);
467
+
468
+ if (notes->hit_cycles)
469
+ ipc = notes->hit_insn / ((double)notes->hit_cycles);
470
+
471
+ if (notes->total_insn) {
472
+ coverage = notes->cover_insn * 100.0 /
473
+ ((double)notes->total_insn);
474
+ }
475
+
476
+ snprintf(tmp, sizeof(tmp), "%-5.2f [%5.1f%%]", ipc, coverage);
477
+ return repsep_snprintf(bf, size, "%-*s", width, tmp);
478
+}
479
+
480
+struct sort_entry sort_sym_ipc = {
481
+ .se_header = "IPC [IPC Coverage]",
482
+ .se_cmp = sort__sym_cmp,
483
+ .se_snprintf = hist_entry__sym_ipc_snprintf,
484
+ .se_width_idx = HISTC_SYMBOL_IPC,
485
+};
486
+
487
+static int hist_entry__sym_ipc_null_snprintf(struct hist_entry *he
488
+ __maybe_unused,
489
+ char *bf, size_t size,
490
+ unsigned int width)
491
+{
492
+ char tmp[64];
493
+
494
+ snprintf(tmp, sizeof(tmp), "%-5s %2s", "-", "-");
495
+ return repsep_snprintf(bf, size, "%-*s", width, tmp);
496
+}
497
+
498
+struct sort_entry sort_sym_ipc_null = {
499
+ .se_header = "IPC [IPC Coverage]",
500
+ .se_cmp = sort__sym_cmp,
501
+ .se_snprintf = hist_entry__sym_ipc_null_snprintf,
502
+ .se_width_idx = HISTC_SYMBOL_IPC,
429503 };
430504
431505 /* --sort srcfile */
....@@ -569,6 +643,39 @@
569643 .se_width_idx = HISTC_CGROUP_ID,
570644 };
571645
646
+/* --sort cgroup */
647
+
648
+static int64_t
649
+sort__cgroup_cmp(struct hist_entry *left, struct hist_entry *right)
650
+{
651
+ return right->cgroup - left->cgroup;
652
+}
653
+
654
+static int hist_entry__cgroup_snprintf(struct hist_entry *he,
655
+ char *bf, size_t size,
656
+ unsigned int width __maybe_unused)
657
+{
658
+ const char *cgrp_name = "N/A";
659
+
660
+ if (he->cgroup) {
661
+ struct cgroup *cgrp = cgroup__find(he->ms.maps->machine->env,
662
+ he->cgroup);
663
+ if (cgrp != NULL)
664
+ cgrp_name = cgrp->name;
665
+ else
666
+ cgrp_name = "unknown";
667
+ }
668
+
669
+ return repsep_snprintf(bf, size, "%s", cgrp_name);
670
+}
671
+
672
+struct sort_entry sort_cgroup = {
673
+ .se_header = "Cgroup",
674
+ .se_cmp = sort__cgroup_cmp,
675
+ .se_snprintf = hist_entry__cgroup_snprintf,
676
+ .se_width_idx = HISTC_CGROUP,
677
+};
678
+
572679 /* --sort socket */
573680
574681 static int64_t
....@@ -601,12 +708,42 @@
601708 .se_width_idx = HISTC_SOCKET,
602709 };
603710
711
+/* --sort time */
712
+
713
+static int64_t
714
+sort__time_cmp(struct hist_entry *left, struct hist_entry *right)
715
+{
716
+ return right->time - left->time;
717
+}
718
+
719
+static int hist_entry__time_snprintf(struct hist_entry *he, char *bf,
720
+ size_t size, unsigned int width)
721
+{
722
+ char he_time[32];
723
+
724
+ if (symbol_conf.nanosecs)
725
+ timestamp__scnprintf_nsec(he->time, he_time,
726
+ sizeof(he_time));
727
+ else
728
+ timestamp__scnprintf_usec(he->time, he_time,
729
+ sizeof(he_time));
730
+
731
+ return repsep_snprintf(bf, size, "%-.*s", width, he_time);
732
+}
733
+
734
+struct sort_entry sort_time = {
735
+ .se_header = "Time",
736
+ .se_cmp = sort__time_cmp,
737
+ .se_snprintf = hist_entry__time_snprintf,
738
+ .se_width_idx = HISTC_TIME,
739
+};
740
+
604741 /* --sort trace */
605742
606743 static char *get_trace_output(struct hist_entry *he)
607744 {
608745 struct trace_seq seq;
609
- struct perf_evsel *evsel;
746
+ struct evsel *evsel;
610747 struct tep_record rec = {
611748 .data = he->raw_data,
612749 .size = he->raw_size,
....@@ -619,7 +756,8 @@
619756 tep_print_fields(&seq, he->raw_data, he->raw_size,
620757 evsel->tp_format);
621758 } else {
622
- tep_event_info(&seq, evsel->tp_format, &rec);
759
+ tep_print_event(evsel->tp_format->tep,
760
+ &seq, &rec, "%s", TEP_PRINT_INFO);
623761 }
624762 /*
625763 * Trim the buffer, it starts at 4KB and we're not going to
....@@ -631,10 +769,10 @@
631769 static int64_t
632770 sort__trace_cmp(struct hist_entry *left, struct hist_entry *right)
633771 {
634
- struct perf_evsel *evsel;
772
+ struct evsel *evsel;
635773
636774 evsel = hists_to_evsel(left->hists);
637
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
775
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
638776 return 0;
639777
640778 if (left->trace_output == NULL)
....@@ -648,10 +786,10 @@
648786 static int hist_entry__trace_snprintf(struct hist_entry *he, char *bf,
649787 size_t size, unsigned int width)
650788 {
651
- struct perf_evsel *evsel;
789
+ struct evsel *evsel;
652790
653791 evsel = hists_to_evsel(he->hists);
654
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
792
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
655793 return scnprintf(bf, size, "%-.*s", width, "N/A");
656794
657795 if (he->trace_output == NULL)
....@@ -674,15 +812,15 @@
674812 if (!left->branch_info || !right->branch_info)
675813 return cmp_null(left->branch_info, right->branch_info);
676814
677
- return _sort__dso_cmp(left->branch_info->from.map,
678
- right->branch_info->from.map);
815
+ return _sort__dso_cmp(left->branch_info->from.ms.map,
816
+ right->branch_info->from.ms.map);
679817 }
680818
681819 static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
682820 size_t size, unsigned int width)
683821 {
684822 if (he->branch_info)
685
- return _hist_entry__dso_snprintf(he->branch_info->from.map,
823
+ return _hist_entry__dso_snprintf(he->branch_info->from.ms.map,
686824 bf, size, width);
687825 else
688826 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
....@@ -696,8 +834,8 @@
696834 if (type != HIST_FILTER__DSO)
697835 return -1;
698836
699
- return dso && (!he->branch_info || !he->branch_info->from.map ||
700
- he->branch_info->from.map->dso != dso);
837
+ return dso && (!he->branch_info || !he->branch_info->from.ms.map ||
838
+ he->branch_info->from.ms.map->dso != dso);
701839 }
702840
703841 static int64_t
....@@ -706,15 +844,15 @@
706844 if (!left->branch_info || !right->branch_info)
707845 return cmp_null(left->branch_info, right->branch_info);
708846
709
- return _sort__dso_cmp(left->branch_info->to.map,
710
- right->branch_info->to.map);
847
+ return _sort__dso_cmp(left->branch_info->to.ms.map,
848
+ right->branch_info->to.ms.map);
711849 }
712850
713851 static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
714852 size_t size, unsigned int width)
715853 {
716854 if (he->branch_info)
717
- return _hist_entry__dso_snprintf(he->branch_info->to.map,
855
+ return _hist_entry__dso_snprintf(he->branch_info->to.ms.map,
718856 bf, size, width);
719857 else
720858 return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
....@@ -728,15 +866,14 @@
728866 if (type != HIST_FILTER__DSO)
729867 return -1;
730868
731
- return dso && (!he->branch_info || !he->branch_info->to.map ||
732
- he->branch_info->to.map->dso != dso);
869
+ return dso && (!he->branch_info || !he->branch_info->to.ms.map ||
870
+ he->branch_info->to.ms.map->dso != dso);
733871 }
734872
735873 static int64_t
736874 sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
737875 {
738
- struct addr_map_symbol *from_l = &left->branch_info->from;
739
- struct addr_map_symbol *from_r = &right->branch_info->from;
876
+ struct addr_map_symbol *from_l, *from_r;
740877
741878 if (!left->branch_info || !right->branch_info)
742879 return cmp_null(left->branch_info, right->branch_info);
....@@ -744,10 +881,10 @@
744881 from_l = &left->branch_info->from;
745882 from_r = &right->branch_info->from;
746883
747
- if (!from_l->sym && !from_r->sym)
884
+ if (!from_l->ms.sym && !from_r->ms.sym)
748885 return _sort__addr_cmp(from_l->addr, from_r->addr);
749886
750
- return _sort__sym_cmp(from_l->sym, from_r->sym);
887
+ return _sort__sym_cmp(from_l->ms.sym, from_r->ms.sym);
751888 }
752889
753890 static int64_t
....@@ -761,10 +898,10 @@
761898 to_l = &left->branch_info->to;
762899 to_r = &right->branch_info->to;
763900
764
- if (!to_l->sym && !to_r->sym)
901
+ if (!to_l->ms.sym && !to_r->ms.sym)
765902 return _sort__addr_cmp(to_l->addr, to_r->addr);
766903
767
- return _sort__sym_cmp(to_l->sym, to_r->sym);
904
+ return _sort__sym_cmp(to_l->ms.sym, to_r->ms.sym);
768905 }
769906
770907 static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
....@@ -773,7 +910,7 @@
773910 if (he->branch_info) {
774911 struct addr_map_symbol *from = &he->branch_info->from;
775912
776
- return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
913
+ return _hist_entry__sym_snprintf(&from->ms, from->al_addr,
777914 he->level, bf, size, width);
778915 }
779916
....@@ -786,7 +923,7 @@
786923 if (he->branch_info) {
787924 struct addr_map_symbol *to = &he->branch_info->to;
788925
789
- return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
926
+ return _hist_entry__sym_snprintf(&to->ms, to->al_addr,
790927 he->level, bf, size, width);
791928 }
792929
....@@ -801,8 +938,8 @@
801938 if (type != HIST_FILTER__SYMBOL)
802939 return -1;
803940
804
- return sym && !(he->branch_info && he->branch_info->from.sym &&
805
- strstr(he->branch_info->from.sym->name, sym));
941
+ return sym && !(he->branch_info && he->branch_info->from.ms.sym &&
942
+ strstr(he->branch_info->from.ms.sym->name, sym));
806943 }
807944
808945 static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
....@@ -813,8 +950,8 @@
813950 if (type != HIST_FILTER__SYMBOL)
814951 return -1;
815952
816
- return sym && !(he->branch_info && he->branch_info->to.sym &&
817
- strstr(he->branch_info->to.sym->name, sym));
953
+ return sym && !(he->branch_info && he->branch_info->to.ms.sym &&
954
+ strstr(he->branch_info->to.ms.sym->name, sym));
818955 }
819956
820957 struct sort_entry sort_dso_from = {
....@@ -922,16 +1059,13 @@
9221059 size_t size, unsigned int width)
9231060 {
9241061 uint64_t addr = 0;
925
- struct map *map = NULL;
926
- struct symbol *sym = NULL;
1062
+ struct map_symbol *ms = NULL;
9271063
9281064 if (he->mem_info) {
9291065 addr = he->mem_info->daddr.addr;
930
- map = he->mem_info->daddr.map;
931
- sym = he->mem_info->daddr.sym;
1066
+ ms = &he->mem_info->daddr.ms;
9321067 }
933
- return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
934
- width);
1068
+ return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
9351069 }
9361070
9371071 int64_t
....@@ -951,16 +1085,13 @@
9511085 size_t size, unsigned int width)
9521086 {
9531087 uint64_t addr = 0;
954
- struct map *map = NULL;
955
- struct symbol *sym = NULL;
1088
+ struct map_symbol *ms = NULL;
9561089
9571090 if (he->mem_info) {
9581091 addr = he->mem_info->iaddr.addr;
959
- map = he->mem_info->iaddr.map;
960
- sym = he->mem_info->iaddr.sym;
1092
+ ms = &he->mem_info->iaddr.ms;
9611093 }
962
- return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
963
- width);
1094
+ return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
9641095 }
9651096
9661097 static int64_t
....@@ -970,9 +1101,9 @@
9701101 struct map *map_r = NULL;
9711102
9721103 if (left->mem_info)
973
- map_l = left->mem_info->daddr.map;
1104
+ map_l = left->mem_info->daddr.ms.map;
9741105 if (right->mem_info)
975
- map_r = right->mem_info->daddr.map;
1106
+ map_r = right->mem_info->daddr.ms.map;
9761107
9771108 return _sort__dso_cmp(map_l, map_r);
9781109 }
....@@ -983,7 +1114,7 @@
9831114 struct map *map = NULL;
9841115
9851116 if (he->mem_info)
986
- map = he->mem_info->daddr.map;
1117
+ map = he->mem_info->daddr.ms.map;
9871118
9881119 return _hist_entry__dso_snprintf(map, bf, size, width);
9891120 }
....@@ -1105,6 +1236,7 @@
11051236 {
11061237 u64 l, r;
11071238 struct map *l_map, *r_map;
1239
+ int rc;
11081240
11091241 if (!left->mem_info) return -1;
11101242 if (!right->mem_info) return 1;
....@@ -1113,8 +1245,8 @@
11131245 if (left->cpumode > right->cpumode) return -1;
11141246 if (left->cpumode < right->cpumode) return 1;
11151247
1116
- l_map = left->mem_info->daddr.map;
1117
- r_map = right->mem_info->daddr.map;
1248
+ l_map = left->mem_info->daddr.ms.map;
1249
+ r_map = right->mem_info->daddr.ms.map;
11181250
11191251 /* if both are NULL, jump to sort on al_addr instead */
11201252 if (!l_map && !r_map)
....@@ -1123,18 +1255,9 @@
11231255 if (!l_map) return -1;
11241256 if (!r_map) return 1;
11251257
1126
- if (l_map->maj > r_map->maj) return -1;
1127
- if (l_map->maj < r_map->maj) return 1;
1128
-
1129
- if (l_map->min > r_map->min) return -1;
1130
- if (l_map->min < r_map->min) return 1;
1131
-
1132
- if (l_map->ino > r_map->ino) return -1;
1133
- if (l_map->ino < r_map->ino) return 1;
1134
-
1135
- if (l_map->ino_generation > r_map->ino_generation) return -1;
1136
- if (l_map->ino_generation < r_map->ino_generation) return 1;
1137
-
1258
+ rc = dso__cmp_id(l_map->dso, r_map->dso);
1259
+ if (rc)
1260
+ return rc;
11381261 /*
11391262 * Addresses with no major/minor numbers are assumed to be
11401263 * anonymous in userspace. Sort those on pid then address.
....@@ -1145,8 +1268,8 @@
11451268
11461269 if ((left->cpumode != PERF_RECORD_MISC_KERNEL) &&
11471270 (!(l_map->flags & MAP_SHARED)) &&
1148
- !l_map->maj && !l_map->min && !l_map->ino &&
1149
- !l_map->ino_generation) {
1271
+ !l_map->dso->id.maj && !l_map->dso->id.min &&
1272
+ !l_map->dso->id.ino && !l_map->dso->id.ino_generation) {
11501273 /* userspace anonymous */
11511274
11521275 if (left->thread->pid_ > right->thread->pid_) return -1;
....@@ -1169,27 +1292,26 @@
11691292 {
11701293
11711294 uint64_t addr = 0;
1172
- struct map *map = NULL;
1173
- struct symbol *sym = NULL;
1295
+ struct map_symbol *ms = NULL;
11741296 char level = he->level;
11751297
11761298 if (he->mem_info) {
1299
+ struct map *map = he->mem_info->daddr.ms.map;
1300
+
11771301 addr = cl_address(he->mem_info->daddr.al_addr);
1178
- map = he->mem_info->daddr.map;
1179
- sym = he->mem_info->daddr.sym;
1302
+ ms = &he->mem_info->daddr.ms;
11801303
11811304 /* print [s] for shared data mmaps */
11821305 if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
11831306 map && !(map->prot & PROT_EXEC) &&
11841307 (map->flags & MAP_SHARED) &&
1185
- (map->maj || map->min || map->ino ||
1186
- map->ino_generation))
1308
+ (map->dso->id.maj || map->dso->id.min ||
1309
+ map->dso->id.ino || map->dso->id.ino_generation))
11871310 level = 's';
11881311 else if (!map)
11891312 level = 'X';
11901313 }
1191
- return _hist_entry__sym_snprintf(map, sym, addr, level, bf, size,
1192
- width);
1314
+ return _hist_entry__sym_snprintf(ms, addr, level, bf, size, width);
11931315 }
11941316
11951317 struct sort_entry sort_mispredict = {
....@@ -1579,7 +1701,10 @@
15791701 DIM(SORT_TRACE, "trace", sort_trace),
15801702 DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size),
15811703 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size),
1704
+ DIM(SORT_CGROUP, "cgroup", sort_cgroup),
15821705 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
1706
+ DIM(SORT_SYM_IPC_NULL, "ipc_null", sort_sym_ipc_null),
1707
+ DIM(SORT_TIME, "time", sort_time),
15831708 };
15841709
15851710 #undef DIM
....@@ -1597,6 +1722,7 @@
15971722 DIM(SORT_CYCLES, "cycles", sort_cycles),
15981723 DIM(SORT_SRCLINE_FROM, "srcline_from", sort_srcline_from),
15991724 DIM(SORT_SRCLINE_TO, "srcline_to", sort_srcline_to),
1725
+ DIM(SORT_SYM_IPC, "ipc_lbr", sort_sym_ipc),
16001726 };
16011727
16021728 #undef DIM
....@@ -1889,8 +2015,8 @@
18892015
18902016 struct hpp_dynamic_entry {
18912017 struct perf_hpp_fmt hpp;
1892
- struct perf_evsel *evsel;
1893
- struct format_field *field;
2018
+ struct evsel *evsel;
2019
+ struct tep_format_field *field;
18942020 unsigned dynamic_len;
18952021 bool raw_trace;
18962022 };
....@@ -1905,7 +2031,7 @@
19052031 if (namelen > len)
19062032 len = namelen;
19072033
1908
- if (!(hde->field->flags & FIELD_IS_STRING)) {
2034
+ if (!(hde->field->flags & TEP_FIELD_IS_STRING)) {
19092035 /* length for print hex numbers */
19102036 fieldlen = hde->field->size * 2 + 2;
19112037 }
....@@ -1921,7 +2047,7 @@
19212047 struct hist_entry *he)
19222048 {
19232049 char *str, *pos;
1924
- struct format_field *field = hde->field;
2050
+ struct tep_format_field *field = hde->field;
19252051 size_t namelen;
19262052 bool last = false;
19272053
....@@ -2006,7 +2132,7 @@
20062132 struct hpp_dynamic_entry *hde;
20072133 size_t len = fmt->user_len;
20082134 char *str, *pos;
2009
- struct format_field *field;
2135
+ struct tep_format_field *field;
20102136 size_t namelen;
20112137 bool last = false;
20122138 int ret;
....@@ -2066,7 +2192,7 @@
20662192 struct hist_entry *a, struct hist_entry *b)
20672193 {
20682194 struct hpp_dynamic_entry *hde;
2069
- struct format_field *field;
2195
+ struct tep_format_field *field;
20702196 unsigned offset, size;
20712197
20722198 hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
....@@ -2077,7 +2203,7 @@
20772203 }
20782204
20792205 field = hde->field;
2080
- if (field->flags & FIELD_IS_DYNAMIC) {
2206
+ if (field->flags & TEP_FIELD_IS_DYNAMIC) {
20812207 unsigned long long dyn;
20822208
20832209 tep_read_number_field(field, a->raw_data, &dyn);
....@@ -2123,7 +2249,7 @@
21232249 }
21242250
21252251 static struct hpp_dynamic_entry *
2126
-__alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field,
2252
+__alloc_dynamic_entry(struct evsel *evsel, struct tep_format_field *field,
21272253 int level)
21282254 {
21292255 struct hpp_dynamic_entry *hde;
....@@ -2218,22 +2344,22 @@
22182344 * 2. full event name (e.g. sched:sched_switch)
22192345 * 3. partial event name (should not contain ':')
22202346 */
2221
-static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_name)
2347
+static struct evsel *find_evsel(struct evlist *evlist, char *event_name)
22222348 {
2223
- struct perf_evsel *evsel = NULL;
2224
- struct perf_evsel *pos;
2349
+ struct evsel *evsel = NULL;
2350
+ struct evsel *pos;
22252351 bool full_name;
22262352
22272353 /* case 1 */
22282354 if (event_name[0] == '%') {
22292355 int nr = strtol(event_name+1, NULL, 0);
22302356
2231
- if (nr > evlist->nr_entries)
2357
+ if (nr > evlist->core.nr_entries)
22322358 return NULL;
22332359
2234
- evsel = perf_evlist__first(evlist);
2360
+ evsel = evlist__first(evlist);
22352361 while (--nr > 0)
2236
- evsel = perf_evsel__next(evsel);
2362
+ evsel = evsel__next(evsel);
22372363
22382364 return evsel;
22392365 }
....@@ -2257,8 +2383,8 @@
22572383 return evsel;
22582384 }
22592385
2260
-static int __dynamic_dimension__add(struct perf_evsel *evsel,
2261
- struct format_field *field,
2386
+static int __dynamic_dimension__add(struct evsel *evsel,
2387
+ struct tep_format_field *field,
22622388 bool raw_trace, int level)
22632389 {
22642390 struct hpp_dynamic_entry *hde;
....@@ -2273,10 +2399,10 @@
22732399 return 0;
22742400 }
22752401
2276
-static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace, int level)
2402
+static int add_evsel_fields(struct evsel *evsel, bool raw_trace, int level)
22772403 {
22782404 int ret;
2279
- struct format_field *field;
2405
+ struct tep_format_field *field;
22802406
22812407 field = evsel->tp_format->format.fields;
22822408 while (field) {
....@@ -2289,14 +2415,14 @@
22892415 return 0;
22902416 }
22912417
2292
-static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace,
2418
+static int add_all_dynamic_fields(struct evlist *evlist, bool raw_trace,
22932419 int level)
22942420 {
22952421 int ret;
2296
- struct perf_evsel *evsel;
2422
+ struct evsel *evsel;
22972423
22982424 evlist__for_each_entry(evlist, evsel) {
2299
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2425
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
23002426 continue;
23012427
23022428 ret = add_evsel_fields(evsel, raw_trace, level);
....@@ -2306,15 +2432,15 @@
23062432 return 0;
23072433 }
23082434
2309
-static int add_all_matching_fields(struct perf_evlist *evlist,
2435
+static int add_all_matching_fields(struct evlist *evlist,
23102436 char *field_name, bool raw_trace, int level)
23112437 {
23122438 int ret = -ESRCH;
2313
- struct perf_evsel *evsel;
2314
- struct format_field *field;
2439
+ struct evsel *evsel;
2440
+ struct tep_format_field *field;
23152441
23162442 evlist__for_each_entry(evlist, evsel) {
2317
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2443
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
23182444 continue;
23192445
23202446 field = tep_find_any_field(evsel->tp_format, field_name);
....@@ -2328,12 +2454,12 @@
23282454 return ret;
23292455 }
23302456
2331
-static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok,
2457
+static int add_dynamic_entry(struct evlist *evlist, const char *tok,
23322458 int level)
23332459 {
23342460 char *str, *event_name, *field_name, *opt_name;
2335
- struct perf_evsel *evsel;
2336
- struct format_field *field;
2461
+ struct evsel *evsel;
2462
+ struct tep_format_field *field;
23372463 bool raw_trace = symbol_conf.raw_trace;
23382464 int ret = 0;
23392465
....@@ -2375,7 +2501,7 @@
23752501 goto out;
23762502 }
23772503
2378
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2504
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
23792505 pr_debug("%s is not a tracepoint event\n", event_name);
23802506 ret = -EINVAL;
23812507 goto out;
....@@ -2472,7 +2598,7 @@
24722598 }
24732599
24742600 int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
2475
- struct perf_evlist *evlist,
2601
+ struct evlist *evlist,
24762602 int level)
24772603 {
24782604 unsigned int i;
....@@ -2568,7 +2694,7 @@
25682694 }
25692695
25702696 static int setup_sort_list(struct perf_hpp_list *list, char *str,
2571
- struct perf_evlist *evlist)
2697
+ struct evlist *evlist)
25722698 {
25732699 char *tmp, *tok;
25742700 int ret = 0;
....@@ -2598,12 +2724,12 @@
25982724 ret = sort_dimension__add(list, tok, evlist, level);
25992725 if (ret == -EINVAL) {
26002726 if (!cacheline_size() && !strncasecmp(tok, "dcacheline", strlen(tok)))
2601
- pr_err("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system");
2727
+ ui__error("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system");
26022728 else
2603
- pr_err("Invalid --sort key: `%s'", tok);
2729
+ ui__error("Invalid --sort key: `%s'", tok);
26042730 break;
26052731 } else if (ret == -ESRCH) {
2606
- pr_err("Unknown --sort key: `%s'", tok);
2732
+ ui__error("Unknown --sort key: `%s'", tok);
26072733 break;
26082734 }
26092735 }
....@@ -2614,7 +2740,7 @@
26142740 return ret;
26152741 }
26162742
2617
-static const char *get_default_sort_order(struct perf_evlist *evlist)
2743
+static const char *get_default_sort_order(struct evlist *evlist)
26182744 {
26192745 const char *default_sort_orders[] = {
26202746 default_sort_order,
....@@ -2625,7 +2751,7 @@
26252751 default_tracepoint_sort_order,
26262752 };
26272753 bool use_trace = true;
2628
- struct perf_evsel *evsel;
2754
+ struct evsel *evsel;
26292755
26302756 BUG_ON(sort__mode >= ARRAY_SIZE(default_sort_orders));
26312757
....@@ -2633,7 +2759,7 @@
26332759 goto out_no_evlist;
26342760
26352761 evlist__for_each_entry(evlist, evsel) {
2636
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2762
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
26372763 use_trace = false;
26382764 break;
26392765 }
....@@ -2648,7 +2774,7 @@
26482774 return default_sort_orders[sort__mode];
26492775 }
26502776
2651
-static int setup_sort_order(struct perf_evlist *evlist)
2777
+static int setup_sort_order(struct evlist *evlist)
26522778 {
26532779 char *new_sort_order;
26542780
....@@ -2660,7 +2786,7 @@
26602786 return 0;
26612787
26622788 if (sort_order[1] == '\0') {
2663
- pr_err("Invalid --sort key: `+'");
2789
+ ui__error("Invalid --sort key: `+'");
26642790 return -EINVAL;
26652791 }
26662792
....@@ -2709,7 +2835,7 @@
27092835 return keys;
27102836 }
27112837
2712
-static int __setup_sorting(struct perf_evlist *evlist)
2838
+static int __setup_sorting(struct evlist *evlist)
27132839 {
27142840 char *str;
27152841 const char *sort_keys;
....@@ -2876,6 +3002,9 @@
28763002 if (strncasecmp(tok, sd->name, strlen(tok)))
28773003 continue;
28783004
3005
+ if (sort__mode != SORT_MODE__BRANCH)
3006
+ return -EINVAL;
3007
+
28793008 return __sort_dimension__add_output(list, sd);
28803009 }
28813010
....@@ -2884,6 +3013,9 @@
28843013
28853014 if (strncasecmp(tok, sd->name, strlen(tok)))
28863015 continue;
3016
+
3017
+ if (sort__mode != SORT_MODE__MEMORY)
3018
+ return -EINVAL;
28873019
28883020 return __sort_dimension__add_output(list, sd);
28893021 }
....@@ -2951,7 +3083,7 @@
29513083 strp++;
29523084
29533085 if (!strlen(strp)) {
2954
- pr_err("Invalid --fields key: `+'");
3086
+ ui__error("Invalid --fields key: `+'");
29553087 goto out;
29563088 }
29573089
....@@ -2962,7 +3094,7 @@
29623094 return ret;
29633095 }
29643096
2965
-int setup_sorting(struct perf_evlist *evlist)
3097
+int setup_sorting(struct evlist *evlist)
29663098 {
29673099 int err;
29683100
....@@ -3013,3 +3145,54 @@
30133145 reset_dimensions();
30143146 perf_hpp__reset_output_field(&perf_hpp_list);
30153147 }
3148
+
3149
+#define INDENT (3*8 + 1)
3150
+
3151
+static void add_key(struct strbuf *sb, const char *str, int *llen)
3152
+{
3153
+ if (*llen >= 75) {
3154
+ strbuf_addstr(sb, "\n\t\t\t ");
3155
+ *llen = INDENT;
3156
+ }
3157
+ strbuf_addf(sb, " %s", str);
3158
+ *llen += strlen(str) + 1;
3159
+}
3160
+
3161
+static void add_sort_string(struct strbuf *sb, struct sort_dimension *s, int n,
3162
+ int *llen)
3163
+{
3164
+ int i;
3165
+
3166
+ for (i = 0; i < n; i++)
3167
+ add_key(sb, s[i].name, llen);
3168
+}
3169
+
3170
+static void add_hpp_sort_string(struct strbuf *sb, struct hpp_dimension *s, int n,
3171
+ int *llen)
3172
+{
3173
+ int i;
3174
+
3175
+ for (i = 0; i < n; i++)
3176
+ add_key(sb, s[i].name, llen);
3177
+}
3178
+
3179
+char *sort_help(const char *prefix)
3180
+{
3181
+ struct strbuf sb;
3182
+ char *s;
3183
+ int len = strlen(prefix) + INDENT;
3184
+
3185
+ strbuf_init(&sb, 300);
3186
+ strbuf_addstr(&sb, prefix);
3187
+ add_hpp_sort_string(&sb, hpp_sort_dimensions,
3188
+ ARRAY_SIZE(hpp_sort_dimensions), &len);
3189
+ add_sort_string(&sb, common_sort_dimensions,
3190
+ ARRAY_SIZE(common_sort_dimensions), &len);
3191
+ add_sort_string(&sb, bstack_sort_dimensions,
3192
+ ARRAY_SIZE(bstack_sort_dimensions), &len);
3193
+ add_sort_string(&sb, memory_sort_dimensions,
3194
+ ARRAY_SIZE(memory_sort_dimensions), &len);
3195
+ s = strbuf_detach(&sb, NULL);
3196
+ strbuf_release(&sb);
3197
+ return s;
3198
+}