aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-06-13 13:45:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-13 13:45:49 -0400
commitc78a9b9b8e36b8de302eddbe7a1688af3d9650ff (patch)
tree3857996cf30ae6a60b5afe2e1e3e30f75fbca05e /drivers
parent842c895d140a75e5d67fa346213deb3ca2b460f8 (diff)
parent5f127133ee432d0b83ee26e8e3a3d7828ab5f2b1 (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: ftrace: Revert 8ab2b7efd ftrace: Remove unnecessary disabling of irqs kprobes/trace: Fix kprobe selftest for gcc 4.6 ftrace: Fix possible undefined return code oprofile, dcookies: Fix possible circular locking dependency oprofile: Fix locking dependency in sync_start() oprofile: Free potentially owned tasks in case of errors oprofile, x86: Add comments to IBS LVT offset initialization
Diffstat (limited to 'drivers')
-rw-r--r--drivers/oprofile/buffer_sync.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index a3984f4ef192..f34b5b29fb95 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -141,6 +141,13 @@ static struct notifier_block module_load_nb = {
141 .notifier_call = module_load_notify, 141 .notifier_call = module_load_notify,
142}; 142};
143 143
144static void free_all_tasks(void)
145{
146 /* make sure we don't leak task structs */
147 process_task_mortuary();
148 process_task_mortuary();
149}
150
144int sync_start(void) 151int sync_start(void)
145{ 152{
146 int err; 153 int err;
@@ -148,8 +155,6 @@ int sync_start(void)
148 if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) 155 if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL))
149 return -ENOMEM; 156 return -ENOMEM;
150 157
151 mutex_lock(&buffer_mutex);
152
153 err = task_handoff_register(&task_free_nb); 158 err = task_handoff_register(&task_free_nb);
154 if (err) 159 if (err)
155 goto out1; 160 goto out1;
@@ -166,7 +171,6 @@ int sync_start(void)
166 start_cpu_work(); 171 start_cpu_work();
167 172
168out: 173out:
169 mutex_unlock(&buffer_mutex);
170 return err; 174 return err;
171out4: 175out4:
172 profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); 176 profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
@@ -174,6 +178,7 @@ out3:
174 profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); 178 profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
175out2: 179out2:
176 task_handoff_unregister(&task_free_nb); 180 task_handoff_unregister(&task_free_nb);
181 free_all_tasks();
177out1: 182out1:
178 free_cpumask_var(marked_cpus); 183 free_cpumask_var(marked_cpus);
179 goto out; 184 goto out;
@@ -182,20 +187,16 @@ out1:
182 187
183void sync_stop(void) 188void sync_stop(void)
184{ 189{
185 /* flush buffers */
186 mutex_lock(&buffer_mutex);
187 end_cpu_work(); 190 end_cpu_work();
188 unregister_module_notifier(&module_load_nb); 191 unregister_module_notifier(&module_load_nb);
189 profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); 192 profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
190 profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); 193 profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
191 task_handoff_unregister(&task_free_nb); 194 task_handoff_unregister(&task_free_nb);
192 mutex_unlock(&buffer_mutex); 195 barrier(); /* do all of the above first */
193 flush_cpu_work();
194 196
195 /* make sure we don't leak task structs */ 197 flush_cpu_work();
196 process_task_mortuary();
197 process_task_mortuary();
198 198
199 free_all_tasks();
199 free_cpumask_var(marked_cpus); 200 free_cpumask_var(marked_cpus);
200} 201}
201 202