diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index eafbb2b05eb8a2cb7f78a522053f16e4cf70f574..aef6f9ab900ebebe3bd73ee4cbb045b4b601767f 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -454,6 +454,27 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, } EXPORT_SYMBOL_GPL(smp_call_function); +int smp_call_function_single(int cpu, void (*func)(void *info), void *info, + int retry, int wait) +{ + /* prevent preemption and reschedule on another processor */ + int current_cpu = get_cpu(); + int ret = 0; + + if (cpu == current_cpu) { + local_irq_disable(); + func(info); + local_irq_enable(); + } else + ret = smp_call_function_on_cpu(func, info, retry, wait, + cpumask_of_cpu(cpu)); + + put_cpu(); + + return ret; +} +EXPORT_SYMBOL_GPL(smp_call_function_single); + void show_ipi_list(struct seq_file *p) { unsigned int cpu; @@ -481,8 +502,7 @@ void show_local_irqs(struct seq_file *p) static void ipi_timer(void) { irq_enter(); - profile_tick(CPU_PROFILING); - update_process_times(user_mode(get_irq_regs())); + local_timer_interrupt(); irq_exit(); } @@ -621,6 +641,11 @@ void smp_send_timer(void) send_ipi_message(mask, IPI_TIMER); } +void smp_timer_broadcast(cpumask_t mask) +{ + send_ipi_message(mask, IPI_TIMER); +} + void smp_send_stop(void) { cpumask_t mask = cpu_online_map; diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h index f67acce387e7fc1bc0dd18326c5633e4fd2314c2..1f7c51a1886d524e738613479ee2622d8df61be7 100644 --- a/include/asm-arm/smp.h +++ b/include/asm-arm/smp.h @@ -60,6 +60,11 @@ extern void smp_cross_call(cpumask_t callmap); */ extern void smp_send_timer(void); +/* + * Broadcast a clock event to other CPUs. + */ +extern void smp_timer_broadcast(cpumask_t mask); + /* * Boot a secondary CPU, and assign it the specified idle task. * This also gives us the initial stack to use for this CPU. @@ -96,6 +101,11 @@ extern void platform_cpu_die(unsigned int cpu); extern int platform_cpu_kill(unsigned int cpu); extern void platform_cpu_enable(unsigned int cpu); +/* + * Local timer interrupt handling function (can be IPI'ed). + */ +extern void local_timer_interrupt(void); + #ifdef CONFIG_LOCAL_TIMERS /* * Setup a local timer interrupt for a CPU.