/* * Main handler for inter-processor interrupts */ void handle_IPI(int ipinr, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); if ((unsigned)ipinr < NR_IPI) { trace_ipi_entry_rcuidle(ipi_types[ipinr]); __inc_irq_stat(cpu, ipi_irqs[ipinr]); } switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: irq_enter(); generic_smp_call_function_interrupt(); irq_exit(); break; case IPI_CPU_STOP: irq_enter(); ipi_cpu_stop(cpu); irq_exit(); break; #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: irq_enter(); tick_receive_broadcast(); irq_exit(); break; #endif #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: irq_enter(); irq_work_run(); irq_exit(); break; #endif #ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL case IPI_WAKEUP: WARN_ONCE(!acpi_parking_protocol_valid(cpu), "CPU%u: Wake-up IPI outside the ACPI parking protocol\n", cpu); break; #endif default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); set_irq_regs(old_regs); }
/* * Main handler for inter-processor interrupts */ void handle_IPI(int ipinr, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); if ((unsigned)ipinr < NR_IPI) { trace_ipi_entry_rcuidle(ipi_types[ipinr]); __inc_irq_stat(cpu, ipi_irqs[ipinr]); } switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: irq_enter(); generic_smp_call_function_interrupt(); irq_exit(); break; case IPI_CPU_STOP: irq_enter(); ipi_cpu_stop(cpu); irq_exit(); break; #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: irq_enter(); tick_receive_broadcast(); irq_exit(); break; #endif #ifdef CONFIG_IRQ_WORK case IPI_IRQ_WORK: irq_enter(); irq_work_run(); irq_exit(); break; #endif default: if (ipi_custom_irq_domain && ipinr >= IPI_CUSTOM_FIRST && ipinr <= IPI_CUSTOM_LAST) handle_domain_irq(ipi_custom_irq_domain, ipinr, regs); else pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } if ((unsigned)ipinr < NR_IPI) trace_ipi_exit_rcuidle(ipi_types[ipinr]); set_irq_regs(old_regs); }