aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-11-04 21:55:59 -0500
committerIngo Molnar <mingo@kernel.org>2015-02-18 11:16:03 -0500
commit2a0ad3b326a9024ba86dca4028499d31fa0c6c4d (patch)
tree3c710a73ad62005b1e60ebe9f32a8235604de43e /kernel/events
parentba532500c5651a4be4108acc64ed99a95cb005b3 (diff)
perf/x86/intel: Use context switch callback to flush LBR stack
Previous commit introduces context switch callback, its function overlaps with the flush branch stack callback. So we can use the context switch callback to flush LBR stack. This patch adds code that uses the flush branch callback to flush the LBR stack when task is being scheduled in. The callback is enabled only when there are events use the LBR hardware. This patch also removes all old flush branch stack code. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Signed-off-by: Kan Liang <kan.liang@intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Vince Weaver <vincent.weaver@maine.edu> Cc: eranian@google.com Cc: jolsa@redhat.com Link: http://lkml.kernel.org/r/1415156173-10035-4-git-send-email-kan.liang@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/events')
-rw-r--r--kernel/events/core.c77
1 files changed, 0 insertions, 77 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 6c8b31b7efb6..f563ce767f93 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -153,7 +153,6 @@ enum event_type_t {
153 */ 153 */
154struct static_key_deferred perf_sched_events __read_mostly; 154struct static_key_deferred perf_sched_events __read_mostly;
155static DEFINE_PER_CPU(atomic_t, perf_cgroup_events); 155static DEFINE_PER_CPU(atomic_t, perf_cgroup_events);
156static DEFINE_PER_CPU(atomic_t, perf_branch_stack_events);
157static DEFINE_PER_CPU(int, perf_sched_cb_usages); 156static DEFINE_PER_CPU(int, perf_sched_cb_usages);
158 157
159static atomic_t nr_mmap_events __read_mostly; 158static atomic_t nr_mmap_events __read_mostly;
@@ -1240,9 +1239,6 @@ list_add_event(struct perf_event *event, struct perf_event_context *ctx)
1240 if (is_cgroup_event(event)) 1239 if (is_cgroup_event(event))
1241 ctx->nr_cgroups++; 1240 ctx->nr_cgroups++;
1242 1241
1243 if (has_branch_stack(event))
1244 ctx->nr_branch_stack++;
1245
1246 list_add_rcu(&event->event_entry, &ctx->event_list); 1242 list_add_rcu(&event->event_entry, &ctx->event_list);
1247 ctx->nr_events++; 1243 ctx->nr_events++;
1248 if (event->attr.inherit_stat) 1244 if (event->attr.inherit_stat)
@@ -1409,9 +1405,6 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
1409 cpuctx->cgrp = NULL; 1405 cpuctx->cgrp = NULL;
1410 } 1406 }
1411 1407
1412 if (has_branch_stack(event))
1413 ctx->nr_branch_stack--;
1414
1415 ctx->nr_events--; 1408 ctx->nr_events--;
1416 if (event->attr.inherit_stat) 1409 if (event->attr.inherit_stat)
1417 ctx->nr_stat--; 1410 ctx->nr_stat--;
@@ -2809,64 +2802,6 @@ static void perf_event_context_sched_in(struct perf_event_context *ctx,
2809} 2802}
2810 2803
2811/* 2804/*
2812 * When sampling the branck stack in system-wide, it may be necessary
2813 * to flush the stack on context switch. This happens when the branch
2814 * stack does not tag its entries with the pid of the current task.
2815 * Otherwise it becomes impossible to associate a branch entry with a
2816 * task. This ambiguity is more likely to appear when the branch stack
2817 * supports priv level filtering and the user sets it to monitor only
2818 * at the user level (which could be a useful measurement in system-wide
2819 * mode). In that case, the risk is high of having a branch stack with
2820 * branch from multiple tasks. Flushing may mean dropping the existing
2821 * entries or stashing them somewhere in the PMU specific code layer.
2822 *
2823 * This function provides the context switch callback to the lower code
2824 * layer. It is invoked ONLY when there is at least one system-wide context
2825 * with at least one active event using taken branch sampling.
2826 */
2827static void perf_branch_stack_sched_in(struct task_struct *prev,
2828 struct task_struct *task)
2829{
2830 struct perf_cpu_context *cpuctx;
2831 struct pmu *pmu;
2832 unsigned long flags;
2833
2834 /* no need to flush branch stack if not changing task */
2835 if (prev == task)
2836 return;
2837
2838 local_irq_save(flags);
2839
2840 rcu_read_lock();
2841
2842 list_for_each_entry_rcu(pmu, &pmus, entry) {
2843 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context);
2844
2845 /*
2846 * check if the context has at least one
2847 * event using PERF_SAMPLE_BRANCH_STACK
2848 */
2849 if (cpuctx->ctx.nr_branch_stack > 0
2850 && pmu->flush_branch_stack) {
2851
2852 perf_ctx_lock(cpuctx, cpuctx->task_ctx);
2853
2854 perf_pmu_disable(pmu);
2855
2856 pmu->flush_branch_stack();
2857
2858 perf_pmu_enable(pmu);
2859
2860 perf_ctx_unlock(cpuctx, cpuctx->task_ctx);
2861 }
2862 }
2863
2864 rcu_read_unlock();
2865
2866 local_irq_restore(flags);
2867}
2868
2869/*
2870 * Called from scheduler to add the events of the current task 2805 * Called from scheduler to add the events of the current task
2871 * with interrupts disabled. 2806 * with interrupts disabled.
2872 * 2807 *
@@ -2898,10 +2833,6 @@ void __perf_event_task_sched_in(struct task_struct *prev,
2898 if (atomic_read(this_cpu_ptr(&perf_cgroup_events))) 2833 if (atomic_read(this_cpu_ptr(&perf_cgroup_events)))
2899 perf_cgroup_sched_in(prev, task); 2834 perf_cgroup_sched_in(prev, task);
2900 2835
2901 /* check for system-wide branch_stack events */
2902 if (atomic_read(this_cpu_ptr(&perf_branch_stack_events)))
2903 perf_branch_stack_sched_in(prev, task);
2904
2905 if (__this_cpu_read(perf_sched_cb_usages)) 2836 if (__this_cpu_read(perf_sched_cb_usages))
2906 perf_pmu_sched_task(prev, task, true); 2837 perf_pmu_sched_task(prev, task, true);
2907} 2838}
@@ -3480,10 +3411,6 @@ static void unaccount_event_cpu(struct perf_event *event, int cpu)
3480 if (event->parent) 3411 if (event->parent)
3481 return; 3412 return;
3482 3413
3483 if (has_branch_stack(event)) {
3484 if (!(event->attach_state & PERF_ATTACH_TASK))
3485 atomic_dec(&per_cpu(perf_branch_stack_events, cpu));
3486 }
3487 if (is_cgroup_event(event)) 3414 if (is_cgroup_event(event))
3488 atomic_dec(&per_cpu(perf_cgroup_events, cpu)); 3415 atomic_dec(&per_cpu(perf_cgroup_events, cpu));
3489} 3416}
@@ -7139,10 +7066,6 @@ static void account_event_cpu(struct perf_event *event, int cpu)
7139 if (event->parent) 7066 if (event->parent)
7140 return; 7067 return;
7141 7068
7142 if (has_branch_stack(event)) {
7143 if (!(event->attach_state & PERF_ATTACH_TASK))
7144 atomic_inc(&per_cpu(perf_branch_stack_events, cpu));
7145 }
7146 if (is_cgroup_event(event)) 7069 if (is_cgroup_event(event))
7147 atomic_inc(&per_cpu(perf_cgroup_events, cpu)); 7070 atomic_inc(&per_cpu(perf_cgroup_events, cpu));
7148} 7071}