Commit c78a9b9b8e36b8de302eddbe7a1688af3d9650ff
Exists in
master
and in
4 other branches
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kerne…
…l/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
Showing 6 changed files Side-by-side Diff
arch/x86/kernel/apic/apic.c
... | ... | @@ -390,7 +390,8 @@ |
390 | 390 | |
391 | 391 | /* |
392 | 392 | * If mask=1, the LVT entry does not generate interrupts while mask=0 |
393 | - * enables the vector. See also the BKDGs. | |
393 | + * enables the vector. See also the BKDGs. Must be called with | |
394 | + * preemption disabled. | |
394 | 395 | */ |
395 | 396 | |
396 | 397 | int setup_APIC_eilvt(u8 offset, u8 vector, u8 msg_type, u8 mask) |
arch/x86/oprofile/op_model_amd.c
... | ... | @@ -609,16 +609,21 @@ |
609 | 609 | return 0; |
610 | 610 | } |
611 | 611 | |
612 | +/* | |
613 | + * This runs only on the current cpu. We try to find an LVT offset and | |
614 | + * setup the local APIC. For this we must disable preemption. On | |
615 | + * success we initialize all nodes with this offset. This updates then | |
616 | + * the offset in the IBS_CTL per-node msr. The per-core APIC setup of | |
617 | + * the IBS interrupt vector is called from op_amd_setup_ctrs()/op_- | |
618 | + * amd_cpu_shutdown() using the new offset. | |
619 | + */ | |
612 | 620 | static int force_ibs_eilvt_setup(void) |
613 | 621 | { |
614 | 622 | int offset; |
615 | 623 | int ret; |
616 | 624 | |
617 | - /* | |
618 | - * find the next free available EILVT entry, skip offset 0, | |
619 | - * pin search to this cpu | |
620 | - */ | |
621 | 625 | preempt_disable(); |
626 | + /* find the next free available EILVT entry, skip offset 0 */ | |
622 | 627 | for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) { |
623 | 628 | if (get_eilvt(offset)) |
624 | 629 | break; |
drivers/oprofile/buffer_sync.c
... | ... | @@ -141,6 +141,13 @@ |
141 | 141 | .notifier_call = module_load_notify, |
142 | 142 | }; |
143 | 143 | |
144 | +static 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 | + | |
144 | 151 | int sync_start(void) |
145 | 152 | { |
146 | 153 | int err; |
... | ... | @@ -148,8 +155,6 @@ |
148 | 155 | if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) |
149 | 156 | return -ENOMEM; |
150 | 157 | |
151 | - mutex_lock(&buffer_mutex); | |
152 | - | |
153 | 158 | err = task_handoff_register(&task_free_nb); |
154 | 159 | if (err) |
155 | 160 | goto out1; |
... | ... | @@ -166,7 +171,6 @@ |
166 | 171 | start_cpu_work(); |
167 | 172 | |
168 | 173 | out: |
169 | - mutex_unlock(&buffer_mutex); | |
170 | 174 | return err; |
171 | 175 | out4: |
172 | 176 | profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); |
... | ... | @@ -174,6 +178,7 @@ |
174 | 178 | profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); |
175 | 179 | out2: |
176 | 180 | task_handoff_unregister(&task_free_nb); |
181 | + free_all_tasks(); | |
177 | 182 | out1: |
178 | 183 | free_cpumask_var(marked_cpus); |
179 | 184 | goto out; |
180 | 185 | |
181 | 186 | |
... | ... | @@ -182,20 +187,16 @@ |
182 | 187 | |
183 | 188 | void sync_stop(void) |
184 | 189 | { |
185 | - /* flush buffers */ | |
186 | - mutex_lock(&buffer_mutex); | |
187 | 190 | end_cpu_work(); |
188 | 191 | unregister_module_notifier(&module_load_nb); |
189 | 192 | profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); |
190 | 193 | profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); |
191 | 194 | task_handoff_unregister(&task_free_nb); |
192 | - mutex_unlock(&buffer_mutex); | |
195 | + barrier(); /* do all of the above first */ | |
196 | + | |
193 | 197 | flush_cpu_work(); |
194 | 198 | |
195 | - /* make sure we don't leak task structs */ | |
196 | - process_task_mortuary(); | |
197 | - process_task_mortuary(); | |
198 | - | |
199 | + free_all_tasks(); | |
199 | 200 | free_cpumask_var(marked_cpus); |
200 | 201 | } |
201 | 202 |
fs/dcookies.c
... | ... | @@ -178,6 +178,8 @@ |
178 | 178 | /* FIXME: (deleted) ? */ |
179 | 179 | path = d_path(&dcs->path, kbuf, PAGE_SIZE); |
180 | 180 | |
181 | + mutex_unlock(&dcookie_mutex); | |
182 | + | |
181 | 183 | if (IS_ERR(path)) { |
182 | 184 | err = PTR_ERR(path); |
183 | 185 | goto out_free; |
... | ... | @@ -194,6 +196,7 @@ |
194 | 196 | |
195 | 197 | out_free: |
196 | 198 | kfree(kbuf); |
199 | + return err; | |
197 | 200 | out: |
198 | 201 | mutex_unlock(&dcookie_mutex); |
199 | 202 | return err; |
kernel/trace/ftrace.c
... | ... | @@ -2740,7 +2740,7 @@ |
2740 | 2740 | { |
2741 | 2741 | char *func, *command, *next = buff; |
2742 | 2742 | struct ftrace_func_command *p; |
2743 | - int ret; | |
2743 | + int ret = -EINVAL; | |
2744 | 2744 | |
2745 | 2745 | func = strsep(&next, ":"); |
2746 | 2746 | |
... | ... | @@ -3330,6 +3330,7 @@ |
3330 | 3330 | { |
3331 | 3331 | unsigned long *p; |
3332 | 3332 | unsigned long addr; |
3333 | + unsigned long flags; | |
3333 | 3334 | |
3334 | 3335 | mutex_lock(&ftrace_lock); |
3335 | 3336 | p = start; |
3336 | 3337 | |
... | ... | @@ -3346,7 +3347,13 @@ |
3346 | 3347 | ftrace_record_ip(addr); |
3347 | 3348 | } |
3348 | 3349 | |
3350 | + /* | |
3351 | + * Disable interrupts to prevent interrupts from executing | |
3352 | + * code that is being modified. | |
3353 | + */ | |
3354 | + local_irq_save(flags); | |
3349 | 3355 | ftrace_update_code(mod); |
3356 | + local_irq_restore(flags); | |
3350 | 3357 | mutex_unlock(&ftrace_lock); |
3351 | 3358 | |
3352 | 3359 | return 0; |
kernel/trace/trace_kprobe.c
... | ... | @@ -1870,8 +1870,12 @@ |
1870 | 1870 | |
1871 | 1871 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
1872 | 1872 | |
1873 | -static int kprobe_trace_selftest_target(int a1, int a2, int a3, | |
1874 | - int a4, int a5, int a6) | |
1873 | +/* | |
1874 | + * The "__used" keeps gcc from removing the function symbol | |
1875 | + * from the kallsyms table. | |
1876 | + */ | |
1877 | +static __used int kprobe_trace_selftest_target(int a1, int a2, int a3, | |
1878 | + int a4, int a5, int a6) | |
1875 | 1879 | { |
1876 | 1880 | return a1 + a2 + a3 + a4 + a5 + a6; |
1877 | 1881 | } |