aboutsummaryrefslogtreecommitdiffstats
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
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
-rw-r--r--arch/x86/kernel/apic/apic.c3
-rw-r--r--arch/x86/oprofile/op_model_amd.c13
-rw-r--r--drivers/oprofile/buffer_sync.c21
-rw-r--r--fs/dcookies.c3
-rw-r--r--kernel/trace/ftrace.c9
-rw-r--r--kernel/trace/trace_kprobe.c8
6 files changed, 39 insertions, 18 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b961af86bfea..b9338b8cf420 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -390,7 +390,8 @@ static unsigned int reserve_eilvt_offset(int offset, unsigned int new)
390 390
391/* 391/*
392 * If mask=1, the LVT entry does not generate interrupts while mask=0 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
396int setup_APIC_eilvt(u8 offset, u8 vector, u8 msg_type, u8 mask) 397int setup_APIC_eilvt(u8 offset, u8 vector, u8 msg_type, u8 mask)
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 9fd8a567fe1e..9cbb710dc94b 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -609,16 +609,21 @@ static int setup_ibs_ctl(int ibs_eilvt_off)
609 return 0; 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 */
612static int force_ibs_eilvt_setup(void) 620static int force_ibs_eilvt_setup(void)
613{ 621{
614 int offset; 622 int offset;
615 int ret; 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 preempt_disable(); 625 preempt_disable();
626 /* find the next free available EILVT entry, skip offset 0 */
622 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) { 627 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
623 if (get_eilvt(offset)) 628 if (get_eilvt(offset))
624 break; 629 break;
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
diff --git a/fs/dcookies.c b/fs/dcookies.c
index a21cabdbd87b..dda0dc702d1b 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -178,6 +178,8 @@ SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len)
178 /* FIXME: (deleted) ? */ 178 /* FIXME: (deleted) ? */
179 path = d_path(&dcs->path, kbuf, PAGE_SIZE); 179 path = d_path(&dcs->path, kbuf, PAGE_SIZE);
180 180
181 mutex_unlock(&dcookie_mutex);
182
181 if (IS_ERR(path)) { 183 if (IS_ERR(path)) {
182 err = PTR_ERR(path); 184 err = PTR_ERR(path);
183 goto out_free; 185 goto out_free;
@@ -194,6 +196,7 @@ SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len)
194 196
195out_free: 197out_free:
196 kfree(kbuf); 198 kfree(kbuf);
199 return err;
197out: 200out:
198 mutex_unlock(&dcookie_mutex); 201 mutex_unlock(&dcookie_mutex);
199 return err; 202 return err;
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 1ee417fcbfa5..908038f57440 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2740,7 +2740,7 @@ static int ftrace_process_regex(struct ftrace_hash *hash,
2740{ 2740{
2741 char *func, *command, *next = buff; 2741 char *func, *command, *next = buff;
2742 struct ftrace_func_command *p; 2742 struct ftrace_func_command *p;
2743 int ret; 2743 int ret = -EINVAL;
2744 2744
2745 func = strsep(&next, ":"); 2745 func = strsep(&next, ":");
2746 2746
@@ -3330,6 +3330,7 @@ static int ftrace_process_locs(struct module *mod,
3330{ 3330{
3331 unsigned long *p; 3331 unsigned long *p;
3332 unsigned long addr; 3332 unsigned long addr;
3333 unsigned long flags;
3333 3334
3334 mutex_lock(&ftrace_lock); 3335 mutex_lock(&ftrace_lock);
3335 p = start; 3336 p = start;
@@ -3346,7 +3347,13 @@ static int ftrace_process_locs(struct module *mod,
3346 ftrace_record_ip(addr); 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 ftrace_update_code(mod); 3355 ftrace_update_code(mod);
3356 local_irq_restore(flags);
3350 mutex_unlock(&ftrace_lock); 3357 mutex_unlock(&ftrace_lock);
3351 3358
3352 return 0; 3359 return 0;
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index f925c45f0afa..27d13b36b8be 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1870,8 +1870,12 @@ fs_initcall(init_kprobe_trace);
1870 1870
1871#ifdef CONFIG_FTRACE_STARTUP_TEST 1871#ifdef CONFIG_FTRACE_STARTUP_TEST
1872 1872
1873static int kprobe_trace_selftest_target(int a1, int a2, int a3, 1873/*
1874 int a4, int a5, int a6) 1874 * The "__used" keeps gcc from removing the function symbol
1875 * from the kallsyms table.
1876 */
1877static __used int kprobe_trace_selftest_target(int a1, int a2, int a3,
1878 int a4, int a5, int a6)
1875{ 1879{
1876 return a1 + a2 + a3 + a4 + a5 + a6; 1880 return a1 + a2 + a3 + a4 + a5 + a6;
1877} 1881}