Patches contributed by Eötvös Lorand University
commit b7f797cb600fa88de04903be4df3c8a6cb1cb35c
Merge: 99bd0c0fc4b0 0017c869ddcb
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Jun 22 10:24:43 2009 +0200
Merge branch 'for-tip' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu into x86/urgent
commit c1f47b454ce759d7b13604137a233cad4617e1e8
Author: Ingo Molnar <mingo@elte.hu>
Date: Sun Jun 21 13:58:51 2009 +0200
perf_counter tools: Fix vmlinux fallback when running on a different kernel
Lucas De Marchi reported that perf report and perf annotate
displays mismatching profile if a perf.data is analyzed on
an older kernel - even if the correct vmlinux is specified
via the -k option.
The reason is the fallback path in util/symbol.c:dso__load_kernel():
int dso__load_kernel(struct dso *self, const char *vmlinux,
symbol_filter_t filter, int verbose)
{
int err = -1;
if (vmlinux)
err = dso__load_vmlinux(self, vmlinux, filter, verbose);
if (err)
err = dso__load_kallsyms(self, filter, verbose);
return err;
}
dso__load_vmlinux() returns negative on error, but on success it
returns the number of symbols loaded - which confuses the function
to load the kallsyms.
This is normally harmless, as reporting is usually performed on the
same kernel that is analyzed - but if there's a mismatch then we
load the wrong kallsyms and create a non-sensical symbol tree.
The fix is to only fall back to kallsyms on errors.
Reported-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 86e14375e74e..01b62fa03996 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -629,7 +629,7 @@ int dso__load_kernel(struct dso *self, const char *vmlinux,
if (vmlinux)
err = dso__load_vmlinux(self, vmlinux, filter, verbose);
- if (err)
+ if (err < 0)
err = dso__load_kallsyms(self, filter, verbose);
return err;
commit d4c4038343510d83727ea922de4435996c26c0c8
Merge: 3daeb4da9a0b 71e308a239c0
Author: Ingo Molnar <mingo@elte.hu>
Date: Sat Jun 20 18:26:48 2009 +0200
Merge branch 'tip/tracing/urgent-1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into tracing/urgent
commit 3daeb4da9a0b056bdc4af003e5605c1da4c0b068
Merge: 9ea1a153a4fb 4b221f0313f0
Author: Ingo Molnar <mingo@elte.hu>
Date: Sat Jun 20 17:25:49 2009 +0200
Merge branch 'tip/tracing/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into tracing/urgent
commit 1d99100120ead486cd7a2502f19eaf1c1699d806
Merge: bc3f5d3dbd57 b1f49f9582f9
Author: Ingo Molnar <mingo@elte.hu>
Date: Sat Jun 20 10:54:22 2009 +0200
Merge branch 'x86/mce3' into x86/urgent
commit 0c87197142427063e096f11603543ca874045952
Author: Ingo Molnar <mingo@elte.hu>
Date: Mon Jun 15 11:35:01 2009 +0200
perf_counter, x86: Improve interactions with fast-gup
Improve a few details in perfcounter call-chain recording that
makes use of fast-GUP:
- Use ACCESS_ONCE() to observe the pte value. ptes are fundamentally
racy and can be changed on another CPU, so we have to be careful
about how we access them. The PAE branch is already careful with
read-barriers - but the non-PAE and 64-bit side needs an
ACCESS_ONCE() to make sure the pte value is observed only once.
- make the checks a bit stricter so that we can feed it any kind of
cra^H^H^H user-space input ;-)
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index b685ece89d5c..512ee87062c2 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -25,7 +25,12 @@
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(-1UL)
-#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
+
+#ifdef CONFIG_X86_32
+# define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
+#else
+# define USER_DS MAKE_MM_SEG(__VIRTUAL_MASK)
+#endif
#define get_ds() (KERNEL_DS)
#define get_fs() (current_thread_info()->addr_limit)
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
index 697d5727c119..2d1d784ad3f7 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -14,7 +14,7 @@
static inline pte_t gup_get_pte(pte_t *ptep)
{
#ifndef CONFIG_X86_PAE
- return *ptep;
+ return ACCESS_ONCE(*ptep);
#else
/*
* With get_user_pages_fast, we walk down the pagetables without taking
commit b8e6d829729d1a5991a9f628205b671cac2ec06f
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Jun 18 14:32:19 2009 +0200
perf report: Filter to parent set by default
Make it easier to use parent filtering - default to a filtered
output. Also add the parent column so that we get collapsing but
dont display it by default.
add --no-exclude-other to override this.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 714db7327b94..672c5f069c6e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -164,7 +164,7 @@ endif
# CFLAGS and LDFLAGS are for the users to override from the command line.
-CFLAGS = $(M64) -ggdb3 -Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -O6
+CFLAGS = $(M64) -ggdb3 -Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6
LDFLAGS = -lpthread -lrt -lelf -lm
ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index fe66895111b1..86981bd08f65 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -46,9 +46,12 @@ static int full_paths;
static unsigned long page_size;
static unsigned long mmap_window = 32;
-static char *parent_pattern = "^sys_|^do_page_fault";
+static char default_parent_pattern[] = "^sys_|^do_page_fault";
+static char *parent_pattern = default_parent_pattern;
static regex_t parent_regex;
+static int exclude_other = 1;
+
struct ip_event {
struct perf_event_header header;
__u64 ip;
@@ -742,6 +745,9 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, __u64 total_samples)
struct sort_entry *se;
size_t ret;
+ if (exclude_other && !self->parent)
+ return 0;
+
if (total_samples) {
double percent = self->count * 100.0 / total_samples;
char *color = PERF_COLOR_NORMAL;
@@ -764,6 +770,9 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, __u64 total_samples)
ret = fprintf(fp, "%12Ld ", self->count);
list_for_each_entry(se, &hist_entry__sort_list, list) {
+ if (exclude_other && (se == &sort_parent))
+ continue;
+
fprintf(fp, " ");
ret += se->print(fp, self);
}
@@ -855,6 +864,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
.ip = ip,
.level = level,
.count = count,
+ .parent = NULL,
};
int cmp;
@@ -1029,14 +1039,20 @@ static size_t output__fprintf(FILE *fp, __u64 total_samples)
fprintf(fp, "#\n");
fprintf(fp, "# Overhead");
- list_for_each_entry(se, &hist_entry__sort_list, list)
+ list_for_each_entry(se, &hist_entry__sort_list, list) {
+ if (exclude_other && (se == &sort_parent))
+ continue;
fprintf(fp, " %s", se->header);
+ }
fprintf(fp, "\n");
fprintf(fp, "# ........");
list_for_each_entry(se, &hist_entry__sort_list, list) {
int i;
+ if (exclude_other && (se == &sort_parent))
+ continue;
+
fprintf(fp, " ");
for (i = 0; i < strlen(se->header); i++)
fprintf(fp, ".");
@@ -1050,7 +1066,8 @@ static size_t output__fprintf(FILE *fp, __u64 total_samples)
ret += hist_entry__fprintf(fp, pos, total_samples);
}
- if (!strcmp(sort_order, default_sort_order)) {
+ if (sort_order == default_sort_order &&
+ parent_pattern == default_parent_pattern) {
fprintf(fp, "#\n");
fprintf(fp, "# (For more details, try: perf report --sort comm,dso,symbol)\n");
fprintf(fp, "#\n");
@@ -1508,6 +1525,8 @@ static const struct option options[] = {
"Don't shorten the pathnames taking into account the cwd"),
OPT_STRING('p', "parent", &parent_pattern, "regex",
"regex filter to identify parent, see: '--sort parent'"),
+ OPT_BOOLEAN('x', "exclude-other", &exclude_other,
+ "Only display entries with parent-match"),
OPT_END()
};
@@ -1536,6 +1555,11 @@ int cmd_report(int argc, const char **argv, const char *prefix)
setup_sorting();
+ if (parent_pattern != default_parent_pattern)
+ sort_dimension__add("parent");
+ else
+ exclude_other = 0;
+
/*
* Any (unrecognized) arguments left?
*/
commit 7522060c95395f479ee4a6af3bbf9e097e92e48f
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Jun 18 08:00:17 2009 +0200
perf report: Add validation of call-chain entries
Add boundary checks for call-chain events. In case of corrupted
entries we could crash otherwise.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index eccae437fe37..a7d3a61a59b7 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -337,6 +337,16 @@ enum perf_event_type {
*/
};
+#define MAX_STACK_DEPTH 255
+
+struct perf_callchain_entry {
+ __u16 nr;
+ __u16 hv;
+ __u16 kernel;
+ __u16 user;
+ __u64 ip[MAX_STACK_DEPTH];
+};
+
#ifdef __KERNEL__
/*
* Kernel-internal data types and definitions:
@@ -652,16 +662,6 @@ extern void perf_counter_fork(struct task_struct *tsk);
extern void perf_counter_task_migration(struct task_struct *task, int cpu);
-#define MAX_STACK_DEPTH 255
-
-struct perf_callchain_entry {
- u16 nr;
- u16 hv;
- u16 kernel;
- u16 user;
- u64 ip[MAX_STACK_DEPTH];
-};
-
extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
extern int sysctl_perf_counter_paranoid;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 986834623b43..e14e98676171 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -39,6 +39,8 @@ static int dump_trace = 0;
#define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
static int verbose;
+#define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0)
+
static int full_paths;
static unsigned long page_size;
@@ -47,14 +49,6 @@ static unsigned long mmap_window = 32;
static char *parent_pattern = "^sys_|^do_page_fault";
static regex_t parent_regex;
-struct ip_chain_event {
- __u16 nr;
- __u16 hv;
- __u16 kernel;
- __u16 user;
- __u64 ips[];
-};
-
struct ip_event {
struct perf_event_header header;
__u64 ip;
@@ -131,15 +125,11 @@ static struct dso *dsos__findnew(const char *name)
nr = dso__load(dso, NULL, verbose);
if (nr < 0) {
- if (verbose)
- fprintf(stderr, "Failed to open: %s\n", name);
+ eprintf("Failed to open: %s\n", name);
goto out_delete_dso;
}
- if (!nr && verbose) {
- fprintf(stderr,
- "No symbols found in: %s, maybe install a debug package?\n",
- name);
- }
+ if (!nr)
+ eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
dsos__add(dso);
@@ -844,7 +834,7 @@ static struct symbol *call__match(struct symbol *sym)
static int
hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
- struct symbol *sym, __u64 ip, struct ip_chain_event *chain,
+ struct symbol *sym, __u64 ip, struct perf_callchain_entry *chain,
char level, __u64 count)
{
struct rb_node **p = &hist.rb_node;
@@ -868,7 +858,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
__u64 ip;
for (i = 0; i < chain->kernel; i++) {
- ip = chain->ips[nr + i];
+ ip = chain->ip[nr + i];
dso = kernel_dso;
sym = resolve_symbol(thread, NULL, &dso, &ip);
entry.parent = call__match(sym);
@@ -878,7 +868,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
nr += i;
for (i = 0; i < chain->user; i++) {
- ip = chain->ips[nr + i];
+ ip = chain->ip[nr + i];
sym = resolve_symbol(thread, NULL, NULL, &ip);
entry.parent = call__match(sym);
if (entry.parent)
@@ -1080,6 +1070,30 @@ static unsigned long total = 0,
total_fork = 0,
total_unknown = 0;
+static int validate_chain(struct perf_callchain_entry *chain, event_t *event)
+{
+ unsigned int chain_size;
+
+ if (chain->nr > MAX_STACK_DEPTH)
+ return -1;
+ if (chain->hv > MAX_STACK_DEPTH)
+ return -1;
+ if (chain->kernel > MAX_STACK_DEPTH)
+ return -1;
+ if (chain->user > MAX_STACK_DEPTH)
+ return -1;
+ if (chain->hv + chain->kernel + chain->user != chain->nr)
+ return -1;
+
+ chain_size = event->header.size;
+ chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
+
+ if (chain->nr*sizeof(__u64) > chain_size)
+ return -1;
+
+ return 0;
+}
+
static int
process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
{
@@ -1091,7 +1105,7 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
__u64 period = 1;
struct map *map = NULL;
void *more_data = event->ip.__more_data;
- struct ip_chain_event *chain = NULL;
+ struct perf_callchain_entry *chain = NULL;
if (event->header.type & PERF_SAMPLE_PERIOD) {
period = *(__u64 *)more_data;
@@ -1111,21 +1125,26 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
chain = (void *)more_data;
- if (dump_trace) {
- dprintf("... chain: u:%d, k:%d, nr:%d\n",
- chain->user,
- chain->kernel,
- chain->nr);
+ dprintf("... chain: u:%d, k:%d, nr:%d\n",
+ chain->user,
+ chain->kernel,
+ chain->nr);
+ if (validate_chain(chain, event) < 0) {
+ eprintf("call-chain problem with event, skipping it.\n");
+ return 0;
+ }
+
+ if (dump_trace) {
for (i = 0; i < chain->nr; i++)
- dprintf("..... %2d: %016Lx\n", i, chain->ips[i]);
+ dprintf("..... %2d: %016Lx\n", i, chain->ip[i]);
}
}
dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
if (thread == NULL) {
- fprintf(stderr, "problem processing %d event, skipping it.\n",
+ eprintf("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}
@@ -1153,8 +1172,7 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
- fprintf(stderr,
- "problem incrementing symbol count, skipping event\n");
+ eprintf("problem incrementing symbol count, skipping event\n");
return -1;
}
}
commit b25bcf2f133b1e6216c3d40be394756107d3880f
Author: Ingo Molnar <mingo@elte.hu>
Date: Thu Jun 18 07:01:03 2009 +0200
perf report: Tidy up the "--parent <regex>" and "--sort parent" call-chain features
Instead of the ambigious 'call' naming use the much more
specific 'parent' naming:
- rename --call <regex> to --parent <regex>
- rename --sort call to --sort parent
- rename [unmatched] to [other] - to signal that this is not
an error but the inverse set
Also add pagefaults to the default parent-symbol pattern too,
as it's a 'syscall overhead category' in a sense.
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 707f60ce32fd..986834623b43 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -44,8 +44,8 @@ static int full_paths;
static unsigned long page_size;
static unsigned long mmap_window = 32;
-static char *call = "^sys_";
-static regex_t call_regex;
+static char *parent_pattern = "^sys_|^do_page_fault";
+static regex_t parent_regex;
struct ip_chain_event {
__u16 nr;
@@ -465,7 +465,7 @@ struct hist_entry {
struct map *map;
struct dso *dso;
struct symbol *sym;
- struct symbol *call;
+ struct symbol *parent;
__u64 ip;
char level;
@@ -618,13 +618,13 @@ static struct sort_entry sort_sym = {
.print = sort__sym_print,
};
-/* --sort call */
+/* --sort parent */
static int64_t
-sort__call_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
{
- struct symbol *sym_l = left->call;
- struct symbol *sym_r = right->call;
+ struct symbol *sym_l = left->parent;
+ struct symbol *sym_r = right->parent;
if (!sym_l || !sym_r)
return cmp_null(sym_l, sym_r);
@@ -633,23 +633,23 @@ sort__call_cmp(struct hist_entry *left, struct hist_entry *right)
}
static size_t
-sort__call_print(FILE *fp, struct hist_entry *self)
+sort__parent_print(FILE *fp, struct hist_entry *self)
{
size_t ret = 0;
- ret += fprintf(fp, "%-20s", self->call ? self->call->name : "[unmatched]");
+ ret += fprintf(fp, "%-20s", self->parent ? self->parent->name : "[other]");
return ret;
}
-static struct sort_entry sort_call = {
- .header = "Callchain symbol ",
- .cmp = sort__call_cmp,
- .print = sort__call_print,
+static struct sort_entry sort_parent = {
+ .header = "Parent symbol ",
+ .cmp = sort__parent_cmp,
+ .print = sort__parent_print,
};
static int sort__need_collapse = 0;
-static int sort__has_call = 0;
+static int sort__has_parent = 0;
struct sort_dimension {
char *name;
@@ -662,7 +662,7 @@ static struct sort_dimension sort_dimensions[] = {
{ .name = "comm", .entry = &sort_comm, },
{ .name = "dso", .entry = &sort_dso, },
{ .name = "symbol", .entry = &sort_sym, },
- { .name = "call", .entry = &sort_call, },
+ { .name = "parent", .entry = &sort_parent, },
};
static LIST_HEAD(hist_entry__sort_list);
@@ -683,16 +683,17 @@ static int sort_dimension__add(char *tok)
if (sd->entry->collapse)
sort__need_collapse = 1;
- if (sd->entry == &sort_call) {
- int ret = regcomp(&call_regex, call, REG_EXTENDED);
+ if (sd->entry == &sort_parent) {
+ int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
if (ret) {
char err[BUFSIZ];
- regerror(ret, &call_regex, err, sizeof(err));
- fprintf(stderr, "Invalid regex: %s\n%s", call, err);
+ regerror(ret, &parent_regex, err, sizeof(err));
+ fprintf(stderr, "Invalid regex: %s\n%s",
+ parent_pattern, err);
exit(-1);
}
- sort__has_call = 1;
+ sort__has_parent = 1;
}
list_add_tail(&sd->entry->list, &hist_entry__sort_list);
@@ -831,7 +832,7 @@ static struct symbol *call__match(struct symbol *sym)
if (!sym)
return NULL;
- if (sym->name && !regexec(&call_regex, sym->name, 0, NULL, 0))
+ if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
return sym;
return NULL;
@@ -844,7 +845,7 @@ static struct symbol *call__match(struct symbol *sym)
static int
hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
struct symbol *sym, __u64 ip, struct ip_chain_event *chain,
- char level, __u64 count)
+ char level, __u64 count)
{
struct rb_node **p = &hist.rb_node;
struct rb_node *parent = NULL;
@@ -860,7 +861,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
};
int cmp;
- if (sort__has_call && chain) {
+ if (sort__has_parent && chain) {
int i, nr = chain->hv;
struct symbol *sym;
struct dso *dso;
@@ -870,22 +871,22 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
ip = chain->ips[nr + i];
dso = kernel_dso;
sym = resolve_symbol(thread, NULL, &dso, &ip);
- entry.call = call__match(sym);
- if (entry.call)
- goto got_call;
+ entry.parent = call__match(sym);
+ if (entry.parent)
+ goto got_parent;
}
nr += i;
for (i = 0; i < chain->user; i++) {
ip = chain->ips[nr + i];
sym = resolve_symbol(thread, NULL, NULL, &ip);
- entry.call = call__match(sym);
- if (entry.call)
- goto got_call;
+ entry.parent = call__match(sym);
+ if (entry.parent)
+ goto got_parent;
}
nr += i;
}
-got_call:
+got_parent:
while (*p != NULL) {
parent = *p;
@@ -1457,11 +1458,11 @@ static const struct option options[] = {
"dump raw trace in ASCII"),
OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
- "sort by key(s): pid, comm, dso, symbol. Default: pid,symbol"),
+ "sort by key(s): pid, comm, dso, symbol, parent"),
OPT_BOOLEAN('P', "full-paths", &full_paths,
"Don't shorten the pathnames taking into account the cwd"),
- OPT_STRING('c', "call", &call, "regex",
- "regex to use for --sort call"),
+ OPT_STRING('p', "parent", &parent_pattern, "regex",
+ "regex filter to identify parent, see: '--sort parent'"),
OPT_END()
};
commit 4f6e1fe1d8ba3d9f4fb52dd006da9714d75243cf
Merge: 65795efbd380 b72f7fa9788c
Author: Ingo Molnar <mingo@elte.hu>
Date: Wed Jun 17 19:10:28 2009 +0200
Merge branch 'auto' of git://git.kernel.org/pub/scm/linux/kernel/git/rric/oprofile into oprofile