brintos

brintos / linux-shallow public Read only

0
0
Text · 5.2 KiB · 187f12f Raw
224 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <inttypes.h>3#include "util/debug.h"4#include "util/dso.h"5#include "util/event.h" // struct perf_sample6#include "util/map.h"7#include "util/symbol.h"8#include "util/sort.h"9#include "util/evsel.h"10#include "util/machine.h"11#include "util/thread.h"12#include "tests/hists_common.h"13#include <linux/kernel.h>14#include <linux/perf_event.h>15 16static struct {17	u32 pid;18	const char *comm;19} fake_threads[] = {20	{ FAKE_PID_PERF1, "perf" },21	{ FAKE_PID_PERF2, "perf" },22	{ FAKE_PID_BASH,  "bash" },23};24 25static struct {26	u32 pid;27	u64 start;28	const char *filename;29} fake_mmap_info[] = {30	{ FAKE_PID_PERF1, FAKE_MAP_PERF,   "perf" },31	{ FAKE_PID_PERF1, FAKE_MAP_LIBC,   "libc" },32	{ FAKE_PID_PERF1, FAKE_MAP_KERNEL, "[kernel]" },33	{ FAKE_PID_PERF2, FAKE_MAP_PERF,   "perf" },34	{ FAKE_PID_PERF2, FAKE_MAP_LIBC,   "libc" },35	{ FAKE_PID_PERF2, FAKE_MAP_KERNEL, "[kernel]" },36	{ FAKE_PID_BASH,  FAKE_MAP_BASH,   "bash" },37	{ FAKE_PID_BASH,  FAKE_MAP_LIBC,   "libc" },38	{ FAKE_PID_BASH,  FAKE_MAP_KERNEL, "[kernel]" },39};40 41struct fake_sym {42	u64 start;43	u64 length;44	const char *name;45};46 47static struct fake_sym perf_syms[] = {48	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "main" },49	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "run_command" },50	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "cmd_record" },51};52 53static struct fake_sym bash_syms[] = {54	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "main" },55	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "xmalloc" },56	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "xfree" },57};58 59static struct fake_sym libc_syms[] = {60	{ 700, 100, "malloc" },61	{ 800, 100, "free" },62	{ 900, 100, "realloc" },63	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "malloc" },64	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "free" },65	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "realloc" },66};67 68static struct fake_sym kernel_syms[] = {69	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "schedule" },70	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "page_fault" },71	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "sys_perf_event_open" },72};73 74static struct {75	const char *dso_name;76	struct fake_sym *syms;77	size_t nr_syms;78} fake_symbols[] = {79	{ "perf", perf_syms, ARRAY_SIZE(perf_syms) },80	{ "bash", bash_syms, ARRAY_SIZE(bash_syms) },81	{ "libc", libc_syms, ARRAY_SIZE(libc_syms) },82	{ "[kernel]", kernel_syms, ARRAY_SIZE(kernel_syms) },83};84 85struct machine *setup_fake_machine(struct machines *machines)86{87	struct machine *machine = machines__find(machines, HOST_KERNEL_ID);88	size_t i;89 90	if (machine == NULL) {91		pr_debug("Not enough memory for machine setup\n");92		return NULL;93	}94 95	for (i = 0; i < ARRAY_SIZE(fake_threads); i++) {96		struct thread *thread;97 98		thread = machine__findnew_thread(machine, fake_threads[i].pid,99						 fake_threads[i].pid);100		if (thread == NULL)101			goto out;102 103		thread__set_comm(thread, fake_threads[i].comm, 0);104		thread__put(thread);105	}106 107	for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {108		struct perf_sample sample = {109			.cpumode = PERF_RECORD_MISC_USER,110		};111		union perf_event fake_mmap_event = {112			.mmap = {113				.pid = fake_mmap_info[i].pid,114				.tid = fake_mmap_info[i].pid,115				.start = fake_mmap_info[i].start,116				.len = FAKE_MAP_LENGTH,117				.pgoff = 0ULL,118			},119		};120 121		strcpy(fake_mmap_event.mmap.filename,122		       fake_mmap_info[i].filename);123 124		machine__process_mmap_event(machine, &fake_mmap_event, &sample);125	}126 127	for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {128		size_t k;129		struct dso *dso;130 131		dso = machine__findnew_dso(machine, fake_symbols[i].dso_name);132		if (dso == NULL)133			goto out;134 135		/* emulate dso__load() */136		dso__set_loaded(dso);137 138		for (k = 0; k < fake_symbols[i].nr_syms; k++) {139			struct symbol *sym;140			struct fake_sym *fsym = &fake_symbols[i].syms[k];141 142			sym = symbol__new(fsym->start, fsym->length,143					  STB_GLOBAL, STT_FUNC, fsym->name);144			if (sym == NULL) {145				dso__put(dso);146				goto out;147			}148 149			symbols__insert(dso__symbols(dso), sym);150		}151 152		dso__put(dso);153	}154 155	return machine;156 157out:158	pr_debug("Not enough memory for machine setup\n");159	machine__delete_threads(machine);160	return NULL;161}162 163void print_hists_in(struct hists *hists)164{165	int i = 0;166	struct rb_root_cached *root;167	struct rb_node *node;168 169	if (hists__has(hists, need_collapse))170		root = &hists->entries_collapsed;171	else172		root = hists->entries_in;173 174	pr_info("----- %s --------\n", __func__);175	node = rb_first_cached(root);176	while (node) {177		struct hist_entry *he;178 179		he = rb_entry(node, struct hist_entry, rb_node_in);180 181		if (!he->filtered) {182			struct dso *dso = map__dso(he->ms.map);183 184			pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",185				i, thread__comm_str(he->thread),186				dso__short_name(dso),187				he->ms.sym->name, he->stat.period);188		}189 190		i++;191		node = rb_next(node);192	}193}194 195void print_hists_out(struct hists *hists)196{197	int i = 0;198	struct rb_root_cached *root;199	struct rb_node *node;200 201	root = &hists->entries;202 203	pr_info("----- %s --------\n", __func__);204	node = rb_first_cached(root);205	while (node) {206		struct hist_entry *he;207 208		he = rb_entry(node, struct hist_entry, rb_node);209 210		if (!he->filtered) {211			struct dso *dso = map__dso(he->ms.map);212 213			pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n",214				i, thread__comm_str(he->thread), thread__tid(he->thread),215				dso__short_name(dso),216				he->ms.sym->name, he->stat.period,217				he->stat_acc ? he->stat_acc->period : 0);218		}219 220		i++;221		node = rb_next(node);222	}223}224