diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-15 15:38:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-15 15:38:21 -0400 |
commit | ef4a293a4417fc5f50b0b83b62deb9ead8423256 (patch) | |
tree | 310e15624ef6e88545727cbef7ccc2832f87ccbc /kernel | |
parent | 214e9f723e7581c7c51677bdf382cb678d850a9f (diff) | |
parent | 60d5ddeabdda2d6453280efcf172d2429da10eac (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:
"Mostly tooling fixes, but also a lockdep annotation fix, a PMU event
list fix and a new model addition"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
tools/liblockdep: Fix compilation error
tools/liblockdep: Fix linker error in case of cross compile
perf tools: Use getconf to determine number of online CPUs
tools: Fix tools/vm build
perf/x86/rapl: Enable Broadwell-U RAPL support
perf/x86/intel: Fix SLM cache event list
perf: Annotate inherited event ctx->mutex recursion
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c index 81aa3a4ece9f..1a3bf48743ce 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -913,10 +913,30 @@ static void put_ctx(struct perf_event_context *ctx) | |||
913 | * Those places that change perf_event::ctx will hold both | 913 | * Those places that change perf_event::ctx will hold both |
914 | * perf_event_ctx::mutex of the 'old' and 'new' ctx value. | 914 | * perf_event_ctx::mutex of the 'old' and 'new' ctx value. |
915 | * | 915 | * |
916 | * Lock ordering is by mutex address. There is one other site where | 916 | * Lock ordering is by mutex address. There are two other sites where |
917 | * perf_event_context::mutex nests and that is put_event(). But remember that | 917 | * perf_event_context::mutex nests and those are: |
918 | * that is a parent<->child context relation, and migration does not affect | 918 | * |
919 | * children, therefore these two orderings should not interact. | 919 | * - perf_event_exit_task_context() [ child , 0 ] |
920 | * __perf_event_exit_task() | ||
921 | * sync_child_event() | ||
922 | * put_event() [ parent, 1 ] | ||
923 | * | ||
924 | * - perf_event_init_context() [ parent, 0 ] | ||
925 | * inherit_task_group() | ||
926 | * inherit_group() | ||
927 | * inherit_event() | ||
928 | * perf_event_alloc() | ||
929 | * perf_init_event() | ||
930 | * perf_try_init_event() [ child , 1 ] | ||
931 | * | ||
932 | * While it appears there is an obvious deadlock here -- the parent and child | ||
933 | * nesting levels are inverted between the two. This is in fact safe because | ||
934 | * life-time rules separate them. That is an exiting task cannot fork, and a | ||
935 | * spawning task cannot (yet) exit. | ||
936 | * | ||
937 | * But remember that that these are parent<->child context relations, and | ||
938 | * migration does not affect children, therefore these two orderings should not | ||
939 | * interact. | ||
920 | * | 940 | * |
921 | * The change in perf_event::ctx does not affect children (as claimed above) | 941 | * The change in perf_event::ctx does not affect children (as claimed above) |
922 | * because the sys_perf_event_open() case will install a new event and break | 942 | * because the sys_perf_event_open() case will install a new event and break |
@@ -3657,9 +3677,6 @@ static void perf_remove_from_owner(struct perf_event *event) | |||
3657 | } | 3677 | } |
3658 | } | 3678 | } |
3659 | 3679 | ||
3660 | /* | ||
3661 | * Called when the last reference to the file is gone. | ||
3662 | */ | ||
3663 | static void put_event(struct perf_event *event) | 3680 | static void put_event(struct perf_event *event) |
3664 | { | 3681 | { |
3665 | struct perf_event_context *ctx; | 3682 | struct perf_event_context *ctx; |
@@ -3697,6 +3714,9 @@ int perf_event_release_kernel(struct perf_event *event) | |||
3697 | } | 3714 | } |
3698 | EXPORT_SYMBOL_GPL(perf_event_release_kernel); | 3715 | EXPORT_SYMBOL_GPL(perf_event_release_kernel); |
3699 | 3716 | ||
3717 | /* | ||
3718 | * Called when the last reference to the file is gone. | ||
3719 | */ | ||
3700 | static int perf_release(struct inode *inode, struct file *file) | 3720 | static int perf_release(struct inode *inode, struct file *file) |
3701 | { | 3721 | { |
3702 | put_event(file->private_data); | 3722 | put_event(file->private_data); |
@@ -7364,7 +7384,12 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event) | |||
7364 | return -ENODEV; | 7384 | return -ENODEV; |
7365 | 7385 | ||
7366 | if (event->group_leader != event) { | 7386 | if (event->group_leader != event) { |
7367 | ctx = perf_event_ctx_lock(event->group_leader); | 7387 | /* |
7388 | * This ctx->mutex can nest when we're called through | ||
7389 | * inheritance. See the perf_event_ctx_lock_nested() comment. | ||
7390 | */ | ||
7391 | ctx = perf_event_ctx_lock_nested(event->group_leader, | ||
7392 | SINGLE_DEPTH_NESTING); | ||
7368 | BUG_ON(!ctx); | 7393 | BUG_ON(!ctx); |
7369 | } | 7394 | } |
7370 | 7395 | ||