m32r: convert to generic helpers for IPI function calls
authorJens Axboe <jens.axboe@oracle.com>
Tue, 10 Jun 2008 18:49:30 +0000 (20:49 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 26 Jun 2008 09:22:57 +0000 (11:22 +0200)
This converts m32r to use the new helpers for smp_call_function() and
friends, and adds support for smp_call_function_single(). Not tested,
not even compiled.

Cc: Hirokazu Takata <takata@linux-m32r.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
arch/m32r/Kconfig
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/smp.c
arch/m32r/kernel/traps.c
include/asm-m32r/smp.h

index de153de2ea9f34df702bcbd7c915ee119e9bac53..a5f864c445b2fe1a28f511dd2c033e4430fc0814 100644 (file)
@@ -296,6 +296,7 @@ config PREEMPT
 
 config SMP
        bool "Symmetric multi-processing support"
+       select USE_GENERIC_SMP_HELPERS
        ---help---
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
index e6709fe950ba6b090236a1c4ed14efd2ee5b3a03..16bcb189a38319c0831dc0dd6fc1fa505eedc64d 100644 (file)
@@ -43,9 +43,6 @@ EXPORT_SYMBOL(dcache_dummy);
 #endif
 EXPORT_SYMBOL(cpu_data);
 
-/* Global SMP stuff */
-EXPORT_SYMBOL(smp_call_function);
-
 /* TLB flushing */
 EXPORT_SYMBOL(smp_flush_tlb_page);
 #endif
index c837bc13b015d01a72b9ec671c07b1144045d5b2..74eb7bcd5a40a931a8ddc63e1d17a34d5f4adabe 100644 (file)
 /* Data structures and variables                                             */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
-/*
- * Structure and data for smp_call_function(). This is designed to minimise
- * static memory requirements. It also looks cleaner.
- */
-static DEFINE_SPINLOCK(call_lock);
-
-struct call_data_struct {
-       void (*func) (void *info);
-       void *info;
-       atomic_t started;
-       atomic_t finished;
-       int wait;
-} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
-
-static struct call_data_struct *call_data;
-
 /*
  * For flush_cache_all()
  */
@@ -96,9 +80,6 @@ void smp_invalidate_interrupt(void);
 void smp_send_stop(void);
 static void stop_this_cpu(void *);
 
-int smp_call_function(void (*) (void *), void *, int, int);
-void smp_call_function_interrupt(void);
-
 void smp_send_timer(void);
 void smp_ipi_timer_interrupt(struct pt_regs *);
 void smp_local_timer_interrupt(void);
@@ -565,86 +546,14 @@ static void stop_this_cpu(void *dummy)
        for ( ; ; );
 }
 
-/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Call function Routines                                                    */
-/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-
-/*==========================================================================*
- * Name:         smp_call_function
- *
- * Description:  This routine sends a 'CALL_FUNCTION_IPI' to all other CPUs
- *               in the system.
- *
- * Born on Date: 2002.02.05
- *
- * Arguments:    *func - The function to run. This must be fast and
- *                       non-blocking.
- *               *info - An arbitrary pointer to pass to the function.
- *               nonatomic - currently unused.
- *               wait - If true, wait (atomically) until function has
- *                      completed on other CPUs.
- *
- * Returns:      0 on success, else a negative status code. Does not return
- *               until remote CPUs are nearly ready to execute <<func>> or
- *               are or have executed.
- *
- * Cautions:     You must not call this function with disabled interrupts or
- *               from a hardware interrupt handler, you may call it from a
- *               bottom half handler.
- *
- * Modification log:
- * Date       Who Description
- * ---------- --- --------------------------------------------------------
- *
- *==========================================================================*/
-int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
-       int wait)
+void arch_send_call_function_ipi(cpumask_t mask)
 {
-       struct call_data_struct data;
-       int cpus;
-
-#ifdef DEBUG_SMP
-       unsigned long flags;
-       __save_flags(flags);
-       if (!(flags & 0x0040))  /* Interrupt Disable NONONO */
-               BUG();
-#endif /* DEBUG_SMP */
-
-       /* Holding any lock stops cpus from going down. */
-       spin_lock(&call_lock);
-       cpus = num_online_cpus() - 1;
-
-       if (!cpus) {
-               spin_unlock(&call_lock);
-               return 0;
-       }
-
-       /* Can deadlock when called with interrupts disabled */
-       WARN_ON(irqs_disabled());
-
-       data.func = func;
-       data.info = info;
-       atomic_set(&data.started, 0);
-       data.wait = wait;
-       if (wait)
-               atomic_set(&data.finished, 0);
-
-       call_data = &data;
-       mb();
-
-       /* Send a message to all other CPUs and wait for them to respond */
-       send_IPI_allbutself(CALL_FUNCTION_IPI, 0);
-
-       /* Wait for response */
-       while (atomic_read(&data.started) != cpus)
-               barrier();
-
-       if (wait)
-               while (atomic_read(&data.finished) != cpus)
-                       barrier();
-       spin_unlock(&call_lock);
+       send_IPI_mask(mask, CALL_FUNCTION_IPI, 0);
+}
 
-       return 0;
+void arch_send_call_function_single_ipi(int cpu)
+{
+       send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNC_SINGLE_IPI, 0);
 }
 
 /*==========================================================================*
@@ -666,27 +575,16 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
  *==========================================================================*/
 void smp_call_function_interrupt(void)
 {
-       void (*func) (void *info) = call_data->func;
-       void *info = call_data->info;
-       int wait = call_data->wait;
-
-       /*
-        * Notify initiating CPU that I've grabbed the data and am
-        * about to execute the function
-        */
-       mb();
-       atomic_inc(&call_data->started);
-       /*
-        * At this point the info structure may be out of scope unless wait==1
-        */
        irq_enter();
-       (*func)(info);
+       generic_smp_call_function_interrupt();
        irq_exit();
+}
 
-       if (wait) {
-               mb();
-               atomic_inc(&call_data->finished);
-       }
+void smp_call_function_single_interrupt(void)
+{
+       irq_enter();
+       generic_smp_call_function_single_interrupt();
+       irq_exit();
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
index 89ba4a0b5d5109d0be4569947e13591d115a2f91..46159a4e644b81f8bf0191641ac4fecfc58b0f82 100644 (file)
@@ -40,6 +40,7 @@ extern void smp_invalidate_interrupt(void);
 extern void smp_call_function_interrupt(void);
 extern void smp_ipi_timer_interrupt(void);
 extern void smp_flush_cache_all_interrupt(void);
+extern void smp_call_function_single_interrupt(void);
 
 /*
  * for Boot AP function
@@ -103,7 +104,7 @@ void        set_eit_vector_entries(void)
        eit_vector[186] = (unsigned long)smp_call_function_interrupt;
        eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
        eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
-       eit_vector[189] = 0;
+       eit_vector[189] = (unsigned long)smp_call_function_single_interrupt;
        eit_vector[190] = 0;
        eit_vector[191] = 0;
 #endif
index 078e1a51a042a74a6eeda6c48d3f8882a466f2fc..c5dd66916692ad1723fa29bd34089165afef582c 100644 (file)
@@ -89,6 +89,9 @@ static __inline__ unsigned int num_booting_cpus(void)
 extern void smp_send_timer(void);
 extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
 
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi(cpumask_t mask);
+
 #endif /* not __ASSEMBLY__ */
 
 #define NO_PROC_ID (0xff)      /* No processor magic marker */
@@ -104,6 +107,7 @@ extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
 #define LOCAL_TIMER_IPI                (M32R_IRQ_IPI3-M32R_IRQ_IPI0)
 #define INVALIDATE_CACHE_IPI   (M32R_IRQ_IPI4-M32R_IRQ_IPI0)
 #define CPU_BOOT_IPI           (M32R_IRQ_IPI5-M32R_IRQ_IPI0)
+#define CALL_FUNC_SINGLE_IPI   (M32R_IRQ_IPI6-M32R_IRQ_IPI0)
 
 #define IPI_SHIFT      (0)
 #define NR_IPIS                (8)