aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/perf_event.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2010-09-16 13:17:24 -0400
committerIngo Molnar <mingo@elte.hu>2010-09-21 07:55:44 -0400
commit41945f6ccf1e86f87fddf6b32db9cf431c05fb54 (patch)
treecf64d47bfff06ff4560efcaa23a067fa99db34dd /kernel/perf_event.c
parent8b8e2ec1eeca7f6941bc81cefc9663018d6ceb57 (diff)
perf: Avoid RCU vs preemption assumptions
The per-pmu per-cpu context patch converted things from get_cpu_var() to this_cpu_ptr(), but that only works if rcu_read_lock() actually disables preemption, and since there is no such guarantee, we need to fix that. Use the newly introduced {get,put}_cpu_ptr(). Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Tejun Heo <tj@kernel.org> LKML-Reference: <20100917093009.308453028@chello.nl> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r--kernel/perf_event.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index baae1367e94..c16158c77df 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3836,18 +3836,20 @@ static void perf_event_task_event(struct perf_task_event *task_event)
3836 3836
3837 rcu_read_lock(); 3837 rcu_read_lock();
3838 list_for_each_entry_rcu(pmu, &pmus, entry) { 3838 list_for_each_entry_rcu(pmu, &pmus, entry) {
3839 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); 3839 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
3840 perf_event_task_ctx(&cpuctx->ctx, task_event); 3840 perf_event_task_ctx(&cpuctx->ctx, task_event);
3841 3841
3842 ctx = task_event->task_ctx; 3842 ctx = task_event->task_ctx;
3843 if (!ctx) { 3843 if (!ctx) {
3844 ctxn = pmu->task_ctx_nr; 3844 ctxn = pmu->task_ctx_nr;
3845 if (ctxn < 0) 3845 if (ctxn < 0)
3846 continue; 3846 goto next;
3847 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); 3847 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
3848 } 3848 }
3849 if (ctx) 3849 if (ctx)
3850 perf_event_task_ctx(ctx, task_event); 3850 perf_event_task_ctx(ctx, task_event);
3851next:
3852 put_cpu_ptr(pmu->pmu_cpu_context);
3851 } 3853 }
3852 rcu_read_unlock(); 3854 rcu_read_unlock();
3853} 3855}
@@ -3969,16 +3971,18 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
3969 3971
3970 rcu_read_lock(); 3972 rcu_read_lock();
3971 list_for_each_entry_rcu(pmu, &pmus, entry) { 3973 list_for_each_entry_rcu(pmu, &pmus, entry) {
3972 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); 3974 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
3973 perf_event_comm_ctx(&cpuctx->ctx, comm_event); 3975 perf_event_comm_ctx(&cpuctx->ctx, comm_event);
3974 3976
3975 ctxn = pmu->task_ctx_nr; 3977 ctxn = pmu->task_ctx_nr;
3976 if (ctxn < 0) 3978 if (ctxn < 0)
3977 continue; 3979 goto next;
3978 3980
3979 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); 3981 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
3980 if (ctx) 3982 if (ctx)
3981 perf_event_comm_ctx(ctx, comm_event); 3983 perf_event_comm_ctx(ctx, comm_event);
3984next:
3985 put_cpu_ptr(pmu->pmu_cpu_context);
3982 } 3986 }
3983 rcu_read_unlock(); 3987 rcu_read_unlock();
3984} 3988}
@@ -4152,19 +4156,21 @@ got_name:
4152 4156
4153 rcu_read_lock(); 4157 rcu_read_lock();
4154 list_for_each_entry_rcu(pmu, &pmus, entry) { 4158 list_for_each_entry_rcu(pmu, &pmus, entry) {
4155 cpuctx = this_cpu_ptr(pmu->pmu_cpu_context); 4159 cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
4156 perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, 4160 perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
4157 vma->vm_flags & VM_EXEC); 4161 vma->vm_flags & VM_EXEC);
4158 4162
4159 ctxn = pmu->task_ctx_nr; 4163 ctxn = pmu->task_ctx_nr;
4160 if (ctxn < 0) 4164 if (ctxn < 0)
4161 continue; 4165 goto next;
4162 4166
4163 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]); 4167 ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
4164 if (ctx) { 4168 if (ctx) {
4165 perf_event_mmap_ctx(ctx, mmap_event, 4169 perf_event_mmap_ctx(ctx, mmap_event,
4166 vma->vm_flags & VM_EXEC); 4170 vma->vm_flags & VM_EXEC);
4167 } 4171 }
4172next:
4173 put_cpu_ptr(pmu->pmu_cpu_context);
4168 } 4174 }
4169 rcu_read_unlock(); 4175 rcu_read_unlock();
4170 4176