From 3d39ac538629e4f00a6e1c38d46346f1b8e69505 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 28 May 2015 13:06:42 -0300 Subject: [PATCH] perf machine: No need to have two DSOs lists We can, given a DSO, figure out if it is a kernel, a kernel module or a userlevel DSO, so stop having to process two lists in several functions. If searching becomes an issue at some point, we can have them in a rbtree, etc. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-s4yb0onpdywu6dj2xl9lxi4t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/hists_common.c | 2 +- tools/perf/util/build-id.c | 59 +++++++++------------------------ tools/perf/util/dso.c | 2 +- tools/perf/util/header.c | 6 +--- tools/perf/util/machine.c | 28 ++++++---------- tools/perf/util/machine.h | 3 +- tools/perf/util/map.c | 2 +- tools/perf/util/probe-event.c | 5 +-- tools/perf/util/symbol-elf.c | 6 +--- tools/perf/util/vdso.c | 6 ++-- 10 files changed, 39 insertions(+), 80 deletions(-) diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 456f884eb27b..bcde1d27919c 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -121,7 +121,7 @@ struct machine *setup_fake_machine(struct machines *machines) size_t k; struct dso *dso; - dso = __dsos__findnew(&machine->user_dsos, + dso = __dsos__findnew(&machine->dsos, fake_symbols[i].dso_name); if (dso == NULL) goto out; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index ad8cfcbaa25d..1f6fc2323ef9 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -162,15 +162,20 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id, return write_padded(fd, name, name_len + 1, len); } -static int __dsos__write_buildid_table(struct list_head *head, - struct machine *machine, - pid_t pid, u16 misc, int fd) +static int machine__write_buildid_table(struct machine *machine, int fd) { + int err = 0; char nm[PATH_MAX]; struct dso *pos; + u16 kmisc = PERF_RECORD_MISC_KERNEL, + umisc = PERF_RECORD_MISC_USER; + + if (!machine__is_host(machine)) { + kmisc = PERF_RECORD_MISC_GUEST_KERNEL; + umisc = PERF_RECORD_MISC_GUEST_USER; + } - dsos__for_each_with_build_id(pos, head) { - int err; + dsos__for_each_with_build_id(pos, &machine->dsos.head) { const char *name; size_t name_len; @@ -189,32 +194,12 @@ static int __dsos__write_buildid_table(struct list_head *head, name_len = pos->long_name_len + 1; } - err = write_buildid(name, name_len, pos->build_id, - pid, misc, fd); + err = write_buildid(name, name_len, pos->build_id, machine->pid, + pos->kernel ? kmisc : umisc, fd); if (err) - return err; - } - - return 0; -} - -static int machine__write_buildid_table(struct machine *machine, int fd) -{ - int err; - u16 kmisc = PERF_RECORD_MISC_KERNEL, - umisc = PERF_RECORD_MISC_USER; - - if (!machine__is_host(machine)) { - kmisc = PERF_RECORD_MISC_GUEST_KERNEL; - umisc = PERF_RECORD_MISC_GUEST_USER; + break; } - err = __dsos__write_buildid_table(&machine->kernel_dsos.head, machine, - machine->pid, kmisc, fd); - if (err == 0) - err = __dsos__write_buildid_table(&machine->user_dsos.head, - machine, machine->pid, umisc, - fd); return err; } @@ -247,13 +232,7 @@ static int __dsos__hit_all(struct list_head *head) static int machine__hit_all_dsos(struct machine *machine) { - int err; - - err = __dsos__hit_all(&machine->kernel_dsos.head); - if (err) - return err; - - return __dsos__hit_all(&machine->user_dsos.head); + return __dsos__hit_all(&machine->dsos.head); } int dsos__hit_all(struct perf_session *session) @@ -493,9 +472,7 @@ static int __dsos__cache_build_ids(struct list_head *head, static int machine__cache_build_ids(struct machine *machine) { - int ret = __dsos__cache_build_ids(&machine->kernel_dsos.head, machine); - ret |= __dsos__cache_build_ids(&machine->user_dsos.head, machine); - return ret; + return __dsos__cache_build_ids(&machine->dsos.head, machine); } int perf_session__cache_build_ids(struct perf_session *session) @@ -520,11 +497,7 @@ int perf_session__cache_build_ids(struct perf_session *session) static bool machine__read_build_ids(struct machine *machine, bool with_hits) { - bool ret; - - ret = __dsos__read_build_ids(&machine->kernel_dsos.head, with_hits); - ret |= __dsos__read_build_ids(&machine->user_dsos.head, with_hits); - return ret; + return __dsos__read_build_ids(&machine->dsos.head, with_hits); } bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index fe5236833164..ff040b0569d6 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -833,7 +833,7 @@ struct dso *machine__findnew_kernel(struct machine *machine, const char *name, /* * The kernel dso could be created by build_id processing. */ - struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); + struct dso *dso = __dsos__findnew(&machine->dsos, name); /* * We need to run this in all cases, since during the build_id diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3f0d809d853a..a900e9441fb5 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1238,7 +1238,6 @@ static int __event_process_build_id(struct build_id_event *bev, struct perf_session *session) { int err = -1; - struct dsos *dsos; struct machine *machine; u16 misc; struct dso *dso; @@ -1253,22 +1252,19 @@ static int __event_process_build_id(struct build_id_event *bev, switch (misc) { case PERF_RECORD_MISC_KERNEL: dso_type = DSO_TYPE_KERNEL; - dsos = &machine->kernel_dsos; break; case PERF_RECORD_MISC_GUEST_KERNEL: dso_type = DSO_TYPE_GUEST_KERNEL; - dsos = &machine->kernel_dsos; break; case PERF_RECORD_MISC_USER: case PERF_RECORD_MISC_GUEST_USER: dso_type = DSO_TYPE_USER; - dsos = &machine->user_dsos; break; default: goto out; } - dso = __dsos__findnew(dsos, filename); + dso = __dsos__findnew(&machine->dsos, filename); if (dso != NULL) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 8934dc4345fe..ffd31079d447 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -26,8 +26,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) { map_groups__init(&machine->kmaps, machine); RB_CLEAR_NODE(&machine->rb_node); - dsos__init(&machine->user_dsos); - dsos__init(&machine->kernel_dsos); + dsos__init(&machine->dsos); machine->threads = RB_ROOT; pthread_rwlock_init(&machine->threads_lock, NULL); @@ -111,8 +110,7 @@ void machine__delete_threads(struct machine *machine) void machine__exit(struct machine *machine) { map_groups__exit(&machine->kmaps); - dsos__delete(&machine->user_dsos); - dsos__delete(&machine->kernel_dsos); + dsos__delete(&machine->dsos); vdso__exit(machine); zfree(&machine->root_dir); zfree(&machine->current_tid); @@ -490,9 +488,9 @@ machine__module_dso(struct machine *machine, struct kmod_path *m, { struct dso *dso; - dso = dsos__find(&machine->kernel_dsos, m->name, true); + dso = dsos__find(&machine->dsos, m->name, true); if (!dso) { - dso = dsos__addnew(&machine->kernel_dsos, m->name); + dso = dsos__addnew(&machine->dsos, m->name); if (dso == NULL) return NULL; @@ -561,13 +559,11 @@ struct map *machine__new_module(struct machine *machine, u64 start, size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) { struct rb_node *nd; - size_t ret = __dsos__fprintf(&machines->host.kernel_dsos.head, fp) + - __dsos__fprintf(&machines->host.user_dsos.head, fp); + size_t ret = __dsos__fprintf(&machines->host.dsos.head, fp); for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { struct machine *pos = rb_entry(nd, struct machine, rb_node); - ret += __dsos__fprintf(&pos->kernel_dsos.head, fp); - ret += __dsos__fprintf(&pos->user_dsos.head, fp); + ret += __dsos__fprintf(&pos->dsos.head, fp); } return ret; @@ -576,8 +572,7 @@ size_t machines__fprintf_dsos(struct machines *machines, FILE *fp) size_t machine__fprintf_dsos_buildid(struct machine *m, FILE *fp, bool (skip)(struct dso *dso, int parm), int parm) { - return __dsos__fprintf_buildid(&m->kernel_dsos.head, fp, skip, parm) + - __dsos__fprintf_buildid(&m->user_dsos.head, fp, skip, parm); + return __dsos__fprintf_buildid(&m->dsos.head, fp, skip, parm); } size_t machines__fprintf_dsos_buildid(struct machines *machines, FILE *fp, @@ -1106,7 +1101,7 @@ static bool machine__uses_kcore(struct machine *machine) { struct dso *dso; - list_for_each_entry(dso, &machine->kernel_dsos.head, node) { + list_for_each_entry(dso, &machine->dsos.head, node) { if (dso__is_kcore(dso)) return true; } @@ -1153,8 +1148,8 @@ static int machine__process_kernel_mmap_event(struct machine *machine, struct dso *kernel = NULL; struct dso *dso; - list_for_each_entry(dso, &machine->kernel_dsos.head, node) { - if (is_kernel_module(dso->long_name)) + list_for_each_entry(dso, &machine->dsos.head, node) { + if (dso->kernel && is_kernel_module(dso->long_name)) continue; kernel = dso; @@ -1162,8 +1157,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine, } if (kernel == NULL) - kernel = __dsos__findnew(&machine->kernel_dsos, - kmmap_prefix); + kernel = __dsos__findnew(&machine->dsos, kmmap_prefix); if (kernel == NULL) goto out_problem; diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index c7963c63c474..aabca583e655 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -34,8 +34,7 @@ struct machine { struct list_head dead_threads; struct thread *last_match; struct vdso_info *vdso_info; - struct dsos user_dsos; - struct dsos kernel_dsos; + struct dsos dsos; struct map_groups kmaps; struct map *vmlinux_maps[MAP__NR_TYPES]; u64 kernel_start; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index af572322586d..57ff0256c22c 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -180,7 +180,7 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, pgoff = 0; dso = vdso__dso_findnew(machine, thread); } else - dso = __dsos__findnew(&machine->user_dsos, filename); + dso = __dsos__findnew(&machine->dsos, filename); if (dso == NULL) goto out_delete; diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e6a02b1ffd6d..d27edef5eb5b 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -256,8 +256,9 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) int ret = 0; if (module) { - list_for_each_entry(dso, &host_machine->kernel_dsos.head, - node) { + list_for_each_entry(dso, &host_machine->dsos.head, node) { + if (!dso->kernel) + continue; if (strncmp(dso->short_name + 1, module, dso->short_name_len - 2) == 0) goto found; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index fa10116a12ab..a93ba85509b2 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1031,11 +1031,7 @@ int dso__load_sym(struct dso *dso, struct map *map, } curr_dso->symtab_type = dso->symtab_type; map_groups__insert(kmaps, curr_map); - /* - * The new DSO should go to the kernel DSOS - */ - dsos__add(&map->groups->machine->kernel_dsos, - curr_dso); + dsos__add(&map->groups->machine->dsos, curr_dso); dso__set_loaded(curr_dso, map->type); } else curr_dso = curr_map->dso; diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 5c7dd796979d..d3651b43e945 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -127,7 +127,7 @@ static struct dso *vdso__new(struct machine *machine, const char *short_name, dso = dso__new(short_name); if (dso != NULL) { - dsos__add(&machine->user_dsos, dso); + dsos__add(&machine->dsos, dso); dso__set_long_name(dso, long_name, false); } @@ -236,7 +236,7 @@ static struct dso *vdso__findnew_compat(struct machine *machine, const char *file_name; struct dso *dso; - dso = dsos__find(&machine->user_dsos, vdso_file->dso_name, true); + dso = dsos__find(&machine->dsos, vdso_file->dso_name, true); if (dso) return dso; @@ -299,7 +299,7 @@ struct dso *vdso__dso_findnew(struct machine *machine, return dso; #endif - dso = dsos__find(&machine->user_dsos, DSO__NAME_VDSO, true); + dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, true); if (!dso) { char *file; -- GitLab