mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
[PATCH] i386: add smp_call_function_single
Continiung the series of small patches necessary for the perfmon subsystem, here is a patch that adds support for the smp_call_function_single() function for i386. It exists for almost all other architectures but i386. The perfmon subsystem needs it in one case to free some state on a designated remote CPU. Signed-off-by: Stephane Eranian <eranian@hpl.hp.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
27d26666fc
commit
eaa70773e7
@ -634,3 +634,69 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* this function sends a 'generic call function' IPI to one other CPU
|
||||
* in the system.
|
||||
*
|
||||
* cpu is a standard Linux logical CPU number.
|
||||
*/
|
||||
static void
|
||||
__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
|
||||
int nonatomic, int wait)
|
||||
{
|
||||
struct call_data_struct data;
|
||||
int cpus = 1;
|
||||
|
||||
data.func = func;
|
||||
data.info = info;
|
||||
atomic_set(&data.started, 0);
|
||||
data.wait = wait;
|
||||
if (wait)
|
||||
atomic_set(&data.finished, 0);
|
||||
|
||||
call_data = &data;
|
||||
wmb();
|
||||
/* Send a message to all other CPUs and wait for them to respond */
|
||||
send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
|
||||
|
||||
/* Wait for response */
|
||||
while (atomic_read(&data.started) != cpus)
|
||||
cpu_relax();
|
||||
|
||||
if (!wait)
|
||||
return;
|
||||
|
||||
while (atomic_read(&data.finished) != cpus)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
/*
|
||||
* smp_call_function_single - Run a function on another CPU
|
||||
* @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 until function has completed on other CPUs.
|
||||
*
|
||||
* Retrurns 0 on success, else a negative status code.
|
||||
*
|
||||
* Does not return until the remote CPU is nearly ready to execute <func>
|
||||
* or is or has executed.
|
||||
*/
|
||||
|
||||
int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
|
||||
int nonatomic, int wait)
|
||||
{
|
||||
/* prevent preemption and reschedule on another processor */
|
||||
int me = get_cpu();
|
||||
if (cpu == me) {
|
||||
WARN_ON(1);
|
||||
put_cpu();
|
||||
return -EBUSY;
|
||||
}
|
||||
spin_lock_bh(&call_lock);
|
||||
__smp_call_function_single(cpu, func, info, nonatomic, wait);
|
||||
spin_unlock_bh(&call_lock);
|
||||
put_cpu();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(smp_call_function_single);
|
||||
|
Loading…
Reference in New Issue
Block a user