Commit c78a9b9b8e36b8de302eddbe7a1688af3d9650ff

Authored by Linus Torvalds

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  
... ... @@ -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 }