diff options
| -rw-r--r-- | kernel/perf_event.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index b0feb4795af3..96aae13c7960 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
| @@ -3376,15 +3376,23 @@ static void perf_event_task_output(struct perf_event *event, | |||
| 3376 | struct perf_task_event *task_event) | 3376 | struct perf_task_event *task_event) |
| 3377 | { | 3377 | { |
| 3378 | struct perf_output_handle handle; | 3378 | struct perf_output_handle handle; |
| 3379 | int size; | ||
| 3380 | struct task_struct *task = task_event->task; | 3379 | struct task_struct *task = task_event->task; |
| 3381 | int ret; | 3380 | unsigned long flags; |
| 3381 | int size, ret; | ||
| 3382 | |||
| 3383 | /* | ||
| 3384 | * If this CPU attempts to acquire an rq lock held by a CPU spinning | ||
| 3385 | * in perf_output_lock() from interrupt context, it's game over. | ||
| 3386 | */ | ||
| 3387 | local_irq_save(flags); | ||
| 3382 | 3388 | ||
| 3383 | size = task_event->event_id.header.size; | 3389 | size = task_event->event_id.header.size; |
| 3384 | ret = perf_output_begin(&handle, event, size, 0, 0); | 3390 | ret = perf_output_begin(&handle, event, size, 0, 0); |
| 3385 | 3391 | ||
| 3386 | if (ret) | 3392 | if (ret) { |
| 3393 | local_irq_restore(flags); | ||
| 3387 | return; | 3394 | return; |
| 3395 | } | ||
| 3388 | 3396 | ||
| 3389 | task_event->event_id.pid = perf_event_pid(event, task); | 3397 | task_event->event_id.pid = perf_event_pid(event, task); |
| 3390 | task_event->event_id.ppid = perf_event_pid(event, current); | 3398 | task_event->event_id.ppid = perf_event_pid(event, current); |
| @@ -3395,6 +3403,7 @@ static void perf_event_task_output(struct perf_event *event, | |||
| 3395 | perf_output_put(&handle, task_event->event_id); | 3403 | perf_output_put(&handle, task_event->event_id); |
| 3396 | 3404 | ||
| 3397 | perf_output_end(&handle); | 3405 | perf_output_end(&handle); |
| 3406 | local_irq_restore(flags); | ||
| 3398 | } | 3407 | } |
| 3399 | 3408 | ||
| 3400 | static int perf_event_task_match(struct perf_event *event) | 3409 | static int perf_event_task_match(struct perf_event *event) |
