sh: convert to generic helpers for IPI function calls
This converts sh to use the new helpers for smp_call_function() and friends, and adds support for smp_call_function_single(). Not tested, but it compiles. Acked-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
dbcf4787d8
commit
490f5de52a
3 changed files with 13 additions and 50 deletions
|
@ -688,6 +688,7 @@ config CRASH_DUMP
|
||||||
config SMP
|
config SMP
|
||||||
bool "Symmetric multi-processing support"
|
bool "Symmetric multi-processing support"
|
||||||
depends on SYS_SUPPORTS_SMP
|
depends on SYS_SUPPORTS_SMP
|
||||||
|
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
|
||||||
|
|
|
@ -36,13 +36,6 @@ EXPORT_SYMBOL(cpu_possible_map);
|
||||||
cpumask_t cpu_online_map;
|
cpumask_t cpu_online_map;
|
||||||
EXPORT_SYMBOL(cpu_online_map);
|
EXPORT_SYMBOL(cpu_online_map);
|
||||||
|
|
||||||
static atomic_t cpus_booted = ATOMIC_INIT(0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Run specified function on a particular processor.
|
|
||||||
*/
|
|
||||||
void __smp_call_function(unsigned int cpu);
|
|
||||||
|
|
||||||
static inline void __init smp_store_cpu_info(unsigned int cpu)
|
static inline void __init smp_store_cpu_info(unsigned int cpu)
|
||||||
{
|
{
|
||||||
struct sh_cpuinfo *c = cpu_data + cpu;
|
struct sh_cpuinfo *c = cpu_data + cpu;
|
||||||
|
@ -178,42 +171,17 @@ void smp_send_stop(void)
|
||||||
smp_call_function(stop_this_cpu, 0, 1, 0);
|
smp_call_function(stop_this_cpu, 0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct smp_fn_call_struct smp_fn_call = {
|
void arch_send_call_function_ipi(cpumask_t mask)
|
||||||
.lock = __SPIN_LOCK_UNLOCKED(smp_fn_call.lock),
|
|
||||||
.finished = ATOMIC_INIT(0),
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The caller of this wants the passed function to run on every cpu. If wait
|
|
||||||
* is set, wait until all cpus have finished the function before returning.
|
|
||||||
* The lock is here to protect the call structure.
|
|
||||||
* You must not call this function with disabled interrupts or from a
|
|
||||||
* hardware interrupt handler or from a bottom half handler.
|
|
||||||
*/
|
|
||||||
int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
|
|
||||||
{
|
{
|
||||||
unsigned int nr_cpus = atomic_read(&cpus_booted);
|
int cpu;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Can deadlock when called with interrupts disabled */
|
for_each_cpu_mask(cpu, mask)
|
||||||
WARN_ON(irqs_disabled());
|
plat_send_ipi(cpu, SMP_MSG_FUNCTION);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(&smp_fn_call.lock);
|
void arch_send_call_function_single_ipi(int cpu)
|
||||||
|
{
|
||||||
atomic_set(&smp_fn_call.finished, 0);
|
plat_send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
|
||||||
smp_fn_call.fn = func;
|
|
||||||
smp_fn_call.data = info;
|
|
||||||
|
|
||||||
for (i = 0; i < nr_cpus; i++)
|
|
||||||
if (i != smp_processor_id())
|
|
||||||
plat_send_ipi(i, SMP_MSG_FUNCTION);
|
|
||||||
|
|
||||||
if (wait)
|
|
||||||
while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1));
|
|
||||||
|
|
||||||
spin_unlock(&smp_fn_call.lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not really SMP stuff ... */
|
/* Not really SMP stuff ... */
|
||||||
|
|
|
@ -26,18 +26,10 @@ extern int __cpu_logical_map[NR_CPUS];
|
||||||
|
|
||||||
#define NO_PROC_ID (-1)
|
#define NO_PROC_ID (-1)
|
||||||
|
|
||||||
struct smp_fn_call_struct {
|
|
||||||
spinlock_t lock;
|
|
||||||
atomic_t finished;
|
|
||||||
void (*fn)(void *);
|
|
||||||
void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern struct smp_fn_call_struct smp_fn_call;
|
|
||||||
|
|
||||||
#define SMP_MSG_FUNCTION 0
|
#define SMP_MSG_FUNCTION 0
|
||||||
#define SMP_MSG_RESCHEDULE 1
|
#define SMP_MSG_RESCHEDULE 1
|
||||||
#define SMP_MSG_NR 2
|
#define SMP_MSG_FUNCTION_SINGLE 2
|
||||||
|
#define SMP_MSG_NR 3
|
||||||
|
|
||||||
void plat_smp_setup(void);
|
void plat_smp_setup(void);
|
||||||
void plat_prepare_cpus(unsigned int max_cpus);
|
void plat_prepare_cpus(unsigned int max_cpus);
|
||||||
|
@ -46,6 +38,8 @@ void plat_start_cpu(unsigned int cpu, unsigned long entry_point);
|
||||||
void plat_send_ipi(unsigned int cpu, unsigned int message);
|
void plat_send_ipi(unsigned int cpu, unsigned int message);
|
||||||
int plat_register_ipi_handler(unsigned int message,
|
int plat_register_ipi_handler(unsigned int message,
|
||||||
void (*handler)(void *), void *arg);
|
void (*handler)(void *), void *arg);
|
||||||
|
extern void arch_send_call_function_single_ipi(int cpu);
|
||||||
|
extern void arch_send_call_function_ipi(cpumask_t mask);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue