Skip to contentSkip to conversation

perf & kvm: Enhance perf to collect KVM guest os statistics from host side

PATCH In review Zhang, Yanmin 1 participant 1 message Apr 19, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v5 3/3 perf & kvm: Enhance perf to collect KVM guest os statistics from host side

Here is the patch of userspace perf tool.

---

tools/perf/builtin-annotate.c +1 -1
diff -Nraup linux-2.6_tip0417/tools/perf/builtin-annotate.c linux-2.6_tip0417_perfkvm/tools/perf/builtin-annotate.c
@@ -571,7 +571,7 @@ static int __cmd_annotate(void)
 		perf_session__fprintf(session, stdout);
 
 	if (verbose > 2)
-		dsos__fprintf(stdout);
+		dsos__fprintf(&session->kerninfo_root, stdout);
 
 	perf_session__collapse_resort(&session->hists);
 	perf_session__output_resort(&session->hists, session->event_total[0]);
tools/perf/builtin-buildid-list.c +1 -1
diff -Nraup linux-2.6_tip0417/tools/perf/builtin-buildid-list.c linux-2.6_tip0417_perfkvm/tools/perf/builtin-buildid-list.c
@@ -46,7 +46,7 @@ static int __cmd_buildid_list(void)
 	if (with_hits)
 		perf_session__process_events(session, &build_id__mark_dso_hit_ops);
 
-	dsos__fprintf_buildid(stdout, with_hits);
+	dsos__fprintf_buildid(&session->kerninfo_root, stdout, with_hits);
 
 	perf_session__delete(session);
 	return err;
tools/perf/builtin-diff.c +5 -1
diff -Nraup linux-2.6_tip0417/tools/perf/builtin-diff.c linux-2.6_tip0417_perfkvm/tools/perf/builtin-diff.c
@@ -33,7 +33,7 @@ static int perf_session__add_hist_entry(
 		return -ENOMEM;
 
 	if (hit)
-		he->count += count;
+		__perf_session__add_count(he, al, count);
 
 	return 0;
 }
@@ -225,6 +225,10 @@ int cmd_diff(int argc, const char **argv
 			input_new = argv[1];
 		} else
 			input_new = argv[0];
+	} else if (symbol_conf.default_guest_vmlinux_name ||
+		   symbol_conf.default_guest_kallsyms) {
+		input_old = "perf.data.host";
+		input_new = "perf.data.guest";
 	}
 
 	symbol_conf.exclude_other = false;
tools/perf/builtin.h +1 -0
diff -Nraup linux-2.6_tip0417/tools/perf/builtin.h linux-2.6_tip0417_perfkvm/tools/perf/builtin.h
@@ -32,5 +32,6 @@ extern int cmd_version(int argc, const c
 extern int cmd_probe(int argc, const char **argv, const char *prefix);
 extern int cmd_kmem(int argc, const char **argv, const char *prefix);
 extern int cmd_lock(int argc, const char **argv, const char *prefix);
+extern int cmd_kvm(int argc, const char **argv, const char *prefix);
 
 #endif
tools/perf/builtin-kmem.c +9 -2
diff -Nraup linux-2.6_tip0417/tools/perf/builtin-kmem.c linux-2.6_tip0417_perfkvm/tools/perf/builtin-kmem.c
@@ -351,6 +351,7 @@ static void __print_result(struct rb_roo
 			   int n_lines, int is_caller)
 {
 	struct rb_node *next;
+	struct kernel_info *kerninfo;
 
 	printf("%.102s\n", graph_dotted_line);
 	printf(" %-34s |",  is_caller ? "Callsite": "Alloc Ptr");
@@ -359,10 +360,16 @@ static void __print_result(struct rb_roo
 
 	next = rb_first(root);
 
+	kerninfo = kerninfo__findhost(&session->kerninfo_root);
+	if (!kerninfo) {
+		pr_err("__print_result: couldn't find kernel information\n");
+		return;
+	}
 	while (next && n_lines--) {
 		struct alloc_stat *data = rb_entry(next, struct alloc_stat,
 						   node);
 		struct symbol *sym = NULL;
+		struct map_groups *kmaps = &kerninfo->kmaps;
 		struct map *map;
 		char buf[BUFSIZ];
 		u64 addr;
@@ -370,8 +377,8 @@ static void __print_result(struct rb_roo
 		if (is_caller) {
 			addr = data->call_site;
 			if (!raw_ip)
-				sym = map_groups__find_function(&session->kmaps,
-								addr, &map, NULL);
+				sym = map_groups__find_function(kmaps, addr,
+								&map, NULL);
 		} else
 			addr = data->ptr;
 
tools/perf/builtin-kvm.c +145 -0

145 lines not on this page · raw message

tools/perf/builtin-record.c +60 -3

93 lines not on this page · raw message

tools/perf/builtin-report.c +4 -2
diff -Nraup linux-2.6_tip0417/tools/perf/builtin-report.c linux-2.6_tip0417_perfkvm/tools/perf/builtin-report.c
@@ -108,7 +108,7 @@ static int perf_session__add_hist_entry(
 		return -ENOMEM;
 
 	if (hit)
-		he->count += data->period;
+		__perf_session__add_count(he, al,  data->period);
 
 	if (symbol_conf.use_callchain) {
 		if (!hit)
@@ -313,7 +313,7 @@ static int __cmd_report(void)
 		perf_session__fprintf(session, stdout);
 
 	if (verbose > 2)
-		dsos__fprintf(stdout);
+		dsos__fprintf(&session->kerninfo_root, stdout);
 
 	next = rb_first(&session->stats_by_id);
 	while (next) {
@@ -450,6 +450,8 @@ static const struct option options[] = {
 		   "sort by key(s): pid, comm, dso, symbol, parent"),
 	OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
 		    "Don't shorten the pathnames taking into account the cwd"),
+	OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
+		    "Show sample percentage for different cpu modes"),
 	OPT_STRING('p', "parent", &parent_pattern, "regex",
 		   "regex filter to identify parent, see: '--sort parent'"),
 	OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
tools/perf/builtin-top.c +61 -14

165 lines not on this page · raw message

tools/perf/command-list.txt +1 -0
diff -Nraup linux-2.6_tip0417/tools/perf/command-list.txt linux-2.6_tip0417_perfkvm/tools/perf/command-list.txt
@@ -19,3 +19,4 @@ perf-trace			mainporcelain common
 perf-probe			mainporcelain common
 perf-kmem			mainporcelain common
 perf-lock			mainporcelain common
+perf-kvm			mainporcelain common
tools/perf/Documentation/perf-kvm.txt +67 -0

67 lines not on this page · raw message

tools/perf/Makefile +1 -0
diff -Nraup linux-2.6_tip0417/tools/perf/Makefile linux-2.6_tip0417_perfkvm/tools/perf/Makefile
@@ -472,6 +472,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
 BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
 BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
 BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
+BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
 
 PERFLIBS = $(LIB_FILE)
 
tools/perf/perf.c +1 -0
diff -Nraup linux-2.6_tip0417/tools/perf/perf.c linux-2.6_tip0417_perfkvm/tools/perf/perf.c
@@ -307,6 +307,7 @@ static void handle_internal_command(int 
 		{ "probe",	cmd_probe,	0 },
 		{ "kmem",	cmd_kmem,	0 },
 		{ "lock",	cmd_lock,	0 },
+		{ "kvm",	cmd_kvm,	0 },
 	};
 	unsigned int i;
 	static const char ext[] = STRIP_EXTENSION;
tools/perf/perf.h +2 -0
diff -Nraup linux-2.6_tip0417/tools/perf/perf.h linux-2.6_tip0417_perfkvm/tools/perf/perf.h
@@ -131,4 +131,6 @@ struct ip_callchain {
 	u64 ips[0];
 };
 
+extern int perf_host, perf_guest;
+
 #endif
tools/perf/util/build-id.c +1 -1
diff -Nraup linux-2.6_tip0417/tools/perf/util/build-id.c linux-2.6_tip0417_perfkvm/tools/perf/util/build-id.c
@@ -24,7 +24,7 @@ static int build_id__mark_dso_hit(event_
 	}
 
 	thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
-			      event->ip.ip, &al);
+			      event->ip.pid, event->ip.ip, &al);
 
 	if (al.map != NULL)
 		al.map->dso->hit = 1;
tools/perf/util/event.c +203 -73

398 lines not on this page · raw message

tools/perf/util/event.h +7 -3
diff -Nraup linux-2.6_tip0417/tools/perf/util/event.h linux-2.6_tip0417_perfkvm/tools/perf/util/event.h
@@ -79,6 +79,7 @@ struct sample_data {
 
 struct build_id_event {
 	struct perf_event_header header;
+	pid_t			 pid;
 	u8			 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
 	char			 filename[];
 };
@@ -154,10 +155,13 @@ int event__synthesize_thread(pid_t pid, 
 void event__synthesize_threads(event__handler_t process,
 			       struct perf_session *session);
 int event__synthesize_kernel_mmap(event__handler_t process,
-				  struct perf_session *session,
-				  const char *symbol_name);
+				struct perf_session *session,
+				struct kernel_info *kerninfo,
+				const char *symbol_name);
+
 int event__synthesize_modules(event__handler_t process,
-			      struct perf_session *session);
+			      struct perf_session *session,
+			      struct kernel_info *kerninfo);
 
 int event__process_comm(event_t *self, struct perf_session *session);
 int event__process_lost(event_t *self, struct perf_session *session);
tools/perf/util/header.c +173 -40

313 lines not on this page · raw message

tools/perf/util/header.h +1 -0
diff -Nraup linux-2.6_tip0417/tools/perf/util/header.h linux-2.6_tip0417_perfkvm/tools/perf/util/header.h
@@ -120,6 +120,7 @@ int event__process_tracing_data(event_t 
 
 int event__synthesize_build_id(struct dso *pos, u16 misc,
 			       event__handler_t process,
+			       struct kernel_info *kerninfo,
 			       struct perf_session *session);
 int event__synthesize_build_ids(event__handler_t process,
 				struct perf_session *session);
tools/perf/util/hist.c +71 -1

105 lines not on this page · raw message

tools/perf/util/hist.h +3 -0
diff -Nraup linux-2.6_tip0417/tools/perf/util/hist.h linux-2.6_tip0417_perfkvm/tools/perf/util/hist.h
@@ -12,6 +12,9 @@ struct addr_location;
 struct symbol;
 struct rb_root;
 
+void __perf_session__add_count(struct hist_entry *he,
+			struct addr_location *al,
+			u64 count);
 struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists,
 						  struct addr_location *al,
 						  struct symbol *parent,
tools/perf/util/map.c +138 -2

169 lines not on this page · raw message

tools/perf/util/map.h +61 -14

119 lines not on this page · raw message

tools/perf/util/probe-event.c +6 -1
diff -Nraup linux-2.6_tip0417/tools/perf/util/probe-event.c linux-2.6_tip0417_perfkvm/tools/perf/util/probe-event.c
@@ -78,6 +78,7 @@ static struct map *kmaps[MAP__NR_TYPES];
 /* Initialize symbol maps and path of vmlinux */
 static int init_vmlinux(void)
 {
+	struct dso *kernel;
 	int ret;
 
 	symbol_conf.sort_by_name = true;
@@ -91,8 +92,12 @@ static int init_vmlinux(void)
 		goto out;
 	}
 
+	kernel = dso__new_kernel(symbol_conf.vmlinux_name);
+	if (kernel == NULL)
+		die("Failed to create kernel dso.");
+
 	map_groups__init(&kmap_groups);
-	ret = map_groups__create_kernel_maps(&kmap_groups, kmaps);
+	ret = __map_groups__create_kernel_maps(&kmap_groups, kmaps, kernel);
 	if (ret < 0)
 		pr_debug("Failed to create kernel maps.\n");
 
tools/perf/util/session.c +28 -49

121 lines not on this page · raw message

tools/perf/util/session.h +3 -25
diff -Nraup linux-2.6_tip0417/tools/perf/util/session.h linux-2.6_tip0417_perfkvm/tools/perf/util/session.h
@@ -15,17 +15,15 @@ struct perf_session {
 	struct perf_header	header;
 	unsigned long		size;
 	unsigned long		mmap_window;
-	struct map_groups	kmaps;
 	struct rb_root		threads;
 	struct thread		*last_match;
-	struct map		*vmlinux_maps[MAP__NR_TYPES];
+	struct rb_root		kerninfo_root;
 	struct events_stats	events_stats;
 	struct rb_root		stats_by_id;
 	unsigned long		event_total[PERF_RECORD_MAX];
 	unsigned long		unknown_events;
 	struct rb_root		hists;
 	u64			sample_type;
-	struct ref_reloc_sym	ref_reloc_sym;
 	int			fd;
 	bool			fd_pipe;
 	int			cwdlen;
@@ -69,33 +67,13 @@ struct map_symbol *perf_session__resolve
 
 bool perf_session__has_traces(struct perf_session *self, const char *msg);
 
-int perf_header__read_build_ids(struct perf_header *self, int input,
-				u64 offset, u64 file_size);
-
-int perf_session__set_kallsyms_ref_reloc_sym(struct perf_session *self,
+int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
 					     const char *symbol_name,
 					     u64 addr);
 
 void mem_bswap_64(void *src, int byte_size);
 
-static inline int __perf_session__create_kernel_maps(struct perf_session *self,
-						struct dso *kernel)
-{
-	return __map_groups__create_kernel_maps(&self->kmaps,
-						self->vmlinux_maps, kernel);
-}
-
-static inline int perf_session__create_kernel_maps(struct perf_session *self)
-{
-	return map_groups__create_kernel_maps(&self->kmaps, self->vmlinux_maps);
-}
-
-static inline struct map *
-	perf_session__new_module_map(struct perf_session *self,
-				     u64 start, const char *filename)
-{
-	return map_groups__new_module(&self->kmaps, start, filename);
-}
+int perf_session__create_kernel_maps(struct perf_session *self);
 
 int do_read(int fd, void *buf, size_t size);
 void perf_session__update_sample_type(struct perf_session *self);
tools/perf/util/sort.h +5 -0
diff -Nraup linux-2.6_tip0417/tools/perf/util/sort.h linux-2.6_tip0417_perfkvm/tools/perf/util/sort.h
@@ -44,6 +44,11 @@ extern enum sort_type sort__first_dimens
 struct hist_entry {
 	struct rb_node		rb_node;
 	u64			count;
+	u64			count_sys;
+	u64			count_us;
+	u64			count_guest_sys;
+	u64			count_guest_us;
+
 	/*
 	 * XXX WARNING!
 	 * thread _has_ to come after ms, see
tools/perf/util/symbol.c +318 -65

648 lines not on this page · raw message

tools/perf/util/symbol.h +29 -14

105 lines not on this page · raw message

tools/perf/util/thread.h +2 -2
diff -Nraup linux-2.6_tip0417/tools/perf/util/thread.h linux-2.6_tip0417_perfkvm/tools/perf/util/thread.h
@@ -33,12 +33,12 @@ static inline struct map *thread__find_m
 
 void thread__find_addr_map(struct thread *self,
 			   struct perf_session *session, u8 cpumode,
-			   enum map_type type, u64 addr,
+			   enum map_type type, pid_t pid, u64 addr,
 			   struct addr_location *al);
 
 void thread__find_addr_location(struct thread *self,
 				struct perf_session *session, u8 cpumode,
-				enum map_type type, u64 addr,
+				enum map_type type, pid_t pid, u64 addr,
 				struct addr_location *al,
 				symbol_filter_t filter);
 #endif	/* __PERF_THREAD_H */