diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/events/core.c | 41 | ||||
-rw-r--r-- | kernel/irq/dummychip.c | 1 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 6 | ||||
-rw-r--r-- | kernel/trace/trace_output.c | 3 |
4 files changed, 37 insertions, 14 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 | ||
diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c index 988dc58e8847..2feb6feca0cc 100644 --- a/kernel/irq/dummychip.c +++ b/kernel/irq/dummychip.c | |||
@@ -57,5 +57,6 @@ struct irq_chip dummy_irq_chip = { | |||
57 | .irq_ack = noop, | 57 | .irq_ack = noop, |
58 | .irq_mask = noop, | 58 | .irq_mask = noop, |
59 | .irq_unmask = noop, | 59 | .irq_unmask = noop, |
60 | .flags = IRQCHIP_SKIP_SET_WAKE, | ||
60 | }; | 61 | }; |
61 | EXPORT_SYMBOL_GPL(dummy_irq_chip); | 62 | EXPORT_SYMBOL_GPL(dummy_irq_chip); |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 11dc22a6983b..637a09461c1d 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -117,11 +117,7 @@ static int __clockevents_set_state(struct clock_event_device *dev, | |||
117 | /* Transition with new state-specific callbacks */ | 117 | /* Transition with new state-specific callbacks */ |
118 | switch (state) { | 118 | switch (state) { |
119 | case CLOCK_EVT_STATE_DETACHED: | 119 | case CLOCK_EVT_STATE_DETACHED: |
120 | /* | 120 | /* The clockevent device is getting replaced. Shut it down. */ |
121 | * This is an internal state, which is guaranteed to go from | ||
122 | * SHUTDOWN to DETACHED. No driver interaction required. | ||
123 | */ | ||
124 | return 0; | ||
125 | 121 | ||
126 | case CLOCK_EVT_STATE_SHUTDOWN: | 122 | case CLOCK_EVT_STATE_SHUTDOWN: |
127 | return dev->set_state_shutdown(dev); | 123 | return dev->set_state_shutdown(dev); |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 692bf7184c8c..25a086bcb700 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -178,12 +178,13 @@ ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) | |||
178 | EXPORT_SYMBOL(ftrace_print_hex_seq); | 178 | EXPORT_SYMBOL(ftrace_print_hex_seq); |
179 | 179 | ||
180 | const char * | 180 | const char * |
181 | ftrace_print_array_seq(struct trace_seq *p, const void *buf, int buf_len, | 181 | ftrace_print_array_seq(struct trace_seq *p, const void *buf, int count, |
182 | size_t el_size) | 182 | size_t el_size) |
183 | { | 183 | { |
184 | const char *ret = trace_seq_buffer_ptr(p); | 184 | const char *ret = trace_seq_buffer_ptr(p); |
185 | const char *prefix = ""; | 185 | const char *prefix = ""; |
186 | void *ptr = (void *)buf; | 186 | void *ptr = (void *)buf; |
187 | size_t buf_len = count * el_size; | ||
187 | 188 | ||
188 | trace_seq_putc(p, '{'); | 189 | trace_seq_putc(p, '{'); |
189 | 190 | ||