]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/kernel/smp.c
[POWERPC] Timer interrupt: use a struct for two per_cpu varables
[linux-2.6-omap-h63xx.git] / arch / powerpc / kernel / smp.c
index d577b71db37549433ca2f36aa6ad0bcea8cd3a5a..338950aeb6f6e3f3d19511e87cc992ad4e3535e4 100644 (file)
@@ -61,11 +61,11 @@ struct thread_info *secondary_ti;
 
 cpumask_t cpu_possible_map = CPU_MASK_NONE;
 cpumask_t cpu_online_map = CPU_MASK_NONE;
-cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
 
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL(cpu_possible_map);
-EXPORT_SYMBOL(cpu_sibling_map);
+EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
 
 /* SMP operations for this machine */
 struct smp_ops_t *smp_ops;
@@ -152,11 +152,6 @@ static void stop_this_cpu(void *dummy)
                ;
 }
 
-void smp_send_stop(void)
-{
-       smp_call_function(stop_this_cpu, NULL, 1, 0);
-}
-
 /*
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
@@ -198,9 +193,6 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
        int cpu;
        u64 timeout;
 
-       /* Can deadlock when called with interrupts disabled */
-       WARN_ON(irqs_disabled());
-
        if (unlikely(smp_ops == NULL))
                return ret;
 
@@ -212,11 +204,6 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
                atomic_set(&data.finished, 0);
 
        spin_lock(&call_lock);
-       /* Must grab online cpu count with preempt disabled, otherwise
-        * it can change. */
-       num_cpus = num_online_cpus() - 1;
-       if (!num_cpus)
-               goto done;
 
        /* remove 'self' from the map */
        if (cpu_isset(smp_processor_id(), map))
@@ -224,7 +211,9 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
 
        /* sanity check the map, remove any non-online processors. */
        cpus_and(map, map, cpu_online_map);
-       if (cpus_empty(map))
+
+       num_cpus = cpus_weight(map);
+       if (!num_cpus)
                goto done;
 
        call_data = &data;
@@ -273,10 +262,19 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic,
        return ret;
 }
 
+static int __smp_call_function(void (*func)(void *info), void *info,
+                              int nonatomic, int wait)
+{
+       return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
+}
+
 int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
                        int wait)
 {
-       return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map);
+       /* Can deadlock when called with interrupts disabled */
+       WARN_ON(irqs_disabled());
+
+       return __smp_call_function(func, info, nonatomic, wait);
 }
 EXPORT_SYMBOL(smp_call_function);
 
@@ -284,7 +282,10 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int
                        int wait)
 {
        cpumask_t map = CPU_MASK_NONE;
-       int ret = -EBUSY;
+       int ret = 0;
+
+       /* Can deadlock when called with interrupts disabled */
+       WARN_ON(irqs_disabled());
 
        if (!cpu_online(cpu))
                return -EINVAL;
@@ -292,11 +293,21 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int
        cpu_set(cpu, map);
        if (cpu != get_cpu())
                ret = smp_call_function_map(func,info,nonatomic,wait,map);
+       else {
+               local_irq_disable();
+               func(info);
+               local_irq_enable();
+       }
        put_cpu();
        return ret;
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
+void smp_send_stop(void)
+{
+       __smp_call_function(stop_this_cpu, NULL, 1, 0);
+}
+
 void smp_call_function_interrupt(void)
 {
        void (*func) (void *info);
@@ -558,6 +569,8 @@ int __devinit start_secondary(void *unused)
        if (system_state > SYSTEM_BOOTING)
                snapshot_timebase();
 
+       secondary_cpu_time_init();
+
        spin_lock(&call_lock);
        cpu_set(cpu, cpu_online_map);
        spin_unlock(&call_lock);