--- zzzz-none-000/linux-2.6.19.2/arch/x86_64/kernel/vsyscall.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5504/linux-2.6.19.2/arch/x86_64/kernel/vsyscall.c 2007-01-11 07:38:19.000000000 +0000 @@ -27,9 +27,6 @@ #include #include #include -#include -#include -#include #include #include @@ -246,17 +243,32 @@ #endif -/* Assume __initcall executes before all user space. Hopefully kmod - doesn't violate that. We'll find out if it does. */ -static void __cpuinit vsyscall_set_cpu(int cpu) +static void __cpuinit write_rdtscp_cb(void *info) +{ + write_rdtscp_aux((unsigned long)info); +} + +void __cpuinit vsyscall_set_cpu(int cpu) { unsigned long *d; unsigned long node = 0; #ifdef CONFIG_NUMA node = cpu_to_node[cpu]; #endif - if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) - write_rdtscp_aux((node << 12) | cpu); + if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) { + void *info = (void *)((node << 12) | cpu); + /* Can happen on preemptive kernel */ + if (get_cpu() == cpu) + write_rdtscp_cb(info); +#ifdef CONFIG_SMP + else { + /* the notifier is unfortunately not executed on the + target CPU */ + smp_call_function_single(cpu,write_rdtscp_cb,info,0,1); + } +#endif + put_cpu(); + } /* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. @@ -268,23 +280,6 @@ *d |= (node >> 4) << 48; } -static void __cpuinit cpu_vsyscall_init(void *arg) -{ - /* preemption should be already off */ - vsyscall_set_cpu(raw_smp_processor_id()); -} - -#ifdef CONFIG_HOTPLUG_CPU -static int __cpuinit -cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) -{ - long cpu = (long)arg; - if (action == CPU_ONLINE) - smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); - return NOTIFY_DONE; -} -#endif - static void __init map_vsyscall(void) { extern char __vsyscall_0; @@ -304,8 +299,6 @@ #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); #endif - on_each_cpu(cpu_vsyscall_init, NULL, 0, 1); - hotcpu_notifier(cpu_vsyscall_notifier, 0); return 0; }