diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 534e20d14d631b44cefc136f99200b2257af378f..36f65e2b8b5772f16e644bfa109f89393c893fd3 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c @@ -1503,10 +1503,21 @@ static void perf_counter_enable_on_exec(struct task_struct *task) */ static void __perf_counter_read(void *info) { + struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context); struct perf_counter *counter = info; struct perf_counter_context *ctx = counter->ctx; unsigned long flags; + /* + * If this is a task context, we need to check whether it is + * the current task context of this cpu. If not it has been + * scheduled out before the smp call arrived. In that case + * counter->count would have been updated to a recent sample + * when the counter was scheduled out. + */ + if (ctx->task && cpuctx->task_ctx != ctx) + return; + local_irq_save(flags); if (ctx->is_active) update_context_time(ctx); @@ -2008,6 +2019,10 @@ int perf_counter_task_disable(void) return 0; } +#ifndef PERF_COUNTER_INDEX_OFFSET +# define PERF_COUNTER_INDEX_OFFSET 0 +#endif + static int perf_counter_index(struct perf_counter *counter) { if (counter->state != PERF_COUNTER_STATE_ACTIVE) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 5457192e1b41174e447e1f36d349168e4698c985..bdd3b7ecad0a6dedbf6fc673f7daf3e40c9c49ce 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -35,7 +35,7 @@ man7dir=$(mandir)/man7 # DESTDIR= ASCIIDOC=asciidoc -ASCIIDOC_EXTRA = +ASCIIDOC_EXTRA = --unsafe MANPAGE_XSL = manpage-normal.xsl XMLTO_EXTRA = INSTALL?=install diff --git a/tools/perf/Documentation/perf-examples.txt b/tools/perf/Documentation/examples.txt similarity index 100% rename from tools/perf/Documentation/perf-examples.txt rename to tools/perf/Documentation/examples.txt diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 1dba568e19410d254b9bdfb1401d04316abbe48d..343e7b14bf0118e3ee7d01d9caa0b70462a25fa6 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -980,6 +980,13 @@ process_fork_event(event_t *event, unsigned long offset, unsigned long head) (void *)(long)(event->header.size), event->fork.pid, event->fork.ppid); + /* + * A thread clone will have the same PID for both + * parent and child. + */ + if (thread == parent) + return 0; + if (!thread || !parent || thread__fork(thread, parent)) { dprintf("problem processing PERF_EVENT_FORK, skipping event.\n"); return -1; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 3d051b9cf25ff18790edbb1cd33a7f644ece2dc0..89a5ddcd1ded753e6835c39935989d4c96ac2fdd 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -219,7 +219,7 @@ static pid_t pid_synthesize_comm_event(pid_t pid, int full) snprintf(filename, sizeof(filename), "/proc/%d/status", pid); fp = fopen(filename, "r"); - if (fd == NULL) { + if (fp == NULL) { /* * We raced with a task exiting - just return: */