Per $subject, this patch set only supports for the LIVE kernel. It adds
support infrastructure for path discovery, load address lookup, and
symbol generation of live kernel modules.
TODO includes resurrection of live annotation in perf top, and support
for annotation and report generation of other than live modules. As the
patch set sits, Perf top can generate symbols from live binaries, but
there's no live annotation capability yet.
patch1: perf-counter tools: Make symbol loading consistently return number of loaded symbols.
patch2: perf-counter tools: Add infrastructure to support loading of kernel module symbols
patch3: perf-counter tools: connect module support infrastructure to symbol loading infrastructure
patch4: perf-counter tools: Enable kernel module symbol loading in tools
Comments and suggestions most welcome.
-Mike
patch 1/4 - perf_counter tools: Make symbol loading consistently return number of loaded symbols by Mike Galbraith on
2009-07-02T06:06:27+00:00
perf-counter tools: Make symbol loading consistently return number of loaded symbols.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
-Index: linux-2.6/tools/perf/builtin-annotate.c
===================================================================
+ if (err <= 0) {
dso@@ -189,7 +189,7 @@ static int load-kernel(void)
return -1;
err = dso===================================================================
+ if (dso+++ linux-2.6/tools/perf/util/symbol.c
@@ -146,6 +146,7 @@ static int dso goto out-failure;
@@ -188,8 +189,10 @@ static int dso+ count++;
+ }
}
/*
@@ -212,7 +215,7 @@ static int dso out-delete-line:
free(line);
@@ -639,7 +642,7 @@ int dso
return err;
patch 2/4 - perf_counter tools: Add infrastructure to support loading of kernel module symbols by Mike Galbraith on
2009-07-02T06:07:38+00:00
perf-counter tools: Add infrastructure to support loading of kernel module symbols.
Add infrastructure for module path discovery and section load addresses.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
-Index: linux-2.6/tools/perf/Makefile
===================================================================
LIB-H += util/color.h
LIB-OBJS += util/abspath.o
@@ -329,6 +330,7 @@ LIB-OBJS += util/usage.o
LIB-OBJS += util/wrapper.o
LIB-OBJS += util/sigchain.o
LIB-OBJS += util/symbol.o
+LIB-OBJS += util/module.o
LIB-OBJS += util/color.o
LIB-OBJS += util/pager.o
LIB-OBJS += util/header.o
Index: linux-2.6/tools/perf/util/module.h
===================================================================
+#include "../types.h"
+#include <linux/list.h>
+#include <linux/rbtree.h>
+
+struct section {
+ struct rb-node rb-node;
+ u64 hash;
+ u64 vma;
+ char *name;
+ char *path;
+};
+
+struct sec-dso {
+ struct list-head node;
+ struct rb-root secs;
+ struct section *(*find-section)(struct sec-dso *, const char *name);
+ char name[0];
+};
+
+struct module {
+ struct rb-node rb-node;
+ u64 hash;
+ char *name;
+ char *path;
+ struct sec-dso *sections;
+ int active;
+};
+
+struct mod-dso {
+ struct list-head node;
+ struct rb-root mods;
+ struct module *(*find-module)(struct mod-dso *, const char *name);
+ char name[0];
+};
+
+struct sec-dso *sec-dso+void mod-dsoIndex: linux-2.6/tools/perf/util/module.c
===================================================================
+
+#include <libelf.h>
+#include <gelf.h>
+#include <elf.h>
+#include <dirent.h>
+#include <sys/utsname.h>
+
+static unsigned int crc32(const char *p, unsigned int len)
+{
+ int i;
+ unsigned int crc = 0;
+ while (len+
+/* module section methods */
+
+struct sec-dso *sec-dso+ self->find-section = sec-dso+{
+ free(((void *)self));
+}
+
+void sec-dso+ next = rb-next(&pos->rb-node);
+ rb-erase(&pos->rb-node, &self->secs);
+ sec-dso+ free(self);
+}
+
+static void sec-dso+ while (*p != NULL) {
+ parent = *p;
+ s = rb-entry(parent, struct section, rb-node);
+ if (hash < s->hash)
+ p = &(*p)->rb-left;
+ else
+ p = &(*p)->rb-right;
+ }
+ rb-link-node(&sec->rb-node, parent, p);
+ rb-insert-color(&sec->rb-node, &self->secs);
+}
+
+struct section *sec-dso+ return NULL;
+
+ len = strlen(name);
+ hash = crc32(name, len);
+
+ n = self->secs.rb-node;
+
+ while (n) {
+ struct section *s = rb-entry(n, struct section, rb-node);
+
+ if (hash < s->hash)
+ n = n->rb-left;
+ else if (hash > s->hash)
+ n = n->rb-right;
+ else {
+ if (!strcmp(name, s->name))
+ return s;
+ else
+ n = rb-next(&s->rb-node);
+ }
+ }
+
+ return NULL;
+}
+
+static size-t sec-dso+{
+ size-t ret = fprintf(fp, "dso: %s
", self->name);
+
+ struct rb-node *nd;
+ for (nd = rb-first(&self->secs); nd; nd = rb-next(nd)) {
+ struct section *pos = rb-entry(nd, struct section, rb-node);
+ ret += sec-dso+{
+ struct section *self = calloc(1, sizeof(*self));
+
+ if (!self)
+ goto out-failure;
+
+ self->name = calloc(1, strlen(name) + 1);
+ if (!self->name)
+ goto out-failure;
+
+ self->path = calloc(1, strlen(path) + 1);
+ if (!self->path)
+ goto out-failure;
+
+ strcpy(self->name, name);
+ strcpy(self->path, path);
+ self->hash = crc32(self->name, strlen(name));
+
+ return self;
+
+out-failure:
+ if (self) {
+ if (self->name)
+ free (self->name);
+ if (self->path)
+ free (self->path);
+ free (self);
+ }
+
+ return NULL;
+}
+
+/* module methods */
+
+struct mod-dso *mod-dso+ self->find-module = mod-dso+{
+ free(((void *)self));
+}
+
+void mod-dso+ next = rb-next(&pos->rb-node);
+ rb-erase(&pos->rb-node, &self->mods);
+ mod-dso+ free(self);
+}
+
+static void mod-dso+ while (*p != NULL) {
+ parent = *p;
+ m = rb-entry(parent, struct module, rb-node);
+ if (hash < m->hash)
+ p = &(*p)->rb-left;
+ else
+ p = &(*p)->rb-right;
+ }
+ rb-link-node(&mod->rb-node, parent, p);
+ rb-insert-color(&mod->rb-node, &self->mods);
+}
+
+struct module *mod-dso+ return NULL;
+
+ len = strlen(name);
+ hash = crc32(name, len);
+
+ n = self->mods.rb-node;
+
+ while (n) {
+ struct module *m = rb-entry(n, struct module, rb-node);
+
+ if (hash < m->hash)
+ n = n->rb-left;
+ else if (hash > m->hash)
+ n = n->rb-right;
+ else {
+ if (!strcmp(name, m->name))
+ return m;
+ else
+ n = rb-next(&m->rb-node);
+ }
+ }
+
+ return NULL;
+}
+
+static size-t mod-dso+ size-t ret = fprintf(fp, "dso: %s
", self->name);
+
+ struct rb-node *nd;
+ for (nd = rb-first(&self->mods); nd; nd = rb-next(nd)) {
+ struct module *pos = rb-entry(nd, struct module, rb-node);
+ ret += mod-dso+{
+ struct module *self = calloc(1, sizeof(*self));
+
+ if (!self)
+ goto out-failure;
+
+ self->name = calloc(1, strlen(name) + 1);
+ if (!self->name)
+ goto out-failure;
+
+ self->path = calloc(1, strlen(path) + 1);
+ if (!self->path)
+ goto out-failure;
+
+ strcpy(self->name, name);
+ strcpy(self->path, path);
+ self->hash = crc32(self->name, strlen(name));
+
+ return self;
+
+out-failure:
+ if (self) {
+ if (self->name)
+ free (self->name);
+ if (self->path)
+ free (self->path);
+ free (self);
+ }
+
+ return NULL;
+}
+
+static int mod-dso+ char *dir-path;
+
+ path-len = strlen("/sys/module/");
+ path-len += strlen(mod->name);
+ path-len += strlen("/sections/");
+
+ dir-path = calloc(1, path-len + 1);
+ if (dir-path == NULL)
+ goto out-failure;
+
+ strcat(dir-path, "/sys/module/");
+ strcat(dir-path, mod->name);
+ strcat(dir-path, "/sections/");
+
+ dir = opendir(dir-path);
+ if (dir == NULL)
+ goto out-free;
+
+ while ((entry = readdir(dir))) {
+ struct section *section;
+ FILE *file;
+ char *path, *vma;
+ int line-len;
+
+ if (!strcmp(".", entry->d-name) || !strcmp("..", entry->d-name))
+ continue;
+
+ path = calloc(1, path-len + strlen(entry->d-name) + 1);
+ if (path == NULL)
+ break;
+ strcat(path, dir-path);
+ strcat(path, entry->d-name);
+
+ file = fopen(path, "r");
+ if (file == NULL) {
+ free(path);
+ break;
+ }
+
+ line-len = getline(&line, &n, file);
+ if (line-len < 0) {
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ if (!line) {
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ line[+ }
+ vma += 2;
+
+ section = section+
+ hex2u64(vma, §ion->vma);
+ sec-dso+ closedir(dir);
+ free(line);
+ free(dir-path);
+
+ return count;
+
+out-free:
+ free(dir-path);
+
+out-failure:
+ return count;
+}
+
+static int mod-dso+ char *path;
+
+ if(uname(&uts) < 0)
+ goto out-failure;
+
+ len = strlen("/lib/modules/");
+ len += strlen(uts.release);
+ len += strlen("/modules.dep");
+
+ path = calloc(1, len);
+ if (path == NULL)
+ goto out-failure;
+
+ strcat(path, "/lib/modules/");
+ strcat(path, uts.release);
+ strcat(path, "/modules.dep");
+
+ file = fopen(path, "r");
+ free(path);
+ if (file == NULL)
+ goto out-failure;
+
+ while (!feof(file)) {
+ struct module *module;
+ int line-len, len;
+ char *path, *name, *tmp;
+
+ line-len = getline(&line, &n, file);
+ if (line-len < 0)
+ break;
+
+ if (!line)
+ goto out-failure;
+
+ line[+ name = tmp = strtok(name, "/");
+ while(tmp) {
+ tmp = strtok(NULL, "/");
+ if (tmp)
+ name = tmp;
+ }
+ name = strsep(&name, ".");
+
+ /* Replace '-' with '-' in damn sound modules */
+ for (len = strlen(name); len; len+ goto out-failure;
+ }
+ mod-dso+
+ module->active = mod-dso+ fclose(file);
+
+ return count;
+
+out-failure:
+ return -1;
+}
+
+int mod-dso+}
+
patch 3/4 - perf_counter tools: connect module support infrastructure to symbol loading infrastructure by Mike Galbraith on
2009-07-02T06:08:57+00:00
perf-counter tools: connect module support infrastructure to symbol loading infrastructure.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
-Index: linux-2.6/tools/perf/util/symbol.h
===================================================================
struct symbol {
struct rb-node rb-node;
@@ -13,6 +14,7 @@ struct symbol {
u64 obj-start;
u64 hist-sum;
u64 *hist;
+ struct module *module;
void *priv;
char name[0];
};
@@ -41,7 +43,8 @@ static inline void *dso int dso@@ -35,7 +35,7 @@ static struct symbol *symbol
return self;
@@ -48,8 +48,12 @@ static void symbol self->start, self->end, self->name);
+ else
+ return fprintf(fp, " %llx-%llx %s [%s]
",
+ self->start, self->end, self->name, self->module->name);
}
struct dso *dso+ return elf-sym+ const Elf-Data *secstrs)
+{
+ return secstrs->d-buf + shdr->sh-name;
+}
+
+static inline int elf-sec const Elf-Data *symstrs)
{
@@ -451,9 +475,9 @@ static int dso- Elf-Data *symstrs;
+ Elf-Data *symstrs, *secstrs;
uint32-t nr-syms;
int err = -1;
uint32-t index;
@@ -461,7 +485,7 @@ static int dso size-t dynsym-idx;
int nr = 0;
@@ -520,6 +544,14 @@ static int dso+
+ secstrs = elf-getdata(sec-strndx, NULL);
+ if (symstrs == NULL)
+ goto out-elf-end;
+
nr-syms = shdr.sh-size / shdr.sh-entsize;
memset(&sym, 0, sizeof(sym));
@@ -529,8 +561,11 @@ static int dso
- if (!elf-sym
gelf-getshdr(sec, &shdr);
+
+ if (is-label && !elf-sec@@ -548,6 +588,17 @@ static int dso+ sym.st-value += section->vma;
+ else {
+ fprintf(stderr, "dso elf-sym dso- ret = dso }
+static int dso+ return err;
+
+ fd = open(mod->path, O-RDONLY);
+
+ if (fd < 0)
+ return err;
+
+ err = dso+{
+ struct mod-dso *mods = mod-dso+ if (err <= 0)
+ return err;
+
+ /*
+ * Iterate over modules, and load active symbols.
+ */
+ next = rb-first(&mods->mods);
+ while (next) {
+ pos = rb-entry(next, struct module, rb-node);
+ err = dso+
+ if (err < 0) {
+ mod-dso+static inline void dso+
+ if (prev) {
+ u64 hole = 0;
+ int alias = pos->start == prev->start;
+
+ if (!alias)
+ hole = prev->start - pos->end - 1;
+
+ if (hole || alias) {
+ if (alias)
+ pos->end = prev->end;
+ else if (hole)
+ pos->end = prev->start - 1;
+ }
+ }
+ prev = pos;
+ }
+}
+
static int dso- err = dso
return err;
}
int dso+ if (vmlinux) {
err = dsoIndex: linux-2.6/tools/perf/builtin-annotate.c
===================================================================
+ err = dso+++ linux-2.6/tools/perf/builtin-report.c
@@ -188,7 +188,7 @@ static int load-kernel(void)
if (!kernel-dso)
return -1;
- err = dso+ if (dsothe body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
patch 4/4 - perf_counter tools: Enable kernel module symbol loading in tools by Mike Galbraith on
2009-07-02T06:10:08+00:00
perf-counter tools: Enable kernel module symbol loading in tools.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
-Index: linux-2.6/tools/perf/builtin-annotate.c
===================================================================
+
+static int full-paths;
+
static int print-line;
static unsigned long page-size;
@@ -171,7 +175,7 @@ static int load-kernel(void)
if (!kernel-dso)
return -1;
- err = dso static void annotate-sym(struct dso *dso, struct symbol *sym)
{
- char *filename = dso->name;
+ char *filename = dso->name, *d-filename;
u64 start, end, len;
char command[PATH-MAX*2];
FILE *file;
if (!filename)
return;
- if (dso == kernel-dso)
+ if (sym->module)
+ filename = sym->module->path;
+ else if (dso == kernel-dso)
filename = vmlinux;
start = sym->obj-start;
if (!start)
start = sym->start;
+ if (full-paths)
+ d-filename = filename;
+ else
+ d-filename = basename(filename);
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
@@ -1291,13 +1301,14 @@ static void annotate-sym(struct dso *dso
}
printf("
- sprintf(command, "objdump OPT-BOOLEAN('D', "dump-raw-trace", &dump-trace,
"dump raw trace in ASCII"),
OPT-STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT-BOOLEAN('m', "modules", &modules,
+ "load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT-BOOLEAN('l', "print-line", &print-line,
"print matching source lines (may be slow)"),
+ OPT-BOOLEAN('P', "full-paths", &full-paths,
+ "Don't shorten the displayed pathnames"),
OPT-END()
};
Index: linux-2.6/tools/perf/builtin-report.c
===================================================================
+
static int full-paths;
static unsigned long page-size;
@@ -188,7 +190,7 @@ static int load-kernel(void)
if (!kernel-dso)
return -1;
- err = dso self->dso == kernel-dso ? 'k' :
self->dso == hypervisor-dso ? 'h' : '.', self->sym->name);
+
+ if (self->sym->module)
+ ret += fprintf(fp, " [%s]", self->sym->module->name);
} else {
ret += fprintf(fp, "%#016llx", (u64)self->ip);
}
@@ -1710,6 +1715,8 @@ static const struct option options[] = {
OPT-BOOLEAN('D', "dump-raw-trace", &dump-trace,
"dump raw trace in ASCII"),
OPT-STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT-BOOLEAN('m', "modules", &modules,
+ "load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT-STRING('s', "sort", &sort-order, "key[,key2...]",
"sort by key(s): pid, comm, dso, symbol, parent"),
OPT-BOOLEAN('P', "full-paths", &full-paths,
Index: linux-2.6/tools/perf/builtin-top.c
===================================================================
static char *sym-filter;
static unsigned long filter-start;
@@ -265,7 +266,10 @@ static void print-sym-table(void)
printf("%9.1f %10ld - ", syme->weight, syme->snap-count);
color-fprintf(stdout, color, "%4.1f%%", pcnt);
- printf(" - %016llx : %s
", sym->start, sym->name);
+ printf(" - %016llx : %s", sym->start, sym->name);
+ if (sym->module)
+ printf(" [%s]", sym->module->name);
+ printf("
");
}
}
@@ -359,12 +363,13 @@ static int parse-symbols(void)
{
struct rb-node *node;
struct symbol *sym;
+ int modules = vmlinux ? 1 : 0;
kernel-dso = dso
node = rb-first(&kernel-dso->syms);
@@ -680,6 +685,7 @@ static const struct option options[] = {
"system-wide collection from all CPUs"),
OPT-INTEGER('C', "CPU", &profile-cpu,
"CPU to profile on"),
+ OPT-STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
OPT-INTEGER('m', "mmap-pages", &mmap-pages,
"number of mmap data pages"),
OPT-INTEGER('r', "realtime", &realtime-prio,
@@ -709,6 +715,8 @@ int cmd-top(int argc, const char **argv,
{
int counter;
+ symbol
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-02T06:47:40+00:00
* Mike Galbraith <efault@gmx.de> wrote:
> Per $subject, this patch set only supports for the LIVE kernel.
> It adds support infrastructure for path discovery, load address
> lookup, and symbol generation of live kernel modules.
>
> TODO includes resurrection of live annotation in perf top, and
> support for annotation and report generation of other than live
> modules. As the patch set sits, Perf top can generate symbols
> from live binaries, but there's no live annotation capability yet.
>
> patch1: perf-counter tools: Make symbol loading consistently return number of loaded symbols.
> patch2: perf-counter tools: Add infrastructure to support loading of kernel module symbols
> patch3: perf-counter tools: connect module support infrastructure to symbol loading infrastructure
> patch4: perf-counter tools: Enable kernel module symbol loading in tools
>
> Comments and suggestions most welcome.
Looks very nice! I've applied it with a few minor stylistic fixlets
and a tad more verbose changelogs.
I'm wondering about the next step: couldnt we somehow guess at the
position of the vmlinux too, validate somehow that it corresponds to
the kernel we are running - and then use it automatically and by
default?
Plus, offline analysis would be nice as well i suspect - being able
to look at profiles on a different box?
Ingo
tip:perfcounters/urgent - perf_counter tools: Make symbol loading consistently return number of loaded symbols by tip-bot for Mike Galbraith on
2009-07-02T07:07:44+00:00
Commit-ID: 9974f496782b7612e36a143bedda858f1cb953d4
Gitweb: http://git.kernel.org/tip/9974f496782b7612e36a143bedda858f1cb953d4
Author: Mike Galbraith <efault@gmx.de>
AuthorDate: Thu, 2 Jul 2009 08:05:58 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 08:42:20 +0200
perf-counter tools: Make symbol loading consistently return number of loaded symbols
perf-counter tools: Make symbol loading consistently return number of loaded symbols.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246514758.13293.42.camel@marge.simson.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-diff err = dsoindex be1b758..58d1612 100644
+ if (err <= 0) {
dso@@ -364,7 +364,7 @@ static int parse-symbols(void)
if (kernel-dso == NULL)
return -1;
- if (dso
if (file == NULL)
goto out-failure;
@@ -188,8 +189,10 @@ static int dso+ count++;
+ }
}
/*
@@ -212,7 +215,7 @@ static int dso out-delete-line:
free(line);
@@ -639,7 +642,7 @@ int dso
return err;
tip:perfcounters/urgent - perf_counter tools: Add infrastructure to support loading of kernel module symbols by tip-bot for Mike Galbraith on
2009-07-02T07:08:08+00:00
Commit-ID: 208b4b4a59351011b7f212e273f2b7bc47a9c482
Gitweb: http://git.kernel.org/tip/208b4b4a59351011b7f212e273f2b7bc47a9c482
Author: Mike Galbraith <efault@gmx.de>
AuthorDate: Thu, 2 Jul 2009 08:07:10 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 08:42:20 +0200
perf-counter tools: Add infrastructure to support loading of kernel module symbols
Add infrastructure for module path discovery and section load addresses.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246514830.13293.44.camel@marge.simson.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-diff LIB-H += util/symbol.h
+LIB-H += util/module.h
LIB-H += util/color.h
LIB-OBJS += util/abspath.o
@@ -329,6 +330,7 @@ LIB-OBJS += util/usage.o
LIB-OBJS += util/wrapper.o
LIB-OBJS += util/sigchain.o
LIB-OBJS += util/symbol.o
+LIB-OBJS += util/module.o
LIB-OBJS += util/color.o
LIB-OBJS += util/pager.o
LIB-OBJS += util/header.o
diff +#include "../perf.h"
+#include "string.h"
+#include "module.h"
+
+#include <libelf.h>
+#include <gelf.h>
+#include <elf.h>
+#include <dirent.h>
+#include <sys/utsname.h>
+
+static unsigned int crc32(const char *p, unsigned int len)
+{
+ int i;
+ unsigned int crc = 0;
+
+ while (len+
+/* module section methods */
+
+struct sec-dso *sec-dso+ self->find-section = sec-dso+{
+ free(((void *)self));
+}
+
+void sec-dso+ next = rb-next(&pos->rb-node);
+ rb-erase(&pos->rb-node, &self->secs);
+ sec-dso+ free(self);
+}
+
+static void sec-dso+ while (*p != NULL) {
+ parent = *p;
+ s = rb-entry(parent, struct section, rb-node);
+ if (hash < s->hash)
+ p = &(*p)->rb-left;
+ else
+ p = &(*p)->rb-right;
+ }
+ rb-link-node(&sec->rb-node, parent, p);
+ rb-insert-color(&sec->rb-node, &self->secs);
+}
+
+struct section *sec-dso+ return NULL;
+
+ len = strlen(name);
+ hash = crc32(name, len);
+
+ n = self->secs.rb-node;
+
+ while (n) {
+ struct section *s = rb-entry(n, struct section, rb-node);
+
+ if (hash < s->hash)
+ n = n->rb-left;
+ else if (hash > s->hash)
+ n = n->rb-right;
+ else {
+ if (!strcmp(name, s->name))
+ return s;
+ else
+ n = rb-next(&s->rb-node);
+ }
+ }
+
+ return NULL;
+}
+
+static size-t sec-dso+{
+ size-t ret = fprintf(fp, "dso: %s
", self->name);
+
+ struct rb-node *nd;
+ for (nd = rb-first(&self->secs); nd; nd = rb-next(nd)) {
+ struct section *pos = rb-entry(nd, struct section, rb-node);
+ ret += sec-dso+{
+ struct section *self = calloc(1, sizeof(*self));
+
+ if (!self)
+ goto out-failure;
+
+ self->name = calloc(1, strlen(name) + 1);
+ if (!self->name)
+ goto out-failure;
+
+ self->path = calloc(1, strlen(path) + 1);
+ if (!self->path)
+ goto out-failure;
+
+ strcpy(self->name, name);
+ strcpy(self->path, path);
+ self->hash = crc32(self->name, strlen(name));
+
+ return self;
+
+out-failure:
+ if (self) {
+ if (self->name)
+ free(self->name);
+ if (self->path)
+ free(self->path);
+ free(self);
+ }
+
+ return NULL;
+}
+
+/* module methods */
+
+struct mod-dso *mod-dso+ self->find-module = mod-dso+{
+ free(((void *)self));
+}
+
+void mod-dso+ next = rb-next(&pos->rb-node);
+ rb-erase(&pos->rb-node, &self->mods);
+ mod-dso+ free(self);
+}
+
+static void mod-dso+ while (*p != NULL) {
+ parent = *p;
+ m = rb-entry(parent, struct module, rb-node);
+ if (hash < m->hash)
+ p = &(*p)->rb-left;
+ else
+ p = &(*p)->rb-right;
+ }
+ rb-link-node(&mod->rb-node, parent, p);
+ rb-insert-color(&mod->rb-node, &self->mods);
+}
+
+struct module *mod-dso+ return NULL;
+
+ len = strlen(name);
+ hash = crc32(name, len);
+
+ n = self->mods.rb-node;
+
+ while (n) {
+ struct module *m = rb-entry(n, struct module, rb-node);
+
+ if (hash < m->hash)
+ n = n->rb-left;
+ else if (hash > m->hash)
+ n = n->rb-right;
+ else {
+ if (!strcmp(name, m->name))
+ return m;
+ else
+ n = rb-next(&m->rb-node);
+ }
+ }
+
+ return NULL;
+}
+
+static size-t mod-dso+ struct rb-node *nd;
+ size-t ret;
+
+ ret = fprintf(fp, "dso: %s
", self->name);
+
+ for (nd = rb-first(&self->mods); nd; nd = rb-next(nd)) {
+ struct module *pos = rb-entry(nd, struct module, rb-node);
+
+ ret += mod-dso+{
+ struct module *self = calloc(1, sizeof(*self));
+
+ if (!self)
+ goto out-failure;
+
+ self->name = calloc(1, strlen(name) + 1);
+ if (!self->name)
+ goto out-failure;
+
+ self->path = calloc(1, strlen(path) + 1);
+ if (!self->path)
+ goto out-failure;
+
+ strcpy(self->name, name);
+ strcpy(self->path, path);
+ self->hash = crc32(self->name, strlen(name));
+
+ return self;
+
+out-failure:
+ if (self) {
+ if (self->name)
+ free(self->name);
+ if (self->path)
+ free(self->path);
+ free(self);
+ }
+
+ return NULL;
+}
+
+static int mod-dso+ size-t n;
+
+ path-len = strlen("/sys/module/");
+ path-len += strlen(mod->name);
+ path-len += strlen("/sections/");
+
+ dir-path = calloc(1, path-len + 1);
+ if (dir-path == NULL)
+ goto out-failure;
+
+ strcat(dir-path, "/sys/module/");
+ strcat(dir-path, mod->name);
+ strcat(dir-path, "/sections/");
+
+ dir = opendir(dir-path);
+ if (dir == NULL)
+ goto out-free;
+
+ while ((entry = readdir(dir))) {
+ struct section *section;
+ char *path, *vma;
+ int line-len;
+ FILE *file;
+
+ if (!strcmp(".", entry->d-name) || !strcmp("..", entry->d-name))
+ continue;
+
+ path = calloc(1, path-len + strlen(entry->d-name) + 1);
+ if (path == NULL)
+ break;
+ strcat(path, dir-path);
+ strcat(path, entry->d-name);
+
+ file = fopen(path, "r");
+ if (file == NULL) {
+ free(path);
+ break;
+ }
+
+ line-len = getline(&line, &n, file);
+ if (line-len < 0) {
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ if (!line) {
+ free(path);
+ fclose(file);
+ break;
+ }
+
+ line[+ }
+ vma += 2;
+
+ section = section+
+ hex2u64(vma, §ion->vma);
+ sec-dso+ closedir(dir);
+ free(line);
+ free(dir-path);
+
+ return count;
+
+out-free:
+ free(dir-path);
+
+out-failure:
+ return count;
+}
+
+static int mod-dso+ size-t n;
+
+ if (uname(&uts) < 0)
+ goto out-failure;
+
+ len = strlen("/lib/modules/");
+ len += strlen(uts.release);
+ len += strlen("/modules.dep");
+
+ path = calloc(1, len);
+ if (path == NULL)
+ goto out-failure;
+
+ strcat(path, "/lib/modules/");
+ strcat(path, uts.release);
+ strcat(path, "/modules.dep");
+
+ file = fopen(path, "r");
+ free(path);
+ if (file == NULL)
+ goto out-failure;
+
+ while (!feof(file)) {
+ char *path, *name, *tmp;
+ struct module *module;
+ int line-len, len;
+
+ line-len = getline(&line, &n, file);
+ if (line-len < 0)
+ break;
+
+ if (!line)
+ goto out-failure;
+
+ line[+ name = strtok(name, "/");
+
+ tmp = name;
+
+ while (tmp) {
+ tmp = strtok(NULL, "/");
+ if (tmp)
+ name = tmp;
+ }
+ name = strsep(&name, ".");
+
+ /* Quirk: replace '-' with '-' in sound modules */
+ for (len = strlen(name); len; len+ fprintf(stderr, "load-module-paths: allocation error
");
+ goto out-failure;
+ }
+ mod-dso+
+ module->active = mod-dso+ fclose(file);
+
+ return count;
+
+out-failure:
+ return -1;
+}
+
+int mod-dso+}
diff +#define -PERF-MODULE- 1
+
+#include <linux/types.h>
+#include "../types.h"
+#include <linux/list.h>
+#include <linux/rbtree.h>
+
+struct section {
+ struct rb-node rb-node;
+ u64 hash;
+ u64 vma;
+ char *name;
+ char *path;
+};
+
+struct sec-dso {
+ struct list-head node;
+ struct rb-root secs;
+ struct section *(*find-section)(struct sec-dso *, const char *name);
+ char name[0];
+};
+
+struct module {
+ struct rb-node rb-node;
+ u64 hash;
+ char *name;
+ char *path;
+ struct sec-dso *sections;
+ int active;
+};
+
+struct mod-dso {
+ struct list-head node;
+ struct rb-root mods;
+ struct module *(*find-module)(struct mod-dso *, const char *name);
+ char name[0];
+};
+
+struct sec-dso *sec-dso+void mod-dso
tip:perfcounters/urgent - perf_counter tools: Enable kernel module symbol loading in tools by tip-bot for Mike Galbraith on
2009-07-02T07:08:08+00:00
Commit-ID: 429764873cf3fc3e73142872a674bb27cda589c1
Gitweb: http://git.kernel.org/tip/429764873cf3fc3e73142872a674bb27cda589c1
Author: Mike Galbraith <efault@gmx.de>
AuthorDate: Thu, 2 Jul 2009 08:09:46 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 08:42:21 +0200
perf-counter tools: Enable kernel module symbol loading in tools
Add the -m/Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246514986.13293.48.camel@marge.simson.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-diff
+static int modules;
+
+static int full-paths;
+
static int print-line;
static unsigned long page-size;
@@ -171,7 +175,7 @@ static int load-kernel(void)
if (!kernel-dso)
return -1;
- err = dso static void annotate-sym(struct dso *dso, struct symbol *sym)
{
- char *filename = dso->name;
+ char *filename = dso->name, *d-filename;
u64 start, end, len;
char command[PATH-MAX*2];
FILE *file;
if (!filename)
return;
- if (dso == kernel-dso)
+ if (sym->module)
+ filename = sym->module->path;
+ else if (dso == kernel-dso)
filename = vmlinux;
start = sym->obj-start;
if (!start)
start = sym->start;
+ if (full-paths)
+ d-filename = filename;
+ else
+ d-filename = basename(filename);
end = start + sym->end - sym->start + 1;
len = sym->end - sym->start;
@@ -1291,13 +1301,14 @@ static void annotate-sym(struct dso *dso, struct symbol *sym)
}
printf("
- sprintf(command, "objdump OPT-BOOLEAN('D', "dump-raw-trace", &dump-trace,
"dump raw trace in ASCII"),
OPT-STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT-BOOLEAN('m', "modules", &modules,
+ "load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT-BOOLEAN('l', "print-line", &print-line,
"print matching source lines (may be slow)"),
+ OPT-BOOLEAN('P', "full-paths", &full-paths,
+ "Don't shorten the displayed pathnames"),
OPT-END()
};
diff
+static int modules;
+
static int full-paths;
static unsigned long page-size;
@@ -188,7 +190,7 @@ static int load-kernel(void)
if (!kernel-dso)
return -1;
- err = dso self->dso == kernel-dso ? 'k' :
self->dso == hypervisor-dso ? 'h' : '.', self->sym->name);
+
+ if (self->sym->module)
+ ret += fprintf(fp, " [%s]", self->sym->module->name);
} else {
ret += fprintf(fp, "%#016llx", (u64)self->ip);
}
@@ -1710,6 +1715,8 @@ static const struct option options[] = {
OPT-BOOLEAN('D', "dump-raw-trace", &dump-trace,
"dump raw trace in ASCII"),
OPT-STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+ OPT-BOOLEAN('m', "modules", &modules,
+ "load module symbols - WARNING: use only with -k and LIVE kernel"),
OPT-STRING('s', "sort", &sort-order, "key[,key2...]",
"sort by key(s): pid, comm, dso, symbol, parent"),
OPT-BOOLEAN('P', "full-paths", &full-paths,
diff static int verbose = 0;
+static char *vmlinux = NULL;
static char *sym-filter;
static unsigned long filter-start;
@@ -265,7 +266,10 @@ static void print-sym-table(void)
printf("%9.1f %10ld - ", syme->weight, syme->snap-count);
color-fprintf(stdout, color, "%4.1f%%", pcnt);
- printf(" - %016llx : %s
", sym->start, sym->name);
+ printf(" - %016llx : %s", sym->start, sym->name);
+ if (sym->module)
+ printf(" [%s]", sym->module->name);
+ printf("
");
}
}
@@ -359,12 +363,13 @@ static int parse-symbols(void)
{
struct rb-node *node;
struct symbol *sym;
+ int modules = vmlinux ? 1 : 0;
kernel-dso = dso
node = rb-first(&kernel-dso->syms);
@@ -680,6 +685,7 @@ static const struct option options[] = {
"system-wide collection from all CPUs"),
OPT-INTEGER('C', "CPU", &profile-cpu,
"CPU to profile on"),
+ OPT-STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
OPT-INTEGER('m', "mmap-pages", &mmap-pages,
"number of mmap data pages"),
OPT-INTEGER('r', "realtime", &realtime-prio,
@@ -709,6 +715,8 @@ int cmd-top(int argc, const char **argv, const char *prefix
argc = parse-options(argc, argv, options, top-usage, 0);
tip:perfcounters/urgent - perf_counter tools: Connect module support infrastructure to symbol loading infrastructure by tip-bot for Mike Galbraith on
2009-07-02T07:08:40+00:00
Commit-ID: 6cfcc53ed4f3ecb9319e73a03f34f1eddcb644dd
Gitweb: http://git.kernel.org/tip/6cfcc53ed4f3ecb9319e73a03f34f1eddcb644dd
Author: Mike Galbraith <efault@gmx.de>
AuthorDate: Thu, 2 Jul 2009 08:08:36 +0200
Committer: Ingo Molnar <mingo@elte.hu>
CommitDate: Thu, 2 Jul 2009 08:42:21 +0200
perf-counter tools: Connect module support infrastructure to symbol loading infrastructure
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <1246514916.13293.46.camel@marge.simson.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-diff
- err = dso+ err = dso+++ b/tools/perf/builtin-top.c
@@ -364,7 +364,7 @@ static int parse-symbols(void)
if (kernel-dso == NULL)
return -1;
- if (dso+ self->end = len ? start + len - 1 : start;
memcpy(self->name, name, namelen);
return self;
@@ -48,8 +48,12 @@ static void symbol self->start, self->end, self->name);
+ else
+ return fprintf(fp, " %llx-%llx %s [%s]
",
+ self->start, self->end, self->name, self->module->name);
}
struct dso *dso+ return elf-sym+ const Elf-Data *secstrs)
+{
+ return secstrs->d-buf + shdr->sh-name;
+}
+
+static inline int elf-sec const Elf-Data *symstrs)
{
@@ -451,9 +475,9 @@ static int dso- Elf-Data *symstrs;
+ Elf-Data *symstrs, *secstrs;
uint32-t nr-syms;
int err = -1;
uint32-t index;
@@ -461,7 +485,7 @@ static int dso size-t dynsym-idx;
int nr = 0;
@@ -520,6 +544,14 @@ static int dso+
+ secstrs = elf-getdata(sec-strndx, NULL);
+ if (symstrs == NULL)
+ goto out-elf-end;
+
nr-syms = shdr.sh-size / shdr.sh-entsize;
memset(&sym, 0, sizeof(sym));
@@ -529,8 +561,11 @@ static int dso
- if (!elf-sym
gelf-getshdr(sec, &shdr);
+
+ if (is-label && !elf-sec@@ -548,6 +588,17 @@ static int dso+ sym.st-value += section->vma;
+ else {
+ fprintf(stderr, "dso elf-sym dso- ret = dso }
+static int dso+ return err;
+
+ fd = open(mod->path, O-RDONLY);
+
+ if (fd < 0)
+ return err;
+
+ err = dso+{
+ struct mod-dso *mods = mod-dso+ if (err <= 0)
+ return err;
+
+ /*
+ * Iterate over modules, and load active symbols.
+ */
+ next = rb-first(&mods->mods);
+ while (next) {
+ pos = rb-entry(next, struct module, rb-node);
+ err = dso+
+ if (err < 0) {
+ mod-dso+static inline void dso+
+ if (prev) {
+ u64 hole = 0;
+ int alias = pos->start == prev->start;
+
+ if (!alias)
+ hole = prev->start - pos->end - 1;
+
+ if (hole || alias) {
+ if (alias)
+ pos->end = prev->end;
+ else if (hole)
+ pos->end = prev->start - 1;
+ }
+ }
+ prev = pos;
+ }
+}
+
static int dso- err = dso
return err;
}
int dso+ if (vmlinux) {
err = dsodiff #include <linux/rbtree.h>
+#include "module.h"
struct symbol {
struct rb-node rb-node;
@@ -13,6 +14,7 @@ struct symbol {
u64 obj-start;
u64 hist-sum;
u64 *hist;
+ struct module *module;
void *priv;
char name[0];
};
@@ -41,7 +43,8 @@ static inline void *dso int dsoPlease read the FAQ at http://www.tux.org/lkml/
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-02T07:18:27+00:00
On Thu, 2009-07-02 at 08:47 +0200, Ingo Molnar wrote:
> * Mike Galbraith <efault@gmx.de> wrote:
>
> > Per $subject, this patch set only supports for the LIVE kernel.
> > It adds support infrastructure for path discovery, load address
> > lookup, and symbol generation of live kernel modules.
> >
> > TODO includes resurrection of live annotation in perf top, and
> > support for annotation and report generation of other than live
> > modules. As the patch set sits, Perf top can generate symbols
> > from live binaries, but there's no live annotation capability yet.
> >
> > patch1: perf-counter tools: Make symbol loading consistently return number of loaded symbols.
> > patch2: perf-counter tools: Add infrastructure to support loading of kernel module symbols
> > patch3: perf-counter tools: connect module support infrastructure to symbol loading infrastructure
> > patch4: perf-counter tools: Enable kernel module symbol loading in tools
> >
> > Comments and suggestions most welcome.
>
> Looks very nice! I've applied it with a few minor stylistic fixlets
> and a tad more verbose changelogs.
Thanks!
(sorry about changelogs, I did stare at them, nothing spiffy happened)
> I'm wondering about the next step: couldnt we somehow guess at the
> position of the vmlinux too, validate somehow that it corresponds to
> the kernel we are running - and then use it automatically and by
> default?
I don't know of a way to discover where the image lives. Been pondering
that very thing, along with idiot-proofing.
> Plus, offline analysis would be nice as well i suspect - being able
> to look at profiles on a different box?
Yes, that's high on my TODO. I've been pondering a perf archive tool
that would package everything that's needed to do analysis on a
different box. One big problem though, is that while you can easily
package vmlinux and modules, what about all the userland binaries? A
large perf.data and/or debug info binaries can easily make transport
impractical enough.
After I resurrect (well, try) live annotation in top, I'll fiddle with
offline kernel analysis.
-Mike
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-02T07:42:45+00:00
* Mike Galbraith <efault@gmx.de> wrote:
> On Thu, 2009-07-02 at 08:47 +0200, Ingo Molnar wrote:
> > * Mike Galbraith <efault@gmx.de> wrote:
> >
> > > Per $subject, this patch set only supports for the LIVE kernel.
> > > It adds support infrastructure for path discovery, load address
> > > lookup, and symbol generation of live kernel modules.
> > >
> > > TODO includes resurrection of live annotation in perf top, and
> > > support for annotation and report generation of other than live
> > > modules. As the patch set sits, Perf top can generate symbols
> > > from live binaries, but there's no live annotation capability yet.
> > >
> > > patch1: perf-counter tools: Make symbol loading consistently return number of loaded symbols.
> > > patch2: perf-counter tools: Add infrastructure to support loading of kernel module symbols
> > > patch3: perf-counter tools: connect module support infrastructure to symbol loading infrastructure
> > > patch4: perf-counter tools: Enable kernel module symbol loading in tools
> > >
> > > Comments and suggestions most welcome.
> >
> > Looks very nice! I've applied it with a few minor stylistic fixlets
> > and a tad more verbose changelogs.
>
> Thanks!
>
> (sorry about changelogs, I did stare at them, nothing spiffy
> happened)
[ We want to be verbose in changelogs generally - i.e. it's not a
problem at all to tell a boring story about what happens in the
patch. To -you- it certainly looks boring - to others it's a
useful summary that sets their mind-set before looking at the
patch. ]
> > I'm wondering about the next step: couldnt we somehow guess at
> > the position of the vmlinux too, validate somehow that it
> > corresponds to the kernel we are running - and then use it
> > automatically and by default?
>
> I don't know of a way to discover where the image lives. Been
> pondering that very thing, along with idiot-proofing.
There's two main usecases:
- distro kernels. Here the vmlinux and module path varies but
should be discoverable with a finite list of try-and-err paths.
- 'make install modules-install' builds of kernel developers. Here
the vmlinux and the source tree might be anywhere. A small trick
might help: we could expose the build position of the kernel
source tree via a new /proc/kernel-buildpath special file, which
contains the vmlinux filename plus an MD5 sum (or CRC32) for good
measure.
Note that /proc/kernel-buildpath might also help the distro case: a
distro could set it thusly to have the correct position for a
debuginfo rpm/deb install.
I.e. /proc/kernel-buildpath and the MD5 could solve both usecases.
Other tools could make use of it too.
A second, more complex possibility would be to expose the kernel
image itself plus the module images as well. This has limitations
though: debuginfo wont be embedded, and symbols are in
/proc/kallsyms (which we do parse).
The advantage is that it's all readily available in memory (just not
exposed), plus it would show the -real- instructions - the
post-paravirt-fixup post-ftrace-fixup and other dynamic patching
results.
To expose that we'd have to create some sort of special "kernel
image directory" within debugfs that has files like:
/debug/kimage/vmlinux
/debug/kimage/modules/
/debug/kimage/modules/snd-hda-intel.ko
/debug/kimage/modules/firewire-core.ko
Debugfs is quite easy to use and if we dont make it too fancy (no
separate module directories for example) it would be doable without
too much fuss.
It would be assembly-only annotations, without debuginfo.
> > Plus, offline analysis would be nice as well i suspect - being
> > able to look at profiles on a different box?
>
> Yes, that's high on my TODO. I've been pondering a perf archive
> tool that would package everything that's needed to do analysis on
> a different box. One big problem though, is that while you can
> easily package vmlinux and modules, what about all the userland
> binaries? A large perf.data and/or debug info binaries can easily
> make transport impractical enough.
I wouldnt worry about size too much, at least initially.
[ If it ever becomes a big issue then we could do a separate 'perf
compress' pass which could do a 'specific'/sparse snapshot of
affected binaries: i.e. pre-parse the data file, pick out all the
RIPs that matter and check which binaries relate to them, and then
read and pack those bits only. ]
Plus we could use Git's zlib smarts to compress the data file on the
fly as well, during data capture. It's very easy to generate a gig
or two of data currently.
> After I resurrect (well, try) live annotation in top, I'll fiddle
> with offline kernel analysis.
Ok :-)
Btw, another thing: we are thinking about making -F 1000 (1 KHz
auto-freq sampling) the default for perf top and perf record. This
way we'd always gather enough data (and never too much or too little
data), regardless of the intensity of the workload. Have you played
with -F before, what's your general experience about it? It's
particularly useful for 'rare' and highly fluctuating events like
cache-misses.
Maybe 1KHz is a bit too low - Oprofile defaults to 100000 cycles
interval by default which is about 10 KHz on a 1GHz box and 30 KHz
on a 3GHz box. Perhaps 10 KHz is a better default?
Ingo
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-02T07:56:05+00:00
On Thu, 2009-07-02 at 09:42 +0200, Ingo Molnar wrote:
(squirrels suggestions away for later reference)
> Btw, another thing: we are thinking about making -F 1000 (1 KHz
> auto-freq sampling) the default for perf top and perf record. This
> way we'd always gather enough data (and never too much or too little
> data), regardless of the intensity of the workload. Have you played
> with -F before, what's your general experience about it? It's
> particularly useful for 'rare' and highly fluctuating events like
> cache-misses.
>
> Maybe 1KHz is a bit too low - Oprofile defaults to 100000 cycles
> interval by default which is about 10 KHz on a 1GHz box and 30 KHz
> on a 3GHz box. Perhaps 10 KHz is a better default?
My default usage is 1000Hz to keep overhead low. Works fine for me.
-Mike
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-02T08:43:21+00:00
On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> After I resurrect (well, try) live annotation in top...
Random thought wrt live top annotation: instead of resurrecting in the
previous form, which could be a bit intrusive display space wise, what
do you think of this idea?
Provide a kbd input snapshot trigger which builds a perf record (hard?)
compatible file for the symbols being displayed. Start a background
task to annotate the lot, stuffing annotate output into an output file.
Better ideas highly welcome.
-Mike
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-02T08:54:02+00:00
On Thu, 2009-07-02 at 10:42 +0200, Mike Galbraith wrote:
> Provide a kbd input snapshot trigger which builds a perf record (hard?)
> compatible file for the symbols being displayed. Start a background
> task to annotate the lot, stuffing annotate output into an output file.
(P.S. I'm thinking of dirt simple performance issue reporting method)
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Peter Zijlstra on
2009-07-02T12:11:17+00:00
On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> I've been pondering a perf archive tool
> that would package everything that's needed to do analysis on a
> different box. One big problem though, is that while you can easily
> package vmlinux and modules, what about all the userland binaries? A
> large perf.data and/or debug info binaries can easily make transport
> impractical enough.
I would simply extend the current file header with another section in
which we do a structured storage of the data structures we currently
build in perf-report. That is, the dso and symbol bits.
If we then run perf-report on a file containing such a section we read
that data instead of trying to locate them the regular way.
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-03T07:18:01+00:00
On Thu, 2009-07-02 at 14:10 +0200, Peter Zijlstra wrote:
> On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
>
> > I've been pondering a perf archive tool
> > that would package everything that's needed to do analysis on a
> > different box. One big problem though, is that while you can easily
> > package vmlinux and modules, what about all the userland binaries? A
> > large perf.data and/or debug info binaries can easily make transport
> > impractical enough.
>
> I would simply extend the current file header with another section in
> which we do a structured storage of the data structures we currently
> build in perf-report. That is, the dso and symbol bits.
>
> If we then run perf-report on a file containing such a section we read
> that data instead of trying to locate them the regular way.
That's a good idea.
If uname doesn't match stored record time uname, you're not live, so
tools require an exportable perf.data. If you're not live and not on
the same host, annotate requires binaries appended via an export tool
with More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-03T07:24:33+00:00
* Mike Galbraith <efault@gmx.de> wrote:
> On Thu, 2009-07-02 at 14:10 +0200, Peter Zijlstra wrote:
> > On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> >
> > > I've been pondering a perf archive tool
> > > that would package everything that's needed to do analysis on a
> > > different box. One big problem though, is that while you can easily
> > > package vmlinux and modules, what about all the userland binaries? A
> > > large perf.data and/or debug info binaries can easily make transport
> > > impractical enough.
> >
> > I would simply extend the current file header with another section in
> > which we do a structured storage of the data structures we currently
> > build in perf-report. That is, the dso and symbol bits.
> >
> > If we then run perf-report on a file containing such a section we read
> > that data instead of trying to locate them the regular way.
>
> That's a good idea.
>
> If uname doesn't match stored record time uname, you're not live,
> so tools require an exportable perf.data. If you're not live and
> not on the same host, annotate requires binaries appended via an
> export tool with the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-03T07:27:50+00:00
* Mike Galbraith <efault@gmx.de> wrote:
> On Thu, 2009-07-02 at 09:42 +0200, Ingo Molnar wrote:
>
> (squirrels suggestions away for later reference)
>
> > Btw, another thing: we are thinking about making -F 1000 (1 KHz
> > auto-freq sampling) the default for perf top and perf record. This
> > way we'd always gather enough data (and never too much or too little
> > data), regardless of the intensity of the workload. Have you played
> > with -F before, what's your general experience about it? It's
> > particularly useful for 'rare' and highly fluctuating events like
> > cache-misses.
> >
> > Maybe 1KHz is a bit too low - Oprofile defaults to 100000 cycles
> > interval by default which is about 10 KHz on a 1GHz box and 30
> > KHz on a 3GHz box. Perhaps 10 KHz is a better default?
>
> My default usage is 1000Hz to keep overhead low. Works fine for
> me.
ah, so you use -F by default?
I still think 10 KHz would be better - especially for really short
runs like 'perf record -f -g ./git gc'. Since Oprofile samples at 26
KHz by default, we must not go to a too low frequency, otherwise
people might get a 'hm, the perf profiles are worse than the
Oprofile ones' first impression ...
We could perhaps add a freq=1000 switch to .perfconfig - we have
Git's util/config.c facility - it's just unused right now ;-)
[ Look at the Git sources about how config.c is used. ]
Ingo
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-03T07:30:09+00:00
* Mike Galbraith <efault@gmx.de> wrote:
> On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
>
> > After I resurrect (well, try) live annotation in top...
>
> Random thought wrt live top annotation: instead of resurrecting in
> the previous form, which could be a bit intrusive display space
> wise, what do you think of this idea?
>
> Provide a kbd input snapshot trigger which builds a perf record
> (hard?) compatible file for the symbols being displayed. Start a
> background task to annotate the lot, stuffing annotate output into
> an output file.
>
> Better ideas highly welcome.
Hm, is there really a performance problem?
We need to calculate and cache the objdump annotation output once,
but after that it should be pretty fast as we just display updated
counts with the same lines over and over again. No repeated objdump
runs are needed.
Ingo
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Jaswinder Singh Rajput on
2009-07-03T07:33:04+00:00
On Fri, 2009-07-03 at 09:24 +0200, Ingo Molnar wrote:
> * Mike Galbraith <efault@gmx.de> wrote:
>
> > On Thu, 2009-07-02 at 14:10 +0200, Peter Zijlstra wrote:
> > > On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> > >
> > > > I've been pondering a perf archive tool
> > > > that would package everything that's needed to do analysis on a
> > > > different box. One big problem though, is that while you can easily
> > > > package vmlinux and modules, what about all the userland binaries? A
> > > > large perf.data and/or debug info binaries can easily make transport
> > > > impractical enough.
> > >
> > > I would simply extend the current file header with another section in
> > > which we do a structured storage of the data structures we currently
> > > build in perf-report. That is, the dso and symbol bits.
> > >
> > > If we then run perf-report on a file containing such a section we read
> > > that data instead of trying to locate them the regular way.
> >
> > That's a good idea.
> >
> > If uname doesn't match stored record time uname, you're not live,
> > so tools require an exportable perf.data. If you're not live and
> > not on the same host, annotate requires binaries appended via an
> > export tool with
perf export and perf import
http://userweb.kernel.org/~jaswinder/
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-03T07:36:46+00:00
On Fri, 2009-07-03 at 09:27 +0200, Ingo Molnar wrote:
> * Mike Galbraith <efault@gmx.de> wrote:
>
> > On Thu, 2009-07-02 at 09:42 +0200, Ingo Molnar wrote:
> >
> > (squirrels suggestions away for later reference)
> >
> > > Btw, another thing: we are thinking about making -F 1000 (1 KHz
> > > auto-freq sampling) the default for perf top and perf record. This
> > > way we'd always gather enough data (and never too much or too little
> > > data), regardless of the intensity of the workload. Have you played
> > > with -F before, what's your general experience about it? It's
> > > particularly useful for 'rare' and highly fluctuating events like
> > > cache-misses.
> > >
> > > Maybe 1KHz is a bit too low - Oprofile defaults to 100000 cycles
> > > interval by default which is about 10 KHz on a 1GHz box and 30
> > > KHz on a 3GHz box. Perhaps 10 KHz is a better default?
> >
> > My default usage is 1000Hz to keep overhead low. Works fine for
> > me.
>
> ah, so you use -F by default?
Yes.
> I still think 10 KHz would be better - especially for really short
> runs like 'perf record -f -g ./git gc'. Since Oprofile samples at 26
> KHz by default, we must not go to a too low frequency, otherwise
> people might get a 'hm, the perf profiles are worse than the
> Oprofile ones' first impression ...
>
> We could perhaps add a freq=1000 switch to .perfconfig - we have
> Git's util/config.c facility - it's just unused right now ;-)
>
> [ Look at the Git sources about how config.c is used. ]
Yeah, that's a good idea.. everyone can roll their own defaults.
For me, it doesn't matter what the default is, I always specify.
-Mike
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-03T08:01:26+00:00
On Fri, 2009-07-03 at 09:29 +0200, Ingo Molnar wrote:
> * Mike Galbraith <efault@gmx.de> wrote:
>
> > On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> >
> > > After I resurrect (well, try) live annotation in top...
> >
> > Random thought wrt live top annotation: instead of resurrecting in
> > the previous form, which could be a bit intrusive display space
> > wise, what do you think of this idea?
> >
> > Provide a kbd input snapshot trigger which builds a perf record
> > (hard?) compatible file for the symbols being displayed. Start a
> > background task to annotate the lot, stuffing annotate output into
> > an output file.
> >
> > Better ideas highly welcome.
>
> Hm, is there really a performance problem?
Sort of..
> We need to calculate and cache the objdump annotation output once,
> but after that it should be pretty fast as we just display updated
> counts with the same lines over and over again. No repeated objdump
> runs are needed.
But active files follow symbols, which change on the fly.
Besides, as mentioned previously, while displayed annotation was very
cool, it took a lot of display space. For me, top with the ability to
emit bic-disposable mini-reports would be my primary perf tools usage.
I'd only use big brothers when I needed their power/detail.
-Mike
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-03T08:16:42+00:00
* Mike Galbraith <efault@gmx.de> wrote:
> > We need to calculate and cache the objdump annotation output
> > once, but after that it should be pretty fast as we just display
> > updated counts with the same lines over and over again. No
> > repeated objdump runs are needed.
>
> But active files follow symbols, which change on the fly.
>
> Besides, as mentioned previously, while displayed annotation was
> very cool, it took a lot of display space. For me, top with the
> ability to emit bic-disposable mini-reports would be my primary
> perf tools usage. I'd only use big brothers when I needed their
> power/detail.
Ok, then how about putting some sort of interactivity into perf top?
Up and down arrows would allow the walking of the histogram, and
hitting enter on a symbol would show the annotated function? It
would be way cool and more usable and more flexible than some
side-channel for mini-reports.
PowerTop has a lot of good text interactivity code that might be
reused. (assuming it's under a kernel compatible license?)
There's also the 'tig' tool - an interactive tool to walk Git
trees/commits. If it's under a compatible license that would be a
nice place to look for clues too - it has a very mature and
well-thought-out TUI in my opinion.
Ingo
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Mike Galbraith on
2009-07-03T08:35:56+00:00
On Fri, 2009-07-03 at 10:15 +0200, Ingo Molnar wrote:
> * Mike Galbraith <efault@gmx.de> wrote:
>
> > > We need to calculate and cache the objdump annotation output
> > > once, but after that it should be pretty fast as we just display
> > > updated counts with the same lines over and over again. No
> > > repeated objdump runs are needed.
> >
> > But active files follow symbols, which change on the fly.
> >
> > Besides, as mentioned previously, while displayed annotation was
> > very cool, it took a lot of display space. For me, top with the
> > ability to emit bic-disposable mini-reports would be my primary
> > perf tools usage. I'd only use big brothers when I needed their
> > power/detail.
>
> Ok, then how about putting some sort of interactivity into perf top?
>
> Up and down arrows would allow the walking of the histogram, and
> hitting enter on a symbol would show the annotated function? It
> would be way cool and more usable and more flexible than some
> side-channel for mini-reports.
>
> PowerTop has a lot of good text interactivity code that might be
> reused. (assuming it's under a kernel compatible license?)
>
> There's also the 'tig' tool - an interactive tool to walk Git
> trees/commits. If it's under a compatible license that would be a
> nice place to look for clues too - it has a very mature and
> well-thought-out TUI in my opinion.
Cool. I love free samples to bend/spindle/mutilate :)
-Mike
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Frederic Weisbecker on
2009-07-03T08:41:36+00:00
On Fri, Jul 03, 2009 at 09:17:39AM +0200, Mike Galbraith wrote:
> On Thu, 2009-07-02 at 14:10 +0200, Peter Zijlstra wrote:
> > On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> >
> > > I've been pondering a perf archive tool
> > > that would package everything that's needed to do analysis on a
> > > different box. One big problem though, is that while you can easily
> > > package vmlinux and modules, what about all the userland binaries? A
> > > large perf.data and/or debug info binaries can easily make transport
> > > impractical enough.
> >
> > I would simply extend the current file header with another section in
> > which we do a structured storage of the data structures we currently
> > build in perf-report. That is, the dso and symbol bits.
> >
> > If we then run perf-report on a file containing such a section we read
> > that data instead of trying to locate them the regular way.
>
> That's a good idea.
>
> If uname doesn't match stored record time uname, you're not live, so
> tools require an exportable perf.data. If you're not live and not on
> the same host, annotate requires binaries appended via an export tool
> with
(1) comparing different workloads with a same executable.
(2) comparing different executable versions for a same workload
(3) (1) + (2) ?
For the (2), having self contained record files as operands would let
comparisons based on symbols, pretty useful when you have to compare
two different vmlinux (or whatever binary executable).
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Ingo Molnar on
2009-07-03T08:54:07+00:00
* Frederic Weisbecker <fweisbec@gmail.com> wrote:
> On Fri, Jul 03, 2009 at 09:17:39AM +0200, Mike Galbraith wrote:
> > On Thu, 2009-07-02 at 14:10 +0200, Peter Zijlstra wrote:
> > > On Thu, 2009-07-02 at 09:17 +0200, Mike Galbraith wrote:
> > >
> > > > I've been pondering a perf archive tool
> > > > that would package everything that's needed to do analysis on a
> > > > different box. One big problem though, is that while you can easily
> > > > package vmlinux and modules, what about all the userland binaries? A
> > > > large perf.data and/or debug info binaries can easily make transport
> > > > impractical enough.
> > >
> > > I would simply extend the current file header with another section in
> > > which we do a structured storage of the data structures we currently
> > > build in perf-report. That is, the dso and symbol bits.
> > >
> > > If we then run perf-report on a file containing such a section we read
> > > that data instead of trying to locate them the regular way.
> >
> > That's a good idea.
> >
> > If uname doesn't match stored record time uname, you're not live, so
> > tools require an exportable perf.data. If you're not live and not on
> > the same host, annotate requires binaries appended via an export tool
> > with >
> (1) comparing different workloads with a same executable.
> (2) comparing different executable versions for a same workload
> (3) (1) + (2) ?
>
> For the (2), having self contained record files as operands would
> let comparisons based on symbols, pretty useful when you have to
> compare two different vmlinux (or whatever binary executable).
very good points.
Ingo
Re: patch 0/4 - perf_counter tools: support annotation of live kernel modules by Frederic Weisbecker on
2009-07-03T08:54:25+00:00
On Fri, Jul 03, 2009 at 10:28:44AM +0200, Mike Galbraith wrote:
> On Fri, 2009-07-03 at 10:15 +0200, Ingo Molnar wrote:
> > * Mike Galbraith <efault@gmx.de> wrote:
> >
> > > > We need to calculate and cache the objdump annotation output
> > > > once, but after that it should be pretty fast as we just display
> > > > updated counts with the same lines over and over again. No
> > > > repeated objdump runs are needed.
> > >
> > > But active files follow symbols, which change on the fly.
> > >
> > > Besides, as mentioned previously, while displayed annotation was
> > > very cool, it took a lot of display space. For me, top with the
> > > ability to emit bic-disposable mini-reports would be my primary
> > > perf tools usage. I'd only use big brothers when I needed their
> > > power/detail.
> >
> > Ok, then how about putting some sort of interactivity into perf top?
> >
> > Up and down arrows would allow the walking of the histogram, and
> > hitting enter on a symbol would show the annotated function? It
> > would be way cool and more usable and more flexible than some
> > side-channel for mini-reports.
> >
> > PowerTop has a lot of good text interactivity code that might be
> > reused. (assuming it's under a kernel compatible license?)
> >
> > There's also the 'tig' tool - an interactive tool to walk Git
> > trees/commits. If it's under a compatible license that would be a
> > nice place to look for clues too - it has a very mature and
> > well-thought-out TUI in my opinion.
>
> Cool. I love free samples to bend/spindle/mutilate :)
>
> -Mike
The same interactivity could also apply to perf report, by dynamically
expanding callchains, linking to more details with annotate, etc...