aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 574ee58a3046..681af806d76b 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1164,11 +1164,9 @@ void perf_event_task_sched_out(struct task_struct *task,
1164 struct perf_event_context *ctx = task->perf_event_ctxp; 1164 struct perf_event_context *ctx = task->perf_event_ctxp;
1165 struct perf_event_context *next_ctx; 1165 struct perf_event_context *next_ctx;
1166 struct perf_event_context *parent; 1166 struct perf_event_context *parent;
1167 struct pt_regs *regs;
1168 int do_switch = 1; 1167 int do_switch = 1;
1169 1168
1170 regs = task_pt_regs(task); 1169 perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
1171 perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
1172 1170
1173 if (likely(!ctx || !cpuctx->task_ctx)) 1171 if (likely(!ctx || !cpuctx->task_ctx))
1174 return; 1172 return;
@@ -2786,12 +2784,11 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
2786 return NULL; 2784 return NULL;
2787} 2785}
2788 2786
2789#ifdef CONFIG_EVENT_TRACING
2790__weak 2787__weak
2791void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) 2788void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
2792{ 2789{
2793} 2790}
2794#endif 2791
2795 2792
2796/* 2793/*
2797 * Output 2794 * Output
@@ -3378,15 +3375,23 @@ static void perf_event_task_output(struct perf_event *event,
3378 struct perf_task_event *task_event) 3375 struct perf_task_event *task_event)
3379{ 3376{
3380 struct perf_output_handle handle; 3377 struct perf_output_handle handle;
3381 int size;
3382 struct task_struct *task = task_event->task; 3378 struct task_struct *task = task_event->task;
3383 int ret; 3379 unsigned long flags;
3380 int size, ret;
3381
3382 /*
3383 * If this CPU attempts to acquire an rq lock held by a CPU spinning
3384 * in perf_output_lock() from interrupt context, it's game over.
3385 */
3386 local_irq_save(flags);
3384 3387
3385 size = task_event->event_id.header.size; 3388 size = task_event->event_id.header.size;
3386 ret = perf_output_begin(&handle, event, size, 0, 0); 3389 ret = perf_output_begin(&handle, event, size, 0, 0);
3387 3390
3388 if (ret) 3391 if (ret) {
3392 local_irq_restore(flags);
3389 return; 3393 return;
3394 }
3390 3395
3391 task_event->event_id.pid = perf_event_pid(event, task); 3396 task_event->event_id.pid = perf_event_pid(event, task);
3392 task_event->event_id.ppid = perf_event_pid(event, current); 3397 task_event->event_id.ppid = perf_event_pid(event, current);
@@ -3397,6 +3402,7 @@ static void perf_event_task_output(struct perf_event *event,
3397 perf_output_put(&handle, task_event->event_id); 3402 perf_output_put(&handle, task_event->event_id);
3398 3403
3399 perf_output_end(&handle); 3404 perf_output_end(&handle);
3405 local_irq_restore(flags);
3400} 3406}
3401 3407
3402static int perf_event_task_match(struct perf_event *event) 3408static int perf_event_task_match(struct perf_event *event)