xtensa: SMP: rework IPI processing
Don't skip current CPU in send_ipi_message: callers of this function take care of it and it's harmless anyway. Don't clear IPI bits one by one, clear all that were read at once. Check IPI register in a loop in case new IPI was posted while previous was being handled. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
05bdebd546
commit
815af8fff1
|
@ -372,8 +372,7 @@ static void send_ipi_message(const struct cpumask *callmask,
|
|||
unsigned long mask = 0;
|
||||
|
||||
for_each_cpu(index, callmask)
|
||||
if (index != smp_processor_id())
|
||||
mask |= 1 << index;
|
||||
mask |= 1 << index;
|
||||
|
||||
set_er(mask, MIPISET(msg_id));
|
||||
}
|
||||
|
@ -412,22 +411,31 @@ irqreturn_t ipi_interrupt(int irq, void *dev_id)
|
|||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
|
||||
unsigned int msg;
|
||||
unsigned i;
|
||||
|
||||
msg = get_er(MIPICAUSE(cpu));
|
||||
for (i = 0; i < IPI_MAX; i++)
|
||||
if (msg & (1 << i)) {
|
||||
set_er(1 << i, MIPICAUSE(cpu));
|
||||
++ipi->ipi_count[i];
|
||||
for (;;) {
|
||||
unsigned int msg;
|
||||
|
||||
msg = get_er(MIPICAUSE(cpu));
|
||||
set_er(msg, MIPICAUSE(cpu));
|
||||
|
||||
if (!msg)
|
||||
break;
|
||||
|
||||
if (msg & (1 << IPI_CALL_FUNC)) {
|
||||
++ipi->ipi_count[IPI_CALL_FUNC];
|
||||
generic_smp_call_function_interrupt();
|
||||
}
|
||||
|
||||
if (msg & (1 << IPI_RESCHEDULE))
|
||||
scheduler_ipi();
|
||||
if (msg & (1 << IPI_CALL_FUNC))
|
||||
generic_smp_call_function_interrupt();
|
||||
if (msg & (1 << IPI_CPU_STOP))
|
||||
ipi_cpu_stop(cpu);
|
||||
if (msg & (1 << IPI_RESCHEDULE)) {
|
||||
++ipi->ipi_count[IPI_RESCHEDULE];
|
||||
scheduler_ipi();
|
||||
}
|
||||
|
||||
if (msg & (1 << IPI_CPU_STOP)) {
|
||||
++ipi->ipi_count[IPI_CPU_STOP];
|
||||
ipi_cpu_stop(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue