diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-03 07:22:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-03 07:22:12 -0500 |
commit | 4c3b73c6a2eea0cf27fb058086a0eb94e90bffd4 (patch) | |
tree | 2add808dc63a3f6ec461a95af7ddc6e7a117a331 /kernel | |
parent | 7b367f5dba5c5162a7308e85d3fc9170b0cb3e5f (diff) | |
parent | 85dc600263c2291cea33bffa90038808ee64198b (diff) |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar:
"Misc kernel side fixes:
- fix event leak
- fix AMD PMU driver bug
- fix core event handling bug
- fix build bug on certain randconfigs
Plus misc tooling fixes"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/amd/ibs: Fix pmu::stop() nesting
perf/core: Don't leak event in the syscall error path
perf/core: Fix time tracking bug with multiplexing
perf jit: genelf makes assumptions about endian
perf hists: Fix determination of a callchain node's childlessness
perf tools: Add missing initialization of perf_sample.cpumode in synthesized samples
perf tools: Fix build break on powerpc
perf/x86: Move events_sysfs_show() outside CPU_SUP_INTEL
perf bench: Fix detached tarball building due to missing 'perf bench memcpy' headers
perf tests: Fix tarpkg build test error output redirection
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index de24fbce5277..52bedc5a5aaa 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2417,14 +2417,24 @@ static void ctx_sched_out(struct perf_event_context *ctx, cpuctx->task_ctx = NULL; } - is_active ^= ctx->is_active; /* changed bits */ - + /* + * Always update time if it was set; not only when it changes. + * Otherwise we can 'forget' to update time for any but the last + * context we sched out. For example: + * + * ctx_sched_out(.event_type = EVENT_FLEXIBLE) + * ctx_sched_out(.event_type = EVENT_PINNED) + * + * would only update time for the pinned events. + */ if (is_active & EVENT_TIME) { /* update (and stop) ctx time */ update_context_time(ctx); update_cgrp_time_from_cpuctx(cpuctx); } + is_active ^= ctx->is_active; /* changed bits */ + if (!ctx->nr_active || !(is_active & EVENT_ALL)) return; @@ -8532,6 +8542,7 @@ SYSCALL_DEFINE5(perf_event_open, f_flags); if (IS_ERR(event_file)) { err = PTR_ERR(event_file); + event_file = NULL; goto err_context; } |