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 a77266e3e3e1..2f3fbf84215a 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -1165,11 +1165,9 @@ void perf_event_task_sched_out(struct task_struct *task,
1165 struct perf_event_context *ctx = task->perf_event_ctxp; 1165 struct perf_event_context *ctx = task->perf_event_ctxp;
1166 struct perf_event_context *next_ctx; 1166 struct perf_event_context *next_ctx;
1167 struct perf_event_context *parent; 1167 struct perf_event_context *parent;
1168 struct pt_regs *regs;
1169 int do_switch = 1; 1168 int do_switch = 1;
1170 1169
1171 regs = task_pt_regs(task); 1170 perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0);
1172 perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
1173 1171
1174 if (likely(!ctx || !cpuctx->task_ctx)) 1172 if (likely(!ctx || !cpuctx->task_ctx))
1175 return; 1173 return;
@@ -2787,12 +2785,11 @@ __weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
2787 return NULL; 2785 return NULL;
2788} 2786}
2789 2787
2790#ifdef CONFIG_EVENT_TRACING
2791__weak 2788__weak
2792void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip) 2789void perf_arch_fetch_caller_regs(struct pt_regs *regs, unsigned long ip, int skip)
2793{ 2790{
2794} 2791}
2795#endif 2792
2796 2793
2797/* 2794/*
2798 * Output 2795 * Output
@@ -3379,15 +3376,23 @@ static void perf_event_task_output(struct perf_event *event,
3379 struct perf_task_event *task_event) 3376 struct perf_task_event *task_event)
3380{ 3377{
3381 struct perf_output_handle handle; 3378 struct perf_output_handle handle;
3382 int size;
3383 struct task_struct *task = task_event->task; 3379 struct task_struct *task = task_event->task;
3384 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);
3385 3388
3386 size = task_event->event_id.header.size; 3389 size = task_event->event_id.header.size;
3387 ret = perf_output_begin(&handle, event, size, 0, 0); 3390 ret = perf_output_begin(&handle, event, size, 0, 0);
3388 3391
3389 if (ret) 3392 if (ret) {
3393 local_irq_restore(flags);
3390 return; 3394 return;
3395 }
3391 3396
3392 task_event->event_id.pid = perf_event_pid(event, task); 3397 task_event->event_id.pid = perf_event_pid(event, task);
3393 task_event->event_id.ppid = perf_event_pid(event, current); 3398 task_event->event_id.ppid = perf_event_pid(event, current);
@@ -3398,6 +3403,7 @@ static void perf_event_task_output(struct perf_event *event,
3398 perf_output_put(&handle, task_event->event_id); 3403 perf_output_put(&handle, task_event->event_id);
3399 3404
3400 perf_output_end(&handle); 3405 perf_output_end(&handle);
3406 local_irq_restore(flags);
3401} 3407}
3402 3408
3403static int perf_event_task_match(struct perf_event *event) 3409static int perf_event_task_match(struct perf_event *event)