builtin-report.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071
  1. /*
  2. * builtin-report.c
  3. *
  4. * Builtin report command: Analyze the perf.data input file,
  5. * look up and read DSOs and symbol information and display
  6. * a histogram of results, along various sorting keys.
  7. */
  8. #include "builtin.h"
  9. #include "util/util.h"
  10. #include "util/color.h"
  11. #include <linux/list.h>
  12. #include "util/cache.h"
  13. #include <linux/rbtree.h>
  14. #include "util/symbol.h"
  15. #include "util/string.h"
  16. #include "util/callchain.h"
  17. #include "util/strlist.h"
  18. #include "perf.h"
  19. #include "util/header.h"
  20. #include "util/parse-options.h"
  21. #include "util/parse-events.h"
  22. #define SHOW_KERNEL 1
  23. #define SHOW_USER 2
  24. #define SHOW_HV 4
  25. static char const *input_name = "perf.data";
  26. static char *vmlinux = NULL;
  27. static char default_sort_order[] = "comm,dso";
  28. static char *sort_order = default_sort_order;
  29. static char *dso_list_str, *comm_list_str, *sym_list_str,
  30. *col_width_list_str;
  31. static struct strlist *dso_list, *comm_list, *sym_list;
  32. static char *field_sep;
  33. static int input;
  34. static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
  35. static int dump_trace = 0;
  36. #define dprintf(x...) do { if (dump_trace) printf(x); } while (0)
  37. #define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
  38. static int verbose;
  39. #define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0)
  40. static int modules;
  41. static int full_paths;
  42. static int show_nr_samples;
  43. static unsigned long page_size;
  44. static unsigned long mmap_window = 32;
  45. static char default_parent_pattern[] = "^sys_|^do_page_fault";
  46. static char *parent_pattern = default_parent_pattern;
  47. static regex_t parent_regex;
  48. static int exclude_other = 1;
  49. static char callchain_default_opt[] = "fractal,0.5";
  50. static int callchain;
  51. static
  52. struct callchain_param callchain_param = {
  53. .mode = CHAIN_GRAPH_ABS,
  54. .min_percent = 0.5
  55. };
  56. static u64 sample_type;
  57. struct ip_event {
  58. struct perf_event_header header;
  59. u64 ip;
  60. u32 pid, tid;
  61. unsigned char __more_data[];
  62. };
  63. struct mmap_event {
  64. struct perf_event_header header;
  65. u32 pid, tid;
  66. u64 start;
  67. u64 len;
  68. u64 pgoff;
  69. char filename[PATH_MAX];
  70. };
  71. struct comm_event {
  72. struct perf_event_header header;
  73. u32 pid, tid;
  74. char comm[16];
  75. };
  76. struct fork_event {
  77. struct perf_event_header header;
  78. u32 pid, ppid;
  79. };
  80. struct lost_event {
  81. struct perf_event_header header;
  82. u64 id;
  83. u64 lost;
  84. };
  85. struct read_event {
  86. struct perf_event_header header;
  87. u32 pid,tid;
  88. u64 value;
  89. u64 format[3];
  90. };
  91. typedef union event_union {
  92. struct perf_event_header header;
  93. struct ip_event ip;
  94. struct mmap_event mmap;
  95. struct comm_event comm;
  96. struct fork_event fork;
  97. struct lost_event lost;
  98. struct read_event read;
  99. } event_t;
  100. static int repsep_fprintf(FILE *fp, const char *fmt, ...)
  101. {
  102. int n;
  103. va_list ap;
  104. va_start(ap, fmt);
  105. if (!field_sep)
  106. n = vfprintf(fp, fmt, ap);
  107. else {
  108. char *bf = NULL;
  109. n = vasprintf(&bf, fmt, ap);
  110. if (n > 0) {
  111. char *sep = bf;
  112. while (1) {
  113. sep = strchr(sep, *field_sep);
  114. if (sep == NULL)
  115. break;
  116. *sep = '.';
  117. }
  118. }
  119. fputs(bf, fp);
  120. free(bf);
  121. }
  122. va_end(ap);
  123. return n;
  124. }
  125. static LIST_HEAD(dsos);
  126. static struct dso *kernel_dso;
  127. static struct dso *vdso;
  128. static struct dso *hypervisor_dso;
  129. static void dsos__add(struct dso *dso)
  130. {
  131. list_add_tail(&dso->node, &dsos);
  132. }
  133. static struct dso *dsos__find(const char *name)
  134. {
  135. struct dso *pos;
  136. list_for_each_entry(pos, &dsos, node)
  137. if (strcmp(pos->name, name) == 0)
  138. return pos;
  139. return NULL;
  140. }
  141. static struct dso *dsos__findnew(const char *name)
  142. {
  143. struct dso *dso = dsos__find(name);
  144. int nr;
  145. if (dso)
  146. return dso;
  147. dso = dso__new(name, 0);
  148. if (!dso)
  149. goto out_delete_dso;
  150. nr = dso__load(dso, NULL, verbose);
  151. if (nr < 0) {
  152. eprintf("Failed to open: %s\n", name);
  153. goto out_delete_dso;
  154. }
  155. if (!nr)
  156. eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
  157. dsos__add(dso);
  158. return dso;
  159. out_delete_dso:
  160. dso__delete(dso);
  161. return NULL;
  162. }
  163. static void dsos__fprintf(FILE *fp)
  164. {
  165. struct dso *pos;
  166. list_for_each_entry(pos, &dsos, node)
  167. dso__fprintf(pos, fp);
  168. }
  169. static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
  170. {
  171. return dso__find_symbol(dso, ip);
  172. }
  173. static int load_kernel(void)
  174. {
  175. int err;
  176. kernel_dso = dso__new("[kernel]", 0);
  177. if (!kernel_dso)
  178. return -1;
  179. err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
  180. if (err <= 0) {
  181. dso__delete(kernel_dso);
  182. kernel_dso = NULL;
  183. } else
  184. dsos__add(kernel_dso);
  185. vdso = dso__new("[vdso]", 0);
  186. if (!vdso)
  187. return -1;
  188. vdso->find_symbol = vdso__find_symbol;
  189. dsos__add(vdso);
  190. hypervisor_dso = dso__new("[hypervisor]", 0);
  191. if (!hypervisor_dso)
  192. return -1;
  193. dsos__add(hypervisor_dso);
  194. return err;
  195. }
  196. static char __cwd[PATH_MAX];
  197. static char *cwd = __cwd;
  198. static int cwdlen;
  199. static int strcommon(const char *pathname)
  200. {
  201. int n = 0;
  202. while (pathname[n] == cwd[n] && n < cwdlen)
  203. ++n;
  204. return n;
  205. }
  206. struct map {
  207. struct list_head node;
  208. u64 start;
  209. u64 end;
  210. u64 pgoff;
  211. u64 (*map_ip)(struct map *, u64);
  212. struct dso *dso;
  213. };
  214. static u64 map__map_ip(struct map *map, u64 ip)
  215. {
  216. return ip - map->start + map->pgoff;
  217. }
  218. static u64 vdso__map_ip(struct map *map __used, u64 ip)
  219. {
  220. return ip;
  221. }
  222. static inline int is_anon_memory(const char *filename)
  223. {
  224. return strcmp(filename, "//anon") == 0;
  225. }
  226. static struct map *map__new(struct mmap_event *event)
  227. {
  228. struct map *self = malloc(sizeof(*self));
  229. if (self != NULL) {
  230. const char *filename = event->filename;
  231. char newfilename[PATH_MAX];
  232. int anon;
  233. if (cwd) {
  234. int n = strcommon(filename);
  235. if (n == cwdlen) {
  236. snprintf(newfilename, sizeof(newfilename),
  237. ".%s", filename + n);
  238. filename = newfilename;
  239. }
  240. }
  241. anon = is_anon_memory(filename);
  242. if (anon) {
  243. snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
  244. filename = newfilename;
  245. }
  246. self->start = event->start;
  247. self->end = event->start + event->len;
  248. self->pgoff = event->pgoff;
  249. self->dso = dsos__findnew(filename);
  250. if (self->dso == NULL)
  251. goto out_delete;
  252. if (self->dso == vdso || anon)
  253. self->map_ip = vdso__map_ip;
  254. else
  255. self->map_ip = map__map_ip;
  256. }
  257. return self;
  258. out_delete:
  259. free(self);
  260. return NULL;
  261. }
  262. static struct map *map__clone(struct map *self)
  263. {
  264. struct map *map = malloc(sizeof(*self));
  265. if (!map)
  266. return NULL;
  267. memcpy(map, self, sizeof(*self));
  268. return map;
  269. }
  270. static int map__overlap(struct map *l, struct map *r)
  271. {
  272. if (l->start > r->start) {
  273. struct map *t = l;
  274. l = r;
  275. r = t;
  276. }
  277. if (l->end > r->start)
  278. return 1;
  279. return 0;
  280. }
  281. static size_t map__fprintf(struct map *self, FILE *fp)
  282. {
  283. return fprintf(fp, " %Lx-%Lx %Lx %s\n",
  284. self->start, self->end, self->pgoff, self->dso->name);
  285. }
  286. struct thread {
  287. struct rb_node rb_node;
  288. struct list_head maps;
  289. pid_t pid;
  290. char *comm;
  291. };
  292. static struct thread *thread__new(pid_t pid)
  293. {
  294. struct thread *self = malloc(sizeof(*self));
  295. if (self != NULL) {
  296. self->pid = pid;
  297. self->comm = malloc(32);
  298. if (self->comm)
  299. snprintf(self->comm, 32, ":%d", self->pid);
  300. INIT_LIST_HEAD(&self->maps);
  301. }
  302. return self;
  303. }
  304. static unsigned int dsos__col_width,
  305. comms__col_width,
  306. threads__col_width;
  307. static int thread__set_comm(struct thread *self, const char *comm)
  308. {
  309. if (self->comm)
  310. free(self->comm);
  311. self->comm = strdup(comm);
  312. if (!self->comm)
  313. return -ENOMEM;
  314. if (!col_width_list_str && !field_sep &&
  315. (!comm_list || strlist__has_entry(comm_list, comm))) {
  316. unsigned int slen = strlen(comm);
  317. if (slen > comms__col_width) {
  318. comms__col_width = slen;
  319. threads__col_width = slen + 6;
  320. }
  321. }
  322. return 0;
  323. }
  324. static size_t thread__fprintf(struct thread *self, FILE *fp)
  325. {
  326. struct map *pos;
  327. size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
  328. list_for_each_entry(pos, &self->maps, node)
  329. ret += map__fprintf(pos, fp);
  330. return ret;
  331. }
  332. static struct rb_root threads;
  333. static struct thread *last_match;
  334. static struct thread *threads__findnew(pid_t pid)
  335. {
  336. struct rb_node **p = &threads.rb_node;
  337. struct rb_node *parent = NULL;
  338. struct thread *th;
  339. /*
  340. * Font-end cache - PID lookups come in blocks,
  341. * so most of the time we dont have to look up
  342. * the full rbtree:
  343. */
  344. if (last_match && last_match->pid == pid)
  345. return last_match;
  346. while (*p != NULL) {
  347. parent = *p;
  348. th = rb_entry(parent, struct thread, rb_node);
  349. if (th->pid == pid) {
  350. last_match = th;
  351. return th;
  352. }
  353. if (pid < th->pid)
  354. p = &(*p)->rb_left;
  355. else
  356. p = &(*p)->rb_right;
  357. }
  358. th = thread__new(pid);
  359. if (th != NULL) {
  360. rb_link_node(&th->rb_node, parent, p);
  361. rb_insert_color(&th->rb_node, &threads);
  362. last_match = th;
  363. }
  364. return th;
  365. }
  366. static void thread__insert_map(struct thread *self, struct map *map)
  367. {
  368. struct map *pos, *tmp;
  369. list_for_each_entry_safe(pos, tmp, &self->maps, node) {
  370. if (map__overlap(pos, map)) {
  371. if (verbose >= 2) {
  372. printf("overlapping maps:\n");
  373. map__fprintf(map, stdout);
  374. map__fprintf(pos, stdout);
  375. }
  376. if (map->start <= pos->start && map->end > pos->start)
  377. pos->start = map->end;
  378. if (map->end >= pos->end && map->start < pos->end)
  379. pos->end = map->start;
  380. if (verbose >= 2) {
  381. printf("after collision:\n");
  382. map__fprintf(pos, stdout);
  383. }
  384. if (pos->start >= pos->end) {
  385. list_del_init(&pos->node);
  386. free(pos);
  387. }
  388. }
  389. }
  390. list_add_tail(&map->node, &self->maps);
  391. }
  392. static int thread__fork(struct thread *self, struct thread *parent)
  393. {
  394. struct map *map;
  395. if (self->comm)
  396. free(self->comm);
  397. self->comm = strdup(parent->comm);
  398. if (!self->comm)
  399. return -ENOMEM;
  400. list_for_each_entry(map, &parent->maps, node) {
  401. struct map *new = map__clone(map);
  402. if (!new)
  403. return -ENOMEM;
  404. thread__insert_map(self, new);
  405. }
  406. return 0;
  407. }
  408. static struct map *thread__find_map(struct thread *self, u64 ip)
  409. {
  410. struct map *pos;
  411. if (self == NULL)
  412. return NULL;
  413. list_for_each_entry(pos, &self->maps, node)
  414. if (ip >= pos->start && ip <= pos->end)
  415. return pos;
  416. return NULL;
  417. }
  418. static size_t threads__fprintf(FILE *fp)
  419. {
  420. size_t ret = 0;
  421. struct rb_node *nd;
  422. for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
  423. struct thread *pos = rb_entry(nd, struct thread, rb_node);
  424. ret += thread__fprintf(pos, fp);
  425. }
  426. return ret;
  427. }
  428. /*
  429. * histogram, sorted on item, collects counts
  430. */
  431. static struct rb_root hist;
  432. struct hist_entry {
  433. struct rb_node rb_node;
  434. struct thread *thread;
  435. struct map *map;
  436. struct dso *dso;
  437. struct symbol *sym;
  438. struct symbol *parent;
  439. u64 ip;
  440. char level;
  441. struct callchain_node callchain;
  442. struct rb_root sorted_chain;
  443. u64 count;
  444. };
  445. /*
  446. * configurable sorting bits
  447. */
  448. struct sort_entry {
  449. struct list_head list;
  450. char *header;
  451. int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
  452. int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
  453. size_t (*print)(FILE *fp, struct hist_entry *, unsigned int width);
  454. unsigned int *width;
  455. bool elide;
  456. };
  457. static int64_t cmp_null(void *l, void *r)
  458. {
  459. if (!l && !r)
  460. return 0;
  461. else if (!l)
  462. return -1;
  463. else
  464. return 1;
  465. }
  466. /* --sort pid */
  467. static int64_t
  468. sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
  469. {
  470. return right->thread->pid - left->thread->pid;
  471. }
  472. static size_t
  473. sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
  474. {
  475. return repsep_fprintf(fp, "%*s:%5d", width - 6,
  476. self->thread->comm ?: "", self->thread->pid);
  477. }
  478. static struct sort_entry sort_thread = {
  479. .header = "Command: Pid",
  480. .cmp = sort__thread_cmp,
  481. .print = sort__thread_print,
  482. .width = &threads__col_width,
  483. };
  484. /* --sort comm */
  485. static int64_t
  486. sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
  487. {
  488. return right->thread->pid - left->thread->pid;
  489. }
  490. static int64_t
  491. sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
  492. {
  493. char *comm_l = left->thread->comm;
  494. char *comm_r = right->thread->comm;
  495. if (!comm_l || !comm_r)
  496. return cmp_null(comm_l, comm_r);
  497. return strcmp(comm_l, comm_r);
  498. }
  499. static size_t
  500. sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
  501. {
  502. return repsep_fprintf(fp, "%*s", width, self->thread->comm);
  503. }
  504. static struct sort_entry sort_comm = {
  505. .header = "Command",
  506. .cmp = sort__comm_cmp,
  507. .collapse = sort__comm_collapse,
  508. .print = sort__comm_print,
  509. .width = &comms__col_width,
  510. };
  511. /* --sort dso */
  512. static int64_t
  513. sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
  514. {
  515. struct dso *dso_l = left->dso;
  516. struct dso *dso_r = right->dso;
  517. if (!dso_l || !dso_r)
  518. return cmp_null(dso_l, dso_r);
  519. return strcmp(dso_l->name, dso_r->name);
  520. }
  521. static size_t
  522. sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
  523. {
  524. if (self->dso)
  525. return repsep_fprintf(fp, "%-*s", width, self->dso->name);
  526. return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
  527. }
  528. static struct sort_entry sort_dso = {
  529. .header = "Shared Object",
  530. .cmp = sort__dso_cmp,
  531. .print = sort__dso_print,
  532. .width = &dsos__col_width,
  533. };
  534. /* --sort symbol */
  535. static int64_t
  536. sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
  537. {
  538. u64 ip_l, ip_r;
  539. if (left->sym == right->sym)
  540. return 0;
  541. ip_l = left->sym ? left->sym->start : left->ip;
  542. ip_r = right->sym ? right->sym->start : right->ip;
  543. return (int64_t)(ip_r - ip_l);
  544. }
  545. static size_t
  546. sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
  547. {
  548. size_t ret = 0;
  549. if (verbose)
  550. ret += repsep_fprintf(fp, "%#018llx ", (u64)self->ip);
  551. ret += repsep_fprintf(fp, "[%c] ", self->level);
  552. if (self->sym) {
  553. ret += repsep_fprintf(fp, "%s", self->sym->name);
  554. if (self->sym->module)
  555. ret += repsep_fprintf(fp, "\t[%s]",
  556. self->sym->module->name);
  557. } else {
  558. ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
  559. }
  560. return ret;
  561. }
  562. static struct sort_entry sort_sym = {
  563. .header = "Symbol",
  564. .cmp = sort__sym_cmp,
  565. .print = sort__sym_print,
  566. };
  567. /* --sort parent */
  568. static int64_t
  569. sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
  570. {
  571. struct symbol *sym_l = left->parent;
  572. struct symbol *sym_r = right->parent;
  573. if (!sym_l || !sym_r)
  574. return cmp_null(sym_l, sym_r);
  575. return strcmp(sym_l->name, sym_r->name);
  576. }
  577. static size_t
  578. sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
  579. {
  580. return repsep_fprintf(fp, "%-*s", width,
  581. self->parent ? self->parent->name : "[other]");
  582. }
  583. static unsigned int parent_symbol__col_width;
  584. static struct sort_entry sort_parent = {
  585. .header = "Parent symbol",
  586. .cmp = sort__parent_cmp,
  587. .print = sort__parent_print,
  588. .width = &parent_symbol__col_width,
  589. };
  590. static int sort__need_collapse = 0;
  591. static int sort__has_parent = 0;
  592. struct sort_dimension {
  593. char *name;
  594. struct sort_entry *entry;
  595. int taken;
  596. };
  597. static struct sort_dimension sort_dimensions[] = {
  598. { .name = "pid", .entry = &sort_thread, },
  599. { .name = "comm", .entry = &sort_comm, },
  600. { .name = "dso", .entry = &sort_dso, },
  601. { .name = "symbol", .entry = &sort_sym, },
  602. { .name = "parent", .entry = &sort_parent, },
  603. };
  604. static LIST_HEAD(hist_entry__sort_list);
  605. static int sort_dimension__add(char *tok)
  606. {
  607. unsigned int i;
  608. for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
  609. struct sort_dimension *sd = &sort_dimensions[i];
  610. if (sd->taken)
  611. continue;
  612. if (strncasecmp(tok, sd->name, strlen(tok)))
  613. continue;
  614. if (sd->entry->collapse)
  615. sort__need_collapse = 1;
  616. if (sd->entry == &sort_parent) {
  617. int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
  618. if (ret) {
  619. char err[BUFSIZ];
  620. regerror(ret, &parent_regex, err, sizeof(err));
  621. fprintf(stderr, "Invalid regex: %s\n%s",
  622. parent_pattern, err);
  623. exit(-1);
  624. }
  625. sort__has_parent = 1;
  626. }
  627. list_add_tail(&sd->entry->list, &hist_entry__sort_list);
  628. sd->taken = 1;
  629. return 0;
  630. }
  631. return -ESRCH;
  632. }
  633. static int64_t
  634. hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
  635. {
  636. struct sort_entry *se;
  637. int64_t cmp = 0;
  638. list_for_each_entry(se, &hist_entry__sort_list, list) {
  639. cmp = se->cmp(left, right);
  640. if (cmp)
  641. break;
  642. }
  643. return cmp;
  644. }
  645. static int64_t
  646. hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
  647. {
  648. struct sort_entry *se;
  649. int64_t cmp = 0;
  650. list_for_each_entry(se, &hist_entry__sort_list, list) {
  651. int64_t (*f)(struct hist_entry *, struct hist_entry *);
  652. f = se->collapse ?: se->cmp;
  653. cmp = f(left, right);
  654. if (cmp)
  655. break;
  656. }
  657. return cmp;
  658. }
  659. static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
  660. {
  661. int i;
  662. size_t ret = 0;
  663. ret += fprintf(fp, "%s", " ");
  664. for (i = 0; i < depth; i++)
  665. if (depth_mask & (1 << i))
  666. ret += fprintf(fp, "| ");
  667. else
  668. ret += fprintf(fp, " ");
  669. ret += fprintf(fp, "\n");
  670. return ret;
  671. }
  672. static size_t
  673. ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
  674. int depth_mask, int count, u64 total_samples,
  675. int hits)
  676. {
  677. int i;
  678. size_t ret = 0;
  679. ret += fprintf(fp, "%s", " ");
  680. for (i = 0; i < depth; i++) {
  681. if (depth_mask & (1 << i))
  682. ret += fprintf(fp, "|");
  683. else
  684. ret += fprintf(fp, " ");
  685. if (!count && i == depth - 1) {
  686. double percent;
  687. percent = hits * 100.0 / total_samples;
  688. ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
  689. } else
  690. ret += fprintf(fp, "%s", " ");
  691. }
  692. if (chain->sym)
  693. ret += fprintf(fp, "%s\n", chain->sym->name);
  694. else
  695. ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
  696. return ret;
  697. }
  698. static size_t
  699. callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
  700. u64 total_samples, int depth, int depth_mask)
  701. {
  702. struct rb_node *node, *next;
  703. struct callchain_node *child;
  704. struct callchain_list *chain;
  705. int new_depth_mask = depth_mask;
  706. u64 new_total;
  707. size_t ret = 0;
  708. int i;
  709. if (callchain_param.mode == CHAIN_GRAPH_REL)
  710. new_total = self->cumul_hit;
  711. else
  712. new_total = total_samples;
  713. node = rb_first(&self->rb_root);
  714. while (node) {
  715. child = rb_entry(node, struct callchain_node, rb_node);
  716. /*
  717. * The depth mask manages the output of pipes that show
  718. * the depth. We don't want to keep the pipes of the current
  719. * level for the last child of this depth
  720. */
  721. next = rb_next(node);
  722. if (!next)
  723. new_depth_mask &= ~(1 << (depth - 1));
  724. /*
  725. * But we keep the older depth mask for the line seperator
  726. * to keep the level link until we reach the last child
  727. */
  728. ret += ipchain__fprintf_graph_line(fp, depth, depth_mask);
  729. i = 0;
  730. list_for_each_entry(chain, &child->val, list) {
  731. if (chain->ip >= PERF_CONTEXT_MAX)
  732. continue;
  733. ret += ipchain__fprintf_graph(fp, chain, depth,
  734. new_depth_mask, i++,
  735. new_total,
  736. child->cumul_hit);
  737. }
  738. ret += callchain__fprintf_graph(fp, child, new_total,
  739. depth + 1,
  740. new_depth_mask | (1 << depth));
  741. node = next;
  742. }
  743. return ret;
  744. }
  745. static size_t
  746. callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
  747. u64 total_samples)
  748. {
  749. struct callchain_list *chain;
  750. size_t ret = 0;
  751. if (!self)
  752. return 0;
  753. ret += callchain__fprintf_flat(fp, self->parent, total_samples);
  754. list_for_each_entry(chain, &self->val, list) {
  755. if (chain->ip >= PERF_CONTEXT_MAX)
  756. continue;
  757. if (chain->sym)
  758. ret += fprintf(fp, " %s\n", chain->sym->name);
  759. else
  760. ret += fprintf(fp, " %p\n",
  761. (void *)(long)chain->ip);
  762. }
  763. return ret;
  764. }
  765. static size_t
  766. hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
  767. u64 total_samples)
  768. {
  769. struct rb_node *rb_node;
  770. struct callchain_node *chain;
  771. size_t ret = 0;
  772. rb_node = rb_first(&self->sorted_chain);
  773. while (rb_node) {
  774. double percent;
  775. chain = rb_entry(rb_node, struct callchain_node, rb_node);
  776. percent = chain->hit * 100.0 / total_samples;
  777. switch (callchain_param.mode) {
  778. case CHAIN_FLAT:
  779. ret += percent_color_fprintf(fp, " %6.2f%%\n",
  780. percent);
  781. ret += callchain__fprintf_flat(fp, chain, total_samples);
  782. break;
  783. case CHAIN_GRAPH_ABS: /* Falldown */
  784. case CHAIN_GRAPH_REL:
  785. ret += callchain__fprintf_graph(fp, chain,
  786. total_samples, 1, 1);
  787. default:
  788. break;
  789. }
  790. ret += fprintf(fp, "\n");
  791. rb_node = rb_next(rb_node);
  792. }
  793. return ret;
  794. }
  795. static size_t
  796. hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
  797. {
  798. struct sort_entry *se;
  799. size_t ret;
  800. if (exclude_other && !self->parent)
  801. return 0;
  802. if (total_samples)
  803. ret = percent_color_fprintf(fp,
  804. field_sep ? "%.2f" : " %6.2f%%",
  805. (self->count * 100.0) / total_samples);
  806. else
  807. ret = fprintf(fp, field_sep ? "%lld" : "%12lld ", self->count);
  808. if (show_nr_samples) {
  809. if (field_sep)
  810. fprintf(fp, "%c%lld", *field_sep, self->count);
  811. else
  812. fprintf(fp, "%11lld", self->count);
  813. }
  814. list_for_each_entry(se, &hist_entry__sort_list, list) {
  815. if (se->elide)
  816. continue;
  817. fprintf(fp, "%s", field_sep ?: " ");
  818. ret += se->print(fp, self, se->width ? *se->width : 0);
  819. }
  820. ret += fprintf(fp, "\n");
  821. if (callchain)
  822. hist_entry_callchain__fprintf(fp, self, total_samples);
  823. return ret;
  824. }
  825. /*
  826. *
  827. */
  828. static void dso__calc_col_width(struct dso *self)
  829. {
  830. if (!col_width_list_str && !field_sep &&
  831. (!dso_list || strlist__has_entry(dso_list, self->name))) {
  832. unsigned int slen = strlen(self->name);
  833. if (slen > dsos__col_width)
  834. dsos__col_width = slen;
  835. }
  836. self->slen_calculated = 1;
  837. }
  838. static struct symbol *
  839. resolve_symbol(struct thread *thread, struct map **mapp,
  840. struct dso **dsop, u64 *ipp)
  841. {
  842. struct dso *dso = dsop ? *dsop : NULL;
  843. struct map *map = mapp ? *mapp : NULL;
  844. u64 ip = *ipp;
  845. if (!thread)
  846. return NULL;
  847. if (dso)
  848. goto got_dso;
  849. if (map)
  850. goto got_map;
  851. map = thread__find_map(thread, ip);
  852. if (map != NULL) {
  853. /*
  854. * We have to do this here as we may have a dso
  855. * with no symbol hit that has a name longer than
  856. * the ones with symbols sampled.
  857. */
  858. if (!sort_dso.elide && !map->dso->slen_calculated)
  859. dso__calc_col_width(map->dso);
  860. if (mapp)
  861. *mapp = map;
  862. got_map:
  863. ip = map->map_ip(map, ip);
  864. dso = map->dso;
  865. } else {
  866. /*
  867. * If this is outside of all known maps,
  868. * and is a negative address, try to look it
  869. * up in the kernel dso, as it might be a
  870. * vsyscall (which executes in user-mode):
  871. */
  872. if ((long long)ip < 0)
  873. dso = kernel_dso;
  874. }
  875. dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
  876. dprintf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
  877. *ipp = ip;
  878. if (dsop)
  879. *dsop = dso;
  880. if (!dso)
  881. return NULL;
  882. got_dso:
  883. return dso->find_symbol(dso, ip);
  884. }
  885. static int call__match(struct symbol *sym)
  886. {
  887. if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
  888. return 1;
  889. return 0;
  890. }
  891. static struct symbol **
  892. resolve_callchain(struct thread *thread, struct map *map __used,
  893. struct ip_callchain *chain, struct hist_entry *entry)
  894. {
  895. u64 context = PERF_CONTEXT_MAX;
  896. struct symbol **syms = NULL;
  897. unsigned int i;
  898. if (callchain) {
  899. syms = calloc(chain->nr, sizeof(*syms));
  900. if (!syms) {
  901. fprintf(stderr, "Can't allocate memory for symbols\n");
  902. exit(-1);
  903. }
  904. }
  905. for (i = 0; i < chain->nr; i++) {
  906. u64 ip = chain->ips[i];
  907. struct dso *dso = NULL;
  908. struct symbol *sym;
  909. if (ip >= PERF_CONTEXT_MAX) {
  910. context = ip;
  911. continue;
  912. }
  913. switch (context) {
  914. case PERF_CONTEXT_HV:
  915. dso = hypervisor_dso;
  916. break;
  917. case PERF_CONTEXT_KERNEL:
  918. dso = kernel_dso;
  919. break;
  920. default:
  921. break;
  922. }
  923. sym = resolve_symbol(thread, NULL, &dso, &ip);
  924. if (sym) {
  925. if (sort__has_parent && call__match(sym) &&
  926. !entry->parent)
  927. entry->parent = sym;
  928. if (!callchain)
  929. break;
  930. syms[i] = sym;
  931. }
  932. }
  933. return syms;
  934. }
  935. /*
  936. * collect histogram counts
  937. */
  938. static int
  939. hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
  940. struct symbol *sym, u64 ip, struct ip_callchain *chain,
  941. char level, u64 count)
  942. {
  943. struct rb_node **p = &hist.rb_node;
  944. struct rb_node *parent = NULL;
  945. struct hist_entry *he;
  946. struct symbol **syms = NULL;
  947. struct hist_entry entry = {
  948. .thread = thread,
  949. .map = map,
  950. .dso = dso,
  951. .sym = sym,
  952. .ip = ip,
  953. .level = level,
  954. .count = count,
  955. .parent = NULL,
  956. .sorted_chain = RB_ROOT
  957. };
  958. int cmp;
  959. if ((sort__has_parent || callchain) && chain)
  960. syms = resolve_callchain(thread, map, chain, &entry);
  961. while (*p != NULL) {
  962. parent = *p;
  963. he = rb_entry(parent, struct hist_entry, rb_node);
  964. cmp = hist_entry__cmp(&entry, he);
  965. if (!cmp) {
  966. he->count += count;
  967. if (callchain) {
  968. append_chain(&he->callchain, chain, syms);
  969. free(syms);
  970. }
  971. return 0;
  972. }
  973. if (cmp < 0)
  974. p = &(*p)->rb_left;
  975. else
  976. p = &(*p)->rb_right;
  977. }
  978. he = malloc(sizeof(*he));
  979. if (!he)
  980. return -ENOMEM;
  981. *he = entry;
  982. if (callchain) {
  983. callchain_init(&he->callchain);
  984. append_chain(&he->callchain, chain, syms);
  985. free(syms);
  986. }
  987. rb_link_node(&he->rb_node, parent, p);
  988. rb_insert_color(&he->rb_node, &hist);
  989. return 0;
  990. }
  991. static void hist_entry__free(struct hist_entry *he)
  992. {
  993. free(he);
  994. }
  995. /*
  996. * collapse the histogram
  997. */
  998. static struct rb_root collapse_hists;
  999. static void collapse__insert_entry(struct hist_entry *he)
  1000. {
  1001. struct rb_node **p = &collapse_hists.rb_node;
  1002. struct rb_node *parent = NULL;
  1003. struct hist_entry *iter;
  1004. int64_t cmp;
  1005. while (*p != NULL) {
  1006. parent = *p;
  1007. iter = rb_entry(parent, struct hist_entry, rb_node);
  1008. cmp = hist_entry__collapse(iter, he);
  1009. if (!cmp) {
  1010. iter->count += he->count;
  1011. hist_entry__free(he);
  1012. return;
  1013. }
  1014. if (cmp < 0)
  1015. p = &(*p)->rb_left;
  1016. else
  1017. p = &(*p)->rb_right;
  1018. }
  1019. rb_link_node(&he->rb_node, parent, p);
  1020. rb_insert_color(&he->rb_node, &collapse_hists);
  1021. }
  1022. static void collapse__resort(void)
  1023. {
  1024. struct rb_node *next;
  1025. struct hist_entry *n;
  1026. if (!sort__need_collapse)
  1027. return;
  1028. next = rb_first(&hist);
  1029. while (next) {
  1030. n = rb_entry(next, struct hist_entry, rb_node);
  1031. next = rb_next(&n->rb_node);
  1032. rb_erase(&n->rb_node, &hist);
  1033. collapse__insert_entry(n);
  1034. }
  1035. }
  1036. /*
  1037. * reverse the map, sort on count.
  1038. */
  1039. static struct rb_root output_hists;
  1040. static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
  1041. {
  1042. struct rb_node **p = &output_hists.rb_node;
  1043. struct rb_node *parent = NULL;
  1044. struct hist_entry *iter;
  1045. if (callchain)
  1046. callchain_param.sort(&he->sorted_chain, &he->callchain,
  1047. min_callchain_hits, &callchain_param);
  1048. while (*p != NULL) {
  1049. parent = *p;
  1050. iter = rb_entry(parent, struct hist_entry, rb_node);
  1051. if (he->count > iter->count)
  1052. p = &(*p)->rb_left;
  1053. else
  1054. p = &(*p)->rb_right;
  1055. }
  1056. rb_link_node(&he->rb_node, parent, p);
  1057. rb_insert_color(&he->rb_node, &output_hists);
  1058. }
  1059. static void output__resort(u64 total_samples)
  1060. {
  1061. struct rb_node *next;
  1062. struct hist_entry *n;
  1063. struct rb_root *tree = &hist;
  1064. u64 min_callchain_hits;
  1065. min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
  1066. if (sort__need_collapse)
  1067. tree = &collapse_hists;
  1068. next = rb_first(tree);
  1069. while (next) {
  1070. n = rb_entry(next, struct hist_entry, rb_node);
  1071. next = rb_next(&n->rb_node);
  1072. rb_erase(&n->rb_node, tree);
  1073. output__insert_entry(n, min_callchain_hits);
  1074. }
  1075. }
  1076. static size_t output__fprintf(FILE *fp, u64 total_samples)
  1077. {
  1078. struct hist_entry *pos;
  1079. struct sort_entry *se;
  1080. struct rb_node *nd;
  1081. size_t ret = 0;
  1082. unsigned int width;
  1083. char *col_width = col_width_list_str;
  1084. fprintf(fp, "# Samples: %Ld\n", (u64)total_samples);
  1085. fprintf(fp, "#\n");
  1086. fprintf(fp, "# Overhead");
  1087. if (show_nr_samples) {
  1088. if (field_sep)
  1089. fprintf(fp, "%cSamples", *field_sep);
  1090. else
  1091. fputs(" Samples ", fp);
  1092. }
  1093. list_for_each_entry(se, &hist_entry__sort_list, list) {
  1094. if (se->elide)
  1095. continue;
  1096. if (field_sep) {
  1097. fprintf(fp, "%c%s", *field_sep, se->header);
  1098. continue;
  1099. }
  1100. width = strlen(se->header);
  1101. if (se->width) {
  1102. if (col_width_list_str) {
  1103. if (col_width) {
  1104. *se->width = atoi(col_width);
  1105. col_width = strchr(col_width, ',');
  1106. if (col_width)
  1107. ++col_width;
  1108. }
  1109. }
  1110. width = *se->width = max(*se->width, width);
  1111. }
  1112. fprintf(fp, " %*s", width, se->header);
  1113. }
  1114. fprintf(fp, "\n");
  1115. if (field_sep)
  1116. goto print_entries;
  1117. fprintf(fp, "# ........");
  1118. if (show_nr_samples)
  1119. fprintf(fp, " ..........");
  1120. list_for_each_entry(se, &hist_entry__sort_list, list) {
  1121. unsigned int i;
  1122. if (se->elide)
  1123. continue;
  1124. fprintf(fp, " ");
  1125. if (se->width)
  1126. width = *se->width;
  1127. else
  1128. width = strlen(se->header);
  1129. for (i = 0; i < width; i++)
  1130. fprintf(fp, ".");
  1131. }
  1132. fprintf(fp, "\n");
  1133. fprintf(fp, "#\n");
  1134. print_entries:
  1135. for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
  1136. pos = rb_entry(nd, struct hist_entry, rb_node);
  1137. ret += hist_entry__fprintf(fp, pos, total_samples);
  1138. }
  1139. if (sort_order == default_sort_order &&
  1140. parent_pattern == default_parent_pattern) {
  1141. fprintf(fp, "#\n");
  1142. fprintf(fp, "# (For more details, try: perf report --sort comm,dso,symbol)\n");
  1143. fprintf(fp, "#\n");
  1144. }
  1145. fprintf(fp, "\n");
  1146. return ret;
  1147. }
  1148. static void register_idle_thread(void)
  1149. {
  1150. struct thread *thread = threads__findnew(0);
  1151. if (thread == NULL ||
  1152. thread__set_comm(thread, "[idle]")) {
  1153. fprintf(stderr, "problem inserting idle task.\n");
  1154. exit(-1);
  1155. }
  1156. }
  1157. static unsigned long total = 0,
  1158. total_mmap = 0,
  1159. total_comm = 0,
  1160. total_fork = 0,
  1161. total_unknown = 0,
  1162. total_lost = 0;
  1163. static int validate_chain(struct ip_callchain *chain, event_t *event)
  1164. {
  1165. unsigned int chain_size;
  1166. chain_size = event->header.size;
  1167. chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
  1168. if (chain->nr*sizeof(u64) > chain_size)
  1169. return -1;
  1170. return 0;
  1171. }
  1172. static int
  1173. process_sample_event(event_t *event, unsigned long offset, unsigned long head)
  1174. {
  1175. char level;
  1176. int show = 0;
  1177. struct dso *dso = NULL;
  1178. struct thread *thread = threads__findnew(event->ip.pid);
  1179. u64 ip = event->ip.ip;
  1180. u64 period = 1;
  1181. struct map *map = NULL;
  1182. void *more_data = event->ip.__more_data;
  1183. struct ip_callchain *chain = NULL;
  1184. int cpumode;
  1185. if (sample_type & PERF_SAMPLE_PERIOD) {
  1186. period = *(u64 *)more_data;
  1187. more_data += sizeof(u64);
  1188. }
  1189. dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n",
  1190. (void *)(offset + head),
  1191. (void *)(long)(event->header.size),
  1192. event->header.misc,
  1193. event->ip.pid,
  1194. (void *)(long)ip,
  1195. (long long)period);
  1196. if (sample_type & PERF_SAMPLE_CALLCHAIN) {
  1197. unsigned int i;
  1198. chain = (void *)more_data;
  1199. dprintf("... chain: nr:%Lu\n", chain->nr);
  1200. if (validate_chain(chain, event) < 0) {
  1201. eprintf("call-chain problem with event, skipping it.\n");
  1202. return 0;
  1203. }
  1204. if (dump_trace) {
  1205. for (i = 0; i < chain->nr; i++)
  1206. dprintf("..... %2d: %016Lx\n", i, chain->ips[i]);
  1207. }
  1208. }
  1209. dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
  1210. if (thread == NULL) {
  1211. eprintf("problem processing %d event, skipping it.\n",
  1212. event->header.type);
  1213. return -1;
  1214. }
  1215. if (comm_list && !strlist__has_entry(comm_list, thread->comm))
  1216. return 0;
  1217. cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
  1218. if (cpumode == PERF_EVENT_MISC_KERNEL) {
  1219. show = SHOW_KERNEL;
  1220. level = 'k';
  1221. dso = kernel_dso;
  1222. dprintf(" ...... dso: %s\n", dso->name);
  1223. } else if (cpumode == PERF_EVENT_MISC_USER) {
  1224. show = SHOW_USER;
  1225. level = '.';
  1226. } else {
  1227. show = SHOW_HV;
  1228. level = 'H';
  1229. dso = hypervisor_dso;
  1230. dprintf(" ...... dso: [hypervisor]\n");
  1231. }
  1232. if (show & show_mask) {
  1233. struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
  1234. if (dso_list && dso && dso->name && !strlist__has_entry(dso_list, dso->name))
  1235. return 0;
  1236. if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
  1237. return 0;
  1238. if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
  1239. eprintf("problem incrementing symbol count, skipping event\n");
  1240. return -1;
  1241. }
  1242. }
  1243. total += period;
  1244. return 0;
  1245. }
  1246. static int
  1247. process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
  1248. {
  1249. struct thread *thread = threads__findnew(event->mmap.pid);
  1250. struct map *map = map__new(&event->mmap);
  1251. dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
  1252. (void *)(offset + head),
  1253. (void *)(long)(event->header.size),
  1254. event->mmap.pid,
  1255. (void *)(long)event->mmap.start,
  1256. (void *)(long)event->mmap.len,
  1257. (void *)(long)event->mmap.pgoff,
  1258. event->mmap.filename);
  1259. if (thread == NULL || map == NULL) {
  1260. dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
  1261. return 0;
  1262. }
  1263. thread__insert_map(thread, map);
  1264. total_mmap++;
  1265. return 0;
  1266. }
  1267. static int
  1268. process_comm_event(event_t *event, unsigned long offset, unsigned long head)
  1269. {
  1270. struct thread *thread = threads__findnew(event->comm.pid);
  1271. dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
  1272. (void *)(offset + head),
  1273. (void *)(long)(event->header.size),
  1274. event->comm.comm, event->comm.pid);
  1275. if (thread == NULL ||
  1276. thread__set_comm(thread, event->comm.comm)) {
  1277. dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
  1278. return -1;
  1279. }
  1280. total_comm++;
  1281. return 0;
  1282. }
  1283. static int
  1284. process_fork_event(event_t *event, unsigned long offset, unsigned long head)
  1285. {
  1286. struct thread *thread = threads__findnew(event->fork.pid);
  1287. struct thread *parent = threads__findnew(event->fork.ppid);
  1288. dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
  1289. (void *)(offset + head),
  1290. (void *)(long)(event->header.size),
  1291. event->fork.pid, event->fork.ppid);
  1292. if (!thread || !parent || thread__fork(thread, parent)) {
  1293. dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
  1294. return -1;
  1295. }
  1296. total_fork++;
  1297. return 0;
  1298. }
  1299. static int
  1300. process_lost_event(event_t *event, unsigned long offset, unsigned long head)
  1301. {
  1302. dprintf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n",
  1303. (void *)(offset + head),
  1304. (void *)(long)(event->header.size),
  1305. event->lost.id,
  1306. event->lost.lost);
  1307. total_lost += event->lost.lost;
  1308. return 0;
  1309. }
  1310. static void trace_event(event_t *event)
  1311. {
  1312. unsigned char *raw_event = (void *)event;
  1313. char *color = PERF_COLOR_BLUE;
  1314. int i, j;
  1315. if (!dump_trace)
  1316. return;
  1317. dprintf(".");
  1318. cdprintf("\n. ... raw event: size %d bytes\n", event->header.size);
  1319. for (i = 0; i < event->header.size; i++) {
  1320. if ((i & 15) == 0) {
  1321. dprintf(".");
  1322. cdprintf(" %04x: ", i);
  1323. }
  1324. cdprintf(" %02x", raw_event[i]);
  1325. if (((i & 15) == 15) || i == event->header.size-1) {
  1326. cdprintf(" ");
  1327. for (j = 0; j < 15-(i & 15); j++)
  1328. cdprintf(" ");
  1329. for (j = 0; j < (i & 15); j++) {
  1330. if (isprint(raw_event[i-15+j]))
  1331. cdprintf("%c", raw_event[i-15+j]);
  1332. else
  1333. cdprintf(".");
  1334. }
  1335. cdprintf("\n");
  1336. }
  1337. }
  1338. dprintf(".\n");
  1339. }
  1340. static int
  1341. process_read_event(event_t *event, unsigned long offset, unsigned long head)
  1342. {
  1343. dprintf("%p [%p]: PERF_EVENT_READ: %d %d %Lu\n",
  1344. (void *)(offset + head),
  1345. (void *)(long)(event->header.size),
  1346. event->read.pid,
  1347. event->read.tid,
  1348. event->read.value);
  1349. return 0;
  1350. }
  1351. static int
  1352. process_event(event_t *event, unsigned long offset, unsigned long head)
  1353. {
  1354. trace_event(event);
  1355. switch (event->header.type) {
  1356. case PERF_EVENT_SAMPLE:
  1357. return process_sample_event(event, offset, head);
  1358. case PERF_EVENT_MMAP:
  1359. return process_mmap_event(event, offset, head);
  1360. case PERF_EVENT_COMM:
  1361. return process_comm_event(event, offset, head);
  1362. case PERF_EVENT_FORK:
  1363. return process_fork_event(event, offset, head);
  1364. case PERF_EVENT_LOST:
  1365. return process_lost_event(event, offset, head);
  1366. case PERF_EVENT_READ:
  1367. return process_read_event(event, offset, head);
  1368. /*
  1369. * We dont process them right now but they are fine:
  1370. */
  1371. case PERF_EVENT_THROTTLE:
  1372. case PERF_EVENT_UNTHROTTLE:
  1373. return 0;
  1374. default:
  1375. return -1;
  1376. }
  1377. return 0;
  1378. }
  1379. static struct perf_header *header;
  1380. static u64 perf_header__sample_type(void)
  1381. {
  1382. u64 sample_type = 0;
  1383. int i;
  1384. for (i = 0; i < header->attrs; i++) {
  1385. struct perf_header_attr *attr = header->attr[i];
  1386. if (!sample_type)
  1387. sample_type = attr->attr.sample_type;
  1388. else if (sample_type != attr->attr.sample_type)
  1389. die("non matching sample_type");
  1390. }
  1391. return sample_type;
  1392. }
  1393. static int __cmd_report(void)
  1394. {
  1395. int ret, rc = EXIT_FAILURE;
  1396. unsigned long offset = 0;
  1397. unsigned long head, shift;
  1398. struct stat stat;
  1399. event_t *event;
  1400. uint32_t size;
  1401. char *buf;
  1402. register_idle_thread();
  1403. input = open(input_name, O_RDONLY);
  1404. if (input < 0) {
  1405. fprintf(stderr, " failed to open file: %s", input_name);
  1406. if (!strcmp(input_name, "perf.data"))
  1407. fprintf(stderr, " (try 'perf record' first)");
  1408. fprintf(stderr, "\n");
  1409. exit(-1);
  1410. }
  1411. ret = fstat(input, &stat);
  1412. if (ret < 0) {
  1413. perror("failed to stat file");
  1414. exit(-1);
  1415. }
  1416. if (!stat.st_size) {
  1417. fprintf(stderr, "zero-sized file, nothing to do!\n");
  1418. exit(0);
  1419. }
  1420. header = perf_header__read(input);
  1421. head = header->data_offset;
  1422. sample_type = perf_header__sample_type();
  1423. if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
  1424. if (sort__has_parent) {
  1425. fprintf(stderr, "selected --sort parent, but no"
  1426. " callchain data. Did you call"
  1427. " perf record without -g?\n");
  1428. exit(-1);
  1429. }
  1430. if (callchain) {
  1431. fprintf(stderr, "selected -c but no callchain data."
  1432. " Did you call perf record without"
  1433. " -g?\n");
  1434. exit(-1);
  1435. }
  1436. }
  1437. if (load_kernel() < 0) {
  1438. perror("failed to load kernel symbols");
  1439. return EXIT_FAILURE;
  1440. }
  1441. if (!full_paths) {
  1442. if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
  1443. perror("failed to get the current directory");
  1444. return EXIT_FAILURE;
  1445. }
  1446. cwdlen = strlen(cwd);
  1447. } else {
  1448. cwd = NULL;
  1449. cwdlen = 0;
  1450. }
  1451. shift = page_size * (head / page_size);
  1452. offset += shift;
  1453. head -= shift;
  1454. remap:
  1455. buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
  1456. MAP_SHARED, input, offset);
  1457. if (buf == MAP_FAILED) {
  1458. perror("failed to mmap file");
  1459. exit(-1);
  1460. }
  1461. more:
  1462. event = (event_t *)(buf + head);
  1463. size = event->header.size;
  1464. if (!size)
  1465. size = 8;
  1466. if (head + event->header.size >= page_size * mmap_window) {
  1467. int ret;
  1468. shift = page_size * (head / page_size);
  1469. ret = munmap(buf, page_size * mmap_window);
  1470. assert(ret == 0);
  1471. offset += shift;
  1472. head -= shift;
  1473. goto remap;
  1474. }
  1475. size = event->header.size;
  1476. dprintf("\n%p [%p]: event: %d\n",
  1477. (void *)(offset + head),
  1478. (void *)(long)event->header.size,
  1479. event->header.type);
  1480. if (!size || process_event(event, offset, head) < 0) {
  1481. dprintf("%p [%p]: skipping unknown header type: %d\n",
  1482. (void *)(offset + head),
  1483. (void *)(long)(event->header.size),
  1484. event->header.type);
  1485. total_unknown++;
  1486. /*
  1487. * assume we lost track of the stream, check alignment, and
  1488. * increment a single u64 in the hope to catch on again 'soon'.
  1489. */
  1490. if (unlikely(head & 7))
  1491. head &= ~7ULL;
  1492. size = 8;
  1493. }
  1494. head += size;
  1495. if (offset + head >= header->data_offset + header->data_size)
  1496. goto done;
  1497. if (offset + head < (unsigned long)stat.st_size)
  1498. goto more;
  1499. done:
  1500. rc = EXIT_SUCCESS;
  1501. close(input);
  1502. dprintf(" IP events: %10ld\n", total);
  1503. dprintf(" mmap events: %10ld\n", total_mmap);
  1504. dprintf(" comm events: %10ld\n", total_comm);
  1505. dprintf(" fork events: %10ld\n", total_fork);
  1506. dprintf(" lost events: %10ld\n", total_lost);
  1507. dprintf(" unknown events: %10ld\n", total_unknown);
  1508. if (dump_trace)
  1509. return 0;
  1510. if (verbose >= 3)
  1511. threads__fprintf(stdout);
  1512. if (verbose >= 2)
  1513. dsos__fprintf(stdout);
  1514. collapse__resort();
  1515. output__resort(total);
  1516. output__fprintf(stdout, total);
  1517. return rc;
  1518. }
  1519. static int
  1520. parse_callchain_opt(const struct option *opt __used, const char *arg,
  1521. int unset __used)
  1522. {
  1523. char *tok;
  1524. char *endptr;
  1525. callchain = 1;
  1526. if (!arg)
  1527. return 0;
  1528. tok = strtok((char *)arg, ",");
  1529. if (!tok)
  1530. return -1;
  1531. /* get the output mode */
  1532. if (!strncmp(tok, "graph", strlen(arg)))
  1533. callchain_param.mode = CHAIN_GRAPH_ABS;
  1534. else if (!strncmp(tok, "flat", strlen(arg)))
  1535. callchain_param.mode = CHAIN_FLAT;
  1536. else if (!strncmp(tok, "fractal", strlen(arg)))
  1537. callchain_param.mode = CHAIN_GRAPH_REL;
  1538. else
  1539. return -1;
  1540. /* get the min percentage */
  1541. tok = strtok(NULL, ",");
  1542. if (!tok)
  1543. goto setup;
  1544. callchain_param.min_percent = strtod(tok, &endptr);
  1545. if (tok == endptr)
  1546. return -1;
  1547. setup:
  1548. if (register_callchain_param(&callchain_param) < 0) {
  1549. fprintf(stderr, "Can't register callchain params\n");
  1550. return -1;
  1551. }
  1552. return 0;
  1553. }
  1554. static const char * const report_usage[] = {
  1555. "perf report [<options>] <command>",
  1556. NULL
  1557. };
  1558. static const struct option options[] = {
  1559. OPT_STRING('i', "input", &input_name, "file",
  1560. "input file name"),
  1561. OPT_BOOLEAN('v', "verbose", &verbose,
  1562. "be more verbose (show symbol address, etc)"),
  1563. OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
  1564. "dump raw trace in ASCII"),
  1565. OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
  1566. OPT_BOOLEAN('m', "modules", &modules,
  1567. "load module symbols - WARNING: use only with -k and LIVE kernel"),
  1568. OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
  1569. "Show a column with the number of samples"),
  1570. OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
  1571. "sort by key(s): pid, comm, dso, symbol, parent"),
  1572. OPT_BOOLEAN('P', "full-paths", &full_paths,
  1573. "Don't shorten the pathnames taking into account the cwd"),
  1574. OPT_STRING('p', "parent", &parent_pattern, "regex",
  1575. "regex filter to identify parent, see: '--sort parent'"),
  1576. OPT_BOOLEAN('x', "exclude-other", &exclude_other,
  1577. "Only display entries with parent-match"),
  1578. OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
  1579. "Display callchains using output_type and min percent threshold. "
  1580. "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
  1581. OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
  1582. "only consider symbols in these dsos"),
  1583. OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
  1584. "only consider symbols in these comms"),
  1585. OPT_STRING('S', "symbols", &sym_list_str, "symbol[,symbol...]",
  1586. "only consider these symbols"),
  1587. OPT_STRING('w', "column-widths", &col_width_list_str,
  1588. "width[,width...]",
  1589. "don't try to adjust column width, use these fixed values"),
  1590. OPT_STRING('t', "field-separator", &field_sep, "separator",
  1591. "separator for columns, no spaces will be added between "
  1592. "columns '.' is reserved."),
  1593. OPT_END()
  1594. };
  1595. static void setup_sorting(void)
  1596. {
  1597. char *tmp, *tok, *str = strdup(sort_order);
  1598. for (tok = strtok_r(str, ", ", &tmp);
  1599. tok; tok = strtok_r(NULL, ", ", &tmp)) {
  1600. if (sort_dimension__add(tok) < 0) {
  1601. error("Unknown --sort key: `%s'", tok);
  1602. usage_with_options(report_usage, options);
  1603. }
  1604. }
  1605. free(str);
  1606. }
  1607. static void setup_list(struct strlist **list, const char *list_str,
  1608. struct sort_entry *se, const char *list_name,
  1609. FILE *fp)
  1610. {
  1611. if (list_str) {
  1612. *list = strlist__new(true, list_str);
  1613. if (!*list) {
  1614. fprintf(stderr, "problems parsing %s list\n",
  1615. list_name);
  1616. exit(129);
  1617. }
  1618. if (strlist__nr_entries(*list) == 1) {
  1619. fprintf(fp, "# %s: %s\n", list_name,
  1620. strlist__entry(*list, 0)->s);
  1621. se->elide = true;
  1622. }
  1623. }
  1624. }
  1625. int cmd_report(int argc, const char **argv, const char *prefix __used)
  1626. {
  1627. symbol__init();
  1628. page_size = getpagesize();
  1629. argc = parse_options(argc, argv, options, report_usage, 0);
  1630. setup_sorting();
  1631. if (parent_pattern != default_parent_pattern) {
  1632. sort_dimension__add("parent");
  1633. sort_parent.elide = 1;
  1634. } else
  1635. exclude_other = 0;
  1636. /*
  1637. * Any (unrecognized) arguments left?
  1638. */
  1639. if (argc)
  1640. usage_with_options(report_usage, options);
  1641. setup_pager();
  1642. setup_list(&dso_list, dso_list_str, &sort_dso, "dso", stdout);
  1643. setup_list(&comm_list, comm_list_str, &sort_comm, "comm", stdout);
  1644. setup_list(&sym_list, sym_list_str, &sort_sym, "symbol", stdout);
  1645. if (field_sep && *field_sep == '.') {
  1646. fputs("'.' is the only non valid --field-separator argument\n",
  1647. stderr);
  1648. exit(129);
  1649. }
  1650. return __cmd_report();
  1651. }