hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
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,8 +866,8 @@
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
....@@ -744,10 +882,10 @@
744882 from_l = &left->branch_info->from;
745883 from_r = &right->branch_info->from;
746884
747
- if (!from_l->sym && !from_r->sym)
885
+ if (!from_l->ms.sym && !from_r->ms.sym)
748886 return _sort__addr_cmp(from_l->addr, from_r->addr);
749887
750
- return _sort__sym_cmp(from_l->sym, from_r->sym);
888
+ return _sort__sym_cmp(from_l->ms.sym, from_r->ms.sym);
751889 }
752890
753891 static int64_t
....@@ -761,10 +899,10 @@
761899 to_l = &left->branch_info->to;
762900 to_r = &right->branch_info->to;
763901
764
- if (!to_l->sym && !to_r->sym)
902
+ if (!to_l->ms.sym && !to_r->ms.sym)
765903 return _sort__addr_cmp(to_l->addr, to_r->addr);
766904
767
- return _sort__sym_cmp(to_l->sym, to_r->sym);
905
+ return _sort__sym_cmp(to_l->ms.sym, to_r->ms.sym);
768906 }
769907
770908 static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
....@@ -773,7 +911,7 @@
773911 if (he->branch_info) {
774912 struct addr_map_symbol *from = &he->branch_info->from;
775913
776
- return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
914
+ return _hist_entry__sym_snprintf(&from->ms, from->al_addr,
777915 he->level, bf, size, width);
778916 }
779917
....@@ -786,7 +924,7 @@
786924 if (he->branch_info) {
787925 struct addr_map_symbol *to = &he->branch_info->to;
788926
789
- return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
927
+ return _hist_entry__sym_snprintf(&to->ms, to->al_addr,
790928 he->level, bf, size, width);
791929 }
792930
....@@ -801,8 +939,8 @@
801939 if (type != HIST_FILTER__SYMBOL)
802940 return -1;
803941
804
- return sym && !(he->branch_info && he->branch_info->from.sym &&
805
- strstr(he->branch_info->from.sym->name, sym));
942
+ return sym && !(he->branch_info && he->branch_info->from.ms.sym &&
943
+ strstr(he->branch_info->from.ms.sym->name, sym));
806944 }
807945
808946 static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
....@@ -813,8 +951,8 @@
813951 if (type != HIST_FILTER__SYMBOL)
814952 return -1;
815953
816
- return sym && !(he->branch_info && he->branch_info->to.sym &&
817
- strstr(he->branch_info->to.sym->name, sym));
954
+ return sym && !(he->branch_info && he->branch_info->to.ms.sym &&
955
+ strstr(he->branch_info->to.ms.sym->name, sym));
818956 }
819957
820958 struct sort_entry sort_dso_from = {
....@@ -922,16 +1060,13 @@
9221060 size_t size, unsigned int width)
9231061 {
9241062 uint64_t addr = 0;
925
- struct map *map = NULL;
926
- struct symbol *sym = NULL;
1063
+ struct map_symbol *ms = NULL;
9271064
9281065 if (he->mem_info) {
9291066 addr = he->mem_info->daddr.addr;
930
- map = he->mem_info->daddr.map;
931
- sym = he->mem_info->daddr.sym;
1067
+ ms = &he->mem_info->daddr.ms;
9321068 }
933
- return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
934
- width);
1069
+ return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
9351070 }
9361071
9371072 int64_t
....@@ -951,16 +1086,13 @@
9511086 size_t size, unsigned int width)
9521087 {
9531088 uint64_t addr = 0;
954
- struct map *map = NULL;
955
- struct symbol *sym = NULL;
1089
+ struct map_symbol *ms = NULL;
9561090
9571091 if (he->mem_info) {
9581092 addr = he->mem_info->iaddr.addr;
959
- map = he->mem_info->iaddr.map;
960
- sym = he->mem_info->iaddr.sym;
1093
+ ms = &he->mem_info->iaddr.ms;
9611094 }
962
- return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
963
- width);
1095
+ return _hist_entry__sym_snprintf(ms, addr, he->level, bf, size, width);
9641096 }
9651097
9661098 static int64_t
....@@ -970,9 +1102,9 @@
9701102 struct map *map_r = NULL;
9711103
9721104 if (left->mem_info)
973
- map_l = left->mem_info->daddr.map;
1105
+ map_l = left->mem_info->daddr.ms.map;
9741106 if (right->mem_info)
975
- map_r = right->mem_info->daddr.map;
1107
+ map_r = right->mem_info->daddr.ms.map;
9761108
9771109 return _sort__dso_cmp(map_l, map_r);
9781110 }
....@@ -983,7 +1115,7 @@
9831115 struct map *map = NULL;
9841116
9851117 if (he->mem_info)
986
- map = he->mem_info->daddr.map;
1118
+ map = he->mem_info->daddr.ms.map;
9871119
9881120 return _hist_entry__dso_snprintf(map, bf, size, width);
9891121 }
....@@ -1105,6 +1237,7 @@
11051237 {
11061238 u64 l, r;
11071239 struct map *l_map, *r_map;
1240
+ int rc;
11081241
11091242 if (!left->mem_info) return -1;
11101243 if (!right->mem_info) return 1;
....@@ -1113,8 +1246,8 @@
11131246 if (left->cpumode > right->cpumode) return -1;
11141247 if (left->cpumode < right->cpumode) return 1;
11151248
1116
- l_map = left->mem_info->daddr.map;
1117
- r_map = right->mem_info->daddr.map;
1249
+ l_map = left->mem_info->daddr.ms.map;
1250
+ r_map = right->mem_info->daddr.ms.map;
11181251
11191252 /* if both are NULL, jump to sort on al_addr instead */
11201253 if (!l_map && !r_map)
....@@ -1123,18 +1256,9 @@
11231256 if (!l_map) return -1;
11241257 if (!r_map) return 1;
11251258
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
-
1259
+ rc = dso__cmp_id(l_map->dso, r_map->dso);
1260
+ if (rc)
1261
+ return rc;
11381262 /*
11391263 * Addresses with no major/minor numbers are assumed to be
11401264 * anonymous in userspace. Sort those on pid then address.
....@@ -1145,8 +1269,8 @@
11451269
11461270 if ((left->cpumode != PERF_RECORD_MISC_KERNEL) &&
11471271 (!(l_map->flags & MAP_SHARED)) &&
1148
- !l_map->maj && !l_map->min && !l_map->ino &&
1149
- !l_map->ino_generation) {
1272
+ !l_map->dso->id.maj && !l_map->dso->id.min &&
1273
+ !l_map->dso->id.ino && !l_map->dso->id.ino_generation) {
11501274 /* userspace anonymous */
11511275
11521276 if (left->thread->pid_ > right->thread->pid_) return -1;
....@@ -1169,27 +1293,26 @@
11691293 {
11701294
11711295 uint64_t addr = 0;
1172
- struct map *map = NULL;
1173
- struct symbol *sym = NULL;
1296
+ struct map_symbol *ms = NULL;
11741297 char level = he->level;
11751298
11761299 if (he->mem_info) {
1300
+ struct map *map = he->mem_info->daddr.ms.map;
1301
+
11771302 addr = cl_address(he->mem_info->daddr.al_addr);
1178
- map = he->mem_info->daddr.map;
1179
- sym = he->mem_info->daddr.sym;
1303
+ ms = &he->mem_info->daddr.ms;
11801304
11811305 /* print [s] for shared data mmaps */
11821306 if ((he->cpumode != PERF_RECORD_MISC_KERNEL) &&
11831307 map && !(map->prot & PROT_EXEC) &&
11841308 (map->flags & MAP_SHARED) &&
1185
- (map->maj || map->min || map->ino ||
1186
- map->ino_generation))
1309
+ (map->dso->id.maj || map->dso->id.min ||
1310
+ map->dso->id.ino || map->dso->id.ino_generation))
11871311 level = 's';
11881312 else if (!map)
11891313 level = 'X';
11901314 }
1191
- return _hist_entry__sym_snprintf(map, sym, addr, level, bf, size,
1192
- width);
1315
+ return _hist_entry__sym_snprintf(ms, addr, level, bf, size, width);
11931316 }
11941317
11951318 struct sort_entry sort_mispredict = {
....@@ -1579,7 +1702,10 @@
15791702 DIM(SORT_TRACE, "trace", sort_trace),
15801703 DIM(SORT_SYM_SIZE, "symbol_size", sort_sym_size),
15811704 DIM(SORT_DSO_SIZE, "dso_size", sort_dso_size),
1705
+ DIM(SORT_CGROUP, "cgroup", sort_cgroup),
15821706 DIM(SORT_CGROUP_ID, "cgroup_id", sort_cgroup_id),
1707
+ DIM(SORT_SYM_IPC_NULL, "ipc_null", sort_sym_ipc_null),
1708
+ DIM(SORT_TIME, "time", sort_time),
15831709 };
15841710
15851711 #undef DIM
....@@ -1597,6 +1723,7 @@
15971723 DIM(SORT_CYCLES, "cycles", sort_cycles),
15981724 DIM(SORT_SRCLINE_FROM, "srcline_from", sort_srcline_from),
15991725 DIM(SORT_SRCLINE_TO, "srcline_to", sort_srcline_to),
1726
+ DIM(SORT_SYM_IPC, "ipc_lbr", sort_sym_ipc),
16001727 };
16011728
16021729 #undef DIM
....@@ -1889,8 +2016,8 @@
18892016
18902017 struct hpp_dynamic_entry {
18912018 struct perf_hpp_fmt hpp;
1892
- struct perf_evsel *evsel;
1893
- struct format_field *field;
2019
+ struct evsel *evsel;
2020
+ struct tep_format_field *field;
18942021 unsigned dynamic_len;
18952022 bool raw_trace;
18962023 };
....@@ -1905,7 +2032,7 @@
19052032 if (namelen > len)
19062033 len = namelen;
19072034
1908
- if (!(hde->field->flags & FIELD_IS_STRING)) {
2035
+ if (!(hde->field->flags & TEP_FIELD_IS_STRING)) {
19092036 /* length for print hex numbers */
19102037 fieldlen = hde->field->size * 2 + 2;
19112038 }
....@@ -1921,7 +2048,7 @@
19212048 struct hist_entry *he)
19222049 {
19232050 char *str, *pos;
1924
- struct format_field *field = hde->field;
2051
+ struct tep_format_field *field = hde->field;
19252052 size_t namelen;
19262053 bool last = false;
19272054
....@@ -2006,7 +2133,7 @@
20062133 struct hpp_dynamic_entry *hde;
20072134 size_t len = fmt->user_len;
20082135 char *str, *pos;
2009
- struct format_field *field;
2136
+ struct tep_format_field *field;
20102137 size_t namelen;
20112138 bool last = false;
20122139 int ret;
....@@ -2066,7 +2193,7 @@
20662193 struct hist_entry *a, struct hist_entry *b)
20672194 {
20682195 struct hpp_dynamic_entry *hde;
2069
- struct format_field *field;
2196
+ struct tep_format_field *field;
20702197 unsigned offset, size;
20712198
20722199 hde = container_of(fmt, struct hpp_dynamic_entry, hpp);
....@@ -2077,7 +2204,7 @@
20772204 }
20782205
20792206 field = hde->field;
2080
- if (field->flags & FIELD_IS_DYNAMIC) {
2207
+ if (field->flags & TEP_FIELD_IS_DYNAMIC) {
20812208 unsigned long long dyn;
20822209
20832210 tep_read_number_field(field, a->raw_data, &dyn);
....@@ -2123,7 +2250,7 @@
21232250 }
21242251
21252252 static struct hpp_dynamic_entry *
2126
-__alloc_dynamic_entry(struct perf_evsel *evsel, struct format_field *field,
2253
+__alloc_dynamic_entry(struct evsel *evsel, struct tep_format_field *field,
21272254 int level)
21282255 {
21292256 struct hpp_dynamic_entry *hde;
....@@ -2218,22 +2345,22 @@
22182345 * 2. full event name (e.g. sched:sched_switch)
22192346 * 3. partial event name (should not contain ':')
22202347 */
2221
-static struct perf_evsel *find_evsel(struct perf_evlist *evlist, char *event_name)
2348
+static struct evsel *find_evsel(struct evlist *evlist, char *event_name)
22222349 {
2223
- struct perf_evsel *evsel = NULL;
2224
- struct perf_evsel *pos;
2350
+ struct evsel *evsel = NULL;
2351
+ struct evsel *pos;
22252352 bool full_name;
22262353
22272354 /* case 1 */
22282355 if (event_name[0] == '%') {
22292356 int nr = strtol(event_name+1, NULL, 0);
22302357
2231
- if (nr > evlist->nr_entries)
2358
+ if (nr > evlist->core.nr_entries)
22322359 return NULL;
22332360
2234
- evsel = perf_evlist__first(evlist);
2361
+ evsel = evlist__first(evlist);
22352362 while (--nr > 0)
2236
- evsel = perf_evsel__next(evsel);
2363
+ evsel = evsel__next(evsel);
22372364
22382365 return evsel;
22392366 }
....@@ -2257,8 +2384,8 @@
22572384 return evsel;
22582385 }
22592386
2260
-static int __dynamic_dimension__add(struct perf_evsel *evsel,
2261
- struct format_field *field,
2387
+static int __dynamic_dimension__add(struct evsel *evsel,
2388
+ struct tep_format_field *field,
22622389 bool raw_trace, int level)
22632390 {
22642391 struct hpp_dynamic_entry *hde;
....@@ -2273,10 +2400,10 @@
22732400 return 0;
22742401 }
22752402
2276
-static int add_evsel_fields(struct perf_evsel *evsel, bool raw_trace, int level)
2403
+static int add_evsel_fields(struct evsel *evsel, bool raw_trace, int level)
22772404 {
22782405 int ret;
2279
- struct format_field *field;
2406
+ struct tep_format_field *field;
22802407
22812408 field = evsel->tp_format->format.fields;
22822409 while (field) {
....@@ -2289,14 +2416,14 @@
22892416 return 0;
22902417 }
22912418
2292
-static int add_all_dynamic_fields(struct perf_evlist *evlist, bool raw_trace,
2419
+static int add_all_dynamic_fields(struct evlist *evlist, bool raw_trace,
22932420 int level)
22942421 {
22952422 int ret;
2296
- struct perf_evsel *evsel;
2423
+ struct evsel *evsel;
22972424
22982425 evlist__for_each_entry(evlist, evsel) {
2299
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2426
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
23002427 continue;
23012428
23022429 ret = add_evsel_fields(evsel, raw_trace, level);
....@@ -2306,15 +2433,15 @@
23062433 return 0;
23072434 }
23082435
2309
-static int add_all_matching_fields(struct perf_evlist *evlist,
2436
+static int add_all_matching_fields(struct evlist *evlist,
23102437 char *field_name, bool raw_trace, int level)
23112438 {
23122439 int ret = -ESRCH;
2313
- struct perf_evsel *evsel;
2314
- struct format_field *field;
2440
+ struct evsel *evsel;
2441
+ struct tep_format_field *field;
23152442
23162443 evlist__for_each_entry(evlist, evsel) {
2317
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT)
2444
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT)
23182445 continue;
23192446
23202447 field = tep_find_any_field(evsel->tp_format, field_name);
....@@ -2328,12 +2455,12 @@
23282455 return ret;
23292456 }
23302457
2331
-static int add_dynamic_entry(struct perf_evlist *evlist, const char *tok,
2458
+static int add_dynamic_entry(struct evlist *evlist, const char *tok,
23322459 int level)
23332460 {
23342461 char *str, *event_name, *field_name, *opt_name;
2335
- struct perf_evsel *evsel;
2336
- struct format_field *field;
2462
+ struct evsel *evsel;
2463
+ struct tep_format_field *field;
23372464 bool raw_trace = symbol_conf.raw_trace;
23382465 int ret = 0;
23392466
....@@ -2375,7 +2502,7 @@
23752502 goto out;
23762503 }
23772504
2378
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2505
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
23792506 pr_debug("%s is not a tracepoint event\n", event_name);
23802507 ret = -EINVAL;
23812508 goto out;
....@@ -2472,7 +2599,7 @@
24722599 }
24732600
24742601 int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
2475
- struct perf_evlist *evlist,
2602
+ struct evlist *evlist,
24762603 int level)
24772604 {
24782605 unsigned int i;
....@@ -2568,7 +2695,7 @@
25682695 }
25692696
25702697 static int setup_sort_list(struct perf_hpp_list *list, char *str,
2571
- struct perf_evlist *evlist)
2698
+ struct evlist *evlist)
25722699 {
25732700 char *tmp, *tok;
25742701 int ret = 0;
....@@ -2598,12 +2725,12 @@
25982725 ret = sort_dimension__add(list, tok, evlist, level);
25992726 if (ret == -EINVAL) {
26002727 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");
2728
+ ui__error("The \"dcacheline\" --sort key needs to know the cacheline size and it couldn't be determined on this system");
26022729 else
2603
- pr_err("Invalid --sort key: `%s'", tok);
2730
+ ui__error("Invalid --sort key: `%s'", tok);
26042731 break;
26052732 } else if (ret == -ESRCH) {
2606
- pr_err("Unknown --sort key: `%s'", tok);
2733
+ ui__error("Unknown --sort key: `%s'", tok);
26072734 break;
26082735 }
26092736 }
....@@ -2614,7 +2741,7 @@
26142741 return ret;
26152742 }
26162743
2617
-static const char *get_default_sort_order(struct perf_evlist *evlist)
2744
+static const char *get_default_sort_order(struct evlist *evlist)
26182745 {
26192746 const char *default_sort_orders[] = {
26202747 default_sort_order,
....@@ -2625,7 +2752,7 @@
26252752 default_tracepoint_sort_order,
26262753 };
26272754 bool use_trace = true;
2628
- struct perf_evsel *evsel;
2755
+ struct evsel *evsel;
26292756
26302757 BUG_ON(sort__mode >= ARRAY_SIZE(default_sort_orders));
26312758
....@@ -2633,7 +2760,7 @@
26332760 goto out_no_evlist;
26342761
26352762 evlist__for_each_entry(evlist, evsel) {
2636
- if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2763
+ if (evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
26372764 use_trace = false;
26382765 break;
26392766 }
....@@ -2648,7 +2775,7 @@
26482775 return default_sort_orders[sort__mode];
26492776 }
26502777
2651
-static int setup_sort_order(struct perf_evlist *evlist)
2778
+static int setup_sort_order(struct evlist *evlist)
26522779 {
26532780 char *new_sort_order;
26542781
....@@ -2660,7 +2787,7 @@
26602787 return 0;
26612788
26622789 if (sort_order[1] == '\0') {
2663
- pr_err("Invalid --sort key: `+'");
2790
+ ui__error("Invalid --sort key: `+'");
26642791 return -EINVAL;
26652792 }
26662793
....@@ -2709,7 +2836,7 @@
27092836 return keys;
27102837 }
27112838
2712
-static int __setup_sorting(struct perf_evlist *evlist)
2839
+static int __setup_sorting(struct evlist *evlist)
27132840 {
27142841 char *str;
27152842 const char *sort_keys;
....@@ -2876,6 +3003,9 @@
28763003 if (strncasecmp(tok, sd->name, strlen(tok)))
28773004 continue;
28783005
3006
+ if (sort__mode != SORT_MODE__BRANCH)
3007
+ return -EINVAL;
3008
+
28793009 return __sort_dimension__add_output(list, sd);
28803010 }
28813011
....@@ -2884,6 +3014,9 @@
28843014
28853015 if (strncasecmp(tok, sd->name, strlen(tok)))
28863016 continue;
3017
+
3018
+ if (sort__mode != SORT_MODE__MEMORY)
3019
+ return -EINVAL;
28873020
28883021 return __sort_dimension__add_output(list, sd);
28893022 }
....@@ -2951,7 +3084,7 @@
29513084 strp++;
29523085
29533086 if (!strlen(strp)) {
2954
- pr_err("Invalid --fields key: `+'");
3087
+ ui__error("Invalid --fields key: `+'");
29553088 goto out;
29563089 }
29573090
....@@ -2962,7 +3095,7 @@
29623095 return ret;
29633096 }
29643097
2965
-int setup_sorting(struct perf_evlist *evlist)
3098
+int setup_sorting(struct evlist *evlist)
29663099 {
29673100 int err;
29683101
....@@ -3013,3 +3146,54 @@
30133146 reset_dimensions();
30143147 perf_hpp__reset_output_field(&perf_hpp_list);
30153148 }
3149
+
3150
+#define INDENT (3*8 + 1)
3151
+
3152
+static void add_key(struct strbuf *sb, const char *str, int *llen)
3153
+{
3154
+ if (*llen >= 75) {
3155
+ strbuf_addstr(sb, "\n\t\t\t ");
3156
+ *llen = INDENT;
3157
+ }
3158
+ strbuf_addf(sb, " %s", str);
3159
+ *llen += strlen(str) + 1;
3160
+}
3161
+
3162
+static void add_sort_string(struct strbuf *sb, struct sort_dimension *s, int n,
3163
+ int *llen)
3164
+{
3165
+ int i;
3166
+
3167
+ for (i = 0; i < n; i++)
3168
+ add_key(sb, s[i].name, llen);
3169
+}
3170
+
3171
+static void add_hpp_sort_string(struct strbuf *sb, struct hpp_dimension *s, int n,
3172
+ int *llen)
3173
+{
3174
+ int i;
3175
+
3176
+ for (i = 0; i < n; i++)
3177
+ add_key(sb, s[i].name, llen);
3178
+}
3179
+
3180
+char *sort_help(const char *prefix)
3181
+{
3182
+ struct strbuf sb;
3183
+ char *s;
3184
+ int len = strlen(prefix) + INDENT;
3185
+
3186
+ strbuf_init(&sb, 300);
3187
+ strbuf_addstr(&sb, prefix);
3188
+ add_hpp_sort_string(&sb, hpp_sort_dimensions,
3189
+ ARRAY_SIZE(hpp_sort_dimensions), &len);
3190
+ add_sort_string(&sb, common_sort_dimensions,
3191
+ ARRAY_SIZE(common_sort_dimensions), &len);
3192
+ add_sort_string(&sb, bstack_sort_dimensions,
3193
+ ARRAY_SIZE(bstack_sort_dimensions), &len);
3194
+ add_sort_string(&sb, memory_sort_dimensions,
3195
+ ARRAY_SIZE(memory_sort_dimensions), &len);
3196
+ s = strbuf_detach(&sb, NULL);
3197
+ strbuf_release(&sb);
3198
+ return s;
3199
+}