提交 7b7426c8 编写于 作者: J Jens Axboe

m32r: convert to generic helpers for IPI function calls

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: NJens Axboe <jens.axboe@oracle.com>
上级 f6dd9fa5
...@@ -296,6 +296,7 @@ config PREEMPT ...@@ -296,6 +296,7 @@ config PREEMPT
config SMP config SMP
bool "Symmetric multi-processing support" bool "Symmetric multi-processing support"
select USE_GENERIC_SMP_HELPERS
---help--- ---help---
This enables support for systems with more than one CPU. If you have 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 a system with only one CPU, like most personal computers, say N. If
......
...@@ -43,9 +43,6 @@ EXPORT_SYMBOL(dcache_dummy); ...@@ -43,9 +43,6 @@ EXPORT_SYMBOL(dcache_dummy);
#endif #endif
EXPORT_SYMBOL(cpu_data); EXPORT_SYMBOL(cpu_data);
/* Global SMP stuff */
EXPORT_SYMBOL(smp_call_function);
/* TLB flushing */ /* TLB flushing */
EXPORT_SYMBOL(smp_flush_tlb_page); EXPORT_SYMBOL(smp_flush_tlb_page);
#endif #endif
......
...@@ -34,22 +34,6 @@ ...@@ -34,22 +34,6 @@
/* Data structures and variables */ /* 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() * For flush_cache_all()
*/ */
...@@ -96,9 +80,6 @@ void smp_invalidate_interrupt(void); ...@@ -96,9 +80,6 @@ void smp_invalidate_interrupt(void);
void smp_send_stop(void); void smp_send_stop(void);
static void stop_this_cpu(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_send_timer(void);
void smp_ipi_timer_interrupt(struct pt_regs *); void smp_ipi_timer_interrupt(struct pt_regs *);
void smp_local_timer_interrupt(void); void smp_local_timer_interrupt(void);
...@@ -565,86 +546,14 @@ static void stop_this_cpu(void *dummy) ...@@ -565,86 +546,14 @@ static void stop_this_cpu(void *dummy)
for ( ; ; ); for ( ; ; );
} }
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ void arch_send_call_function_ipi(cpumask_t mask)
/* 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)
{ {
struct call_data_struct data; send_IPI_mask(mask, CALL_FUNCTION_IPI, 0);
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);
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, ...@@ -666,27 +575,16 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
*==========================================================================*/ *==========================================================================*/
void smp_call_function_interrupt(void) 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(); irq_enter();
(*func)(info); generic_smp_call_function_interrupt();
irq_exit(); irq_exit();
}
if (wait) { void smp_call_function_single_interrupt(void)
mb(); {
atomic_inc(&call_data->finished); irq_enter();
} generic_smp_call_function_single_interrupt();
irq_exit();
} }
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/ /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
......
...@@ -40,6 +40,7 @@ extern void smp_invalidate_interrupt(void); ...@@ -40,6 +40,7 @@ extern void smp_invalidate_interrupt(void);
extern void smp_call_function_interrupt(void); extern void smp_call_function_interrupt(void);
extern void smp_ipi_timer_interrupt(void); extern void smp_ipi_timer_interrupt(void);
extern void smp_flush_cache_all_interrupt(void); extern void smp_flush_cache_all_interrupt(void);
extern void smp_call_function_single_interrupt(void);
/* /*
* for Boot AP function * for Boot AP function
...@@ -103,7 +104,7 @@ void set_eit_vector_entries(void) ...@@ -103,7 +104,7 @@ void set_eit_vector_entries(void)
eit_vector[186] = (unsigned long)smp_call_function_interrupt; eit_vector[186] = (unsigned long)smp_call_function_interrupt;
eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt; eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
eit_vector[188] = (unsigned long)smp_flush_cache_all_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[190] = 0;
eit_vector[191] = 0; eit_vector[191] = 0;
#endif #endif
......
...@@ -89,6 +89,9 @@ static __inline__ unsigned int num_booting_cpus(void) ...@@ -89,6 +89,9 @@ static __inline__ unsigned int num_booting_cpus(void)
extern void smp_send_timer(void); extern void smp_send_timer(void);
extern unsigned long send_IPI_mask_phys(cpumask_t, int, int); 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__ */ #endif /* not __ASSEMBLY__ */
#define NO_PROC_ID (0xff) /* No processor magic marker */ #define NO_PROC_ID (0xff) /* No processor magic marker */
...@@ -104,6 +107,7 @@ extern unsigned long send_IPI_mask_phys(cpumask_t, int, int); ...@@ -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 LOCAL_TIMER_IPI (M32R_IRQ_IPI3-M32R_IRQ_IPI0)
#define INVALIDATE_CACHE_IPI (M32R_IRQ_IPI4-M32R_IRQ_IPI0) #define INVALIDATE_CACHE_IPI (M32R_IRQ_IPI4-M32R_IRQ_IPI0)
#define CPU_BOOT_IPI (M32R_IRQ_IPI5-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 IPI_SHIFT (0)
#define NR_IPIS (8) #define NR_IPIS (8)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册