void smp_message_recv(int msg) { switch(msg) { case PPC_MSG_CALL_FUNCTION: generic_smp_call_function_interrupt(); break; case PPC_MSG_RESCHEDULE: /* we notice need_resched on exit */ break; case PPC_MSG_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); break; case PPC_MSG_DEBUGGER_BREAK: if (crash_ipi_function_ptr) { crash_ipi_function_ptr(get_irq_regs()); break; } #ifdef CONFIG_DEBUGGER debugger_ipi(get_irq_regs()); break; #endif /* CONFIG_DEBUGGER */ /* FALLTHROUGH */ default: printk("SMP %d: smp_message_recv(): unknown msg %d\n", smp_processor_id(), msg); break; } }
irqreturn_t smp_ipi_demux(void) { struct cpu_messages *info = &__get_cpu_var(ipi_message); unsigned int all; mb(); /* order any irq clear */ do { all = xchg_local(&info->messages, 0); #ifdef __BIG_ENDIAN if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION))) generic_smp_call_function_interrupt(); if (all & (1 << (24 - 8 * PPC_MSG_RESCHEDULE))) scheduler_ipi(); if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNC_SINGLE))) generic_smp_call_function_single_interrupt(); if (all & (1 << (24 - 8 * PPC_MSG_DEBUGGER_BREAK))) debug_ipi_action(0, NULL); #else #error Unsupported ENDIAN #endif } while (info->messages); return IRQ_HANDLED; }
void smp_call_function_single_interrupt(void) { irq_enter(); generic_smp_call_function_single_interrupt(); local_cpu_data().irq_call_count++; irq_exit(); }
void smp_call_function_single_interrupt(struct pt_regs *regs) { //l4/ack_APIC_irq(); irq_enter(); generic_smp_call_function_single_interrupt(); inc_irq_stat(irq_call_count); irq_exit(); }
/* * 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(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_CALL_FUNC_SINGLE: irq_enter(); generic_smp_call_function_single_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: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } if ((unsigned)ipinr < NR_IPI) trace_ipi_exit(ipi_types[ipinr]); set_irq_regs(old_regs); }
static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id) { irq_enter(); generic_smp_call_function_single_interrupt(); inc_irq_stat(irq_call_count); irq_exit(); return IRQ_HANDLED; }
__visible void __irq_entry smp_call_function_single_interrupt(struct pt_regs *r) { ipi_entering_ack_irq(); trace_call_function_single_entry(CALL_FUNCTION_SINGLE_VECTOR); inc_irq_stat(irq_call_count); generic_smp_call_function_single_interrupt(); trace_call_function_single_exit(CALL_FUNCTION_SINGLE_VECTOR); exiting_irq(); }
static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id) { irq_enter(); generic_smp_call_function_single_interrupt(); #ifdef CONFIG_X86_32 __get_cpu_var(irq_stat).irq_call_count++; #else add_pda(irq_call_count, 1); #endif irq_exit(); return IRQ_HANDLED; }
/* * 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 (ipinr >= IPI_RESCHEDULE && ipinr < IPI_RESCHEDULE + NR_IPI) __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_RESCHEDULE]); exynos_ss_irq(ipinr, handle_IPI, irqs_disabled(), ESS_FLAG_IN); switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: irq_enter(); generic_smp_call_function_interrupt(); irq_exit(); break; case IPI_CALL_FUNC_SINGLE: irq_enter(); generic_smp_call_function_single_interrupt(); irq_exit(); break; case IPI_CPU_STOP: irq_enter(); ipi_cpu_stop(cpu, regs); irq_exit(); break; #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case IPI_TIMER: irq_enter(); tick_receive_broadcast(); irq_exit(); break; #endif case IPI_WAKEUP: break; default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } exynos_ss_irq(ipinr, handle_IPI, irqs_disabled(), ESS_FLAG_OUT); 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(ipi_types[ipinr]); __inc_irq_stat(cpu, ipi_irqs[ipinr]); } switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: irq_enter(); mt_trace_ISR_start(ipinr); generic_smp_call_function_interrupt(); mt_trace_ISR_end(ipinr); irq_exit(); break; case IPI_CALL_FUNC_SINGLE: irq_enter(); mt_trace_ISR_start(ipinr); generic_smp_call_function_single_interrupt(); mt_trace_ISR_end(ipinr); irq_exit(); break; case IPI_CPU_STOP: irq_enter(); mt_trace_ISR_start(ipinr); ipi_cpu_stop(cpu); mt_trace_ISR_end(ipinr); irq_exit(); break; default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; } if ((unsigned)ipinr < NR_IPI) trace_ipi_exit(ipi_types[ipinr]); set_irq_regs(old_regs); }
irqreturn_t handle_IPI (int irq, void *dev_id) { int this_cpu = get_cpu(); unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation); unsigned long ops; mb(); /* */ while ((ops = xchg(pending_ipis, 0)) != 0) { mb(); /* */ do { unsigned long which; which = ffz(~ops); ops &= ~(1 << which); switch (which) { case IPI_CPU_STOP: stop_this_cpu(); break; case IPI_CALL_FUNC: generic_smp_call_function_interrupt(); break; case IPI_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); break; #ifdef CONFIG_KEXEC case IPI_KDUMP_CPU_STOP: unw_init_running(kdump_cpu_freeze, NULL); break; #endif default: printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); break; } } while (ops); mb(); /* */ } put_cpu(); return IRQ_HANDLED; }
static void do_ext_call_interrupt(unsigned int ext_int_code, unsigned int param32, unsigned long param64) { unsigned long bits; kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++; /* * handle bit signal external calls */ bits = xchg(&S390_lowcore.ext_call_fast, 0); if (test_bit(ec_schedule, &bits)) scheduler_ipi(); if (test_bit(ec_call_function, &bits)) generic_smp_call_function_interrupt(); if (test_bit(ec_call_function_single, &bits)) generic_smp_call_function_single_interrupt(); }
void smp_message_recv(unsigned int msg) { switch (msg) { case SMP_MSG_FUNCTION: generic_smp_call_function_interrupt(); break; case SMP_MSG_RESCHEDULE: break; case SMP_MSG_FUNCTION_SINGLE: generic_smp_call_function_single_interrupt(); break; case SMP_MSG_TIMER: ipi_timer(); break; default: printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n", smp_processor_id(), __func__, msg); break; } }
irqreturn_t smp_ipi_demux(void) { struct cpu_messages *info = &__get_cpu_var(ipi_message); unsigned int all; mb(); /* order any irq clear */ do { all = xchg(&info->messages, 0); if (all & IPI_MESSAGE(PPC_MSG_CALL_FUNCTION)) generic_smp_call_function_interrupt(); if (all & IPI_MESSAGE(PPC_MSG_RESCHEDULE)) scheduler_ipi(); if (all & IPI_MESSAGE(PPC_MSG_CALL_FUNC_SINGLE)) generic_smp_call_function_single_interrupt(); if (all & IPI_MESSAGE(PPC_MSG_DEBUGGER_BREAK)) debug_ipi_action(0, NULL); } while (info->messages); return IRQ_HANDLED; }
static irqreturn_t ipi_handler_int1(int irq, void *dev_instance) { struct ipi_data *bfin_ipi_data; unsigned int cpu = smp_processor_id(); unsigned long pending; unsigned long msg; platform_clear_ipi(cpu, IRQ_SUPPLE_1); bfin_ipi_data = &__get_cpu_var(bfin_ipi); smp_mb(); while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) { msg = 0; do { msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1); switch (msg) { case BFIN_IPI_TIMER: ipi_timer(); break; case BFIN_IPI_RESCHEDULE: scheduler_ipi(); break; case BFIN_IPI_CALL_FUNC: generic_smp_call_function_interrupt(); break; case BFIN_IPI_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); break; case BFIN_IPI_CPU_STOP: ipi_cpu_stop(cpu); break; } } while (msg < BITS_PER_LONG); smp_mb(); } return IRQ_HANDLED; }
void smp_message_recv(unsigned int msg) { switch (msg) { case SMP_MSG_FUNCTION: generic_smp_call_function_interrupt(); break; case SMP_MSG_RESCHEDULE: scheduler_ipi(); break; case SMP_MSG_FUNCTION_SINGLE: generic_smp_call_function_single_interrupt(); break; #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case SMP_MSG_TIMER: ipi_timer(); break; #endif default: printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n", smp_processor_id(), __func__, msg); break; } }
void handle_IPI(int ipinr) { unsigned int cpu = smp_processor_id(); switch (ipinr) { case IPI_RESCHEDULE: scheduler_ipi(); break; case IPI_CALL_FUNC: generic_smp_call_function_interrupt(); break; case IPI_CALL_FUNC_SINGLE: generic_smp_call_function_single_interrupt(); break; default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); BUG(); break; } }
void smp_call_function_single_interrupt(void) { irq_enter(); generic_smp_call_function_single_interrupt(); irq_exit(); }
static irqreturn_t call_function_single_action(int irq, void *data) { generic_smp_call_function_single_interrupt(); return IRQ_HANDLED; }
irqreturn_t __irq_entry ipi_interrupt(int irq, void *dev_id) { int this_cpu = smp_processor_id(); struct cpuinfo_parisc *p = &per_cpu(cpu_data, this_cpu); unsigned long ops; unsigned long flags; /* Count this now; we may make a call that never returns. */ p->ipi_count++; mb(); /* Order interrupt and bit testing. */ for (;;) { spinlock_t *lock = &per_cpu(ipi_lock, this_cpu); spin_lock_irqsave(lock, flags); ops = p->pending_ipi; p->pending_ipi = 0; spin_unlock_irqrestore(lock, flags); mb(); /* Order bit clearing and data access. */ if (!ops) break; while (ops) { unsigned long which = ffz(~ops); ops &= ~(1 << which); switch (which) { case IPI_NOP: smp_debug(100, KERN_DEBUG "CPU%d IPI_NOP\n", this_cpu); break; case IPI_RESCHEDULE: smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu); scheduler_ipi(); break; case IPI_CALL_FUNC: smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC\n", this_cpu); generic_smp_call_function_interrupt(); break; case IPI_CALL_FUNC_SINGLE: smp_debug(100, KERN_DEBUG "CPU%d IPI_CALL_FUNC_SINGLE\n", this_cpu); generic_smp_call_function_single_interrupt(); break; case IPI_CPU_START: smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_START\n", this_cpu); break; case IPI_CPU_STOP: smp_debug(100, KERN_DEBUG "CPU%d IPI_CPU_STOP\n", this_cpu); halt_processor(); break; case IPI_CPU_TEST: smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu); break; default: printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", this_cpu, which); return IRQ_NONE; } /* Switch */ /* let in any pending interrupts */ local_irq_enable(); local_irq_disable(); } /* while (ops) */ } return IRQ_HANDLED; }
/* * ipi_interrupt() * Handle an Interprocessor Interrupt. */ static irqreturn_t ipi_interrupt(int irq, void *dev_id) { int cpuid = smp_processor_id(); struct cpuinfo_ubicom32 *p = &per_cpu(cpu_data, cpuid); unsigned long ops; /* * Count this now; we may make a call that never returns. */ p->ipi_count++; /* * We are about to process all ops. If another cpu has stated * that we need an IPI, we will have already processed it. By * clearing our smp_needs_ipi, and processing all ops, * we reduce the number of IPI interrupts. However, this introduces * the possibility that smp_needs_ipi will be clear and the soft irq * will have gone off; so we need to make the get_affinity() path * tolerant of spurious interrupts. */ spin_lock(&smp_ipi_lock); smp_needs_ipi &= ~(1 << p->tid); spin_unlock(&smp_ipi_lock); for (;;) { /* * Read the set of IPI commands we should handle. */ spinlock_t *lock = &per_cpu(ipi_lock, cpuid); spin_lock(lock); ops = p->ipi_pending; p->ipi_pending = 0; spin_unlock(lock); /* * If we have no IPI commands to execute, break out. */ if (!ops) { break; } /* * Execute the set of commands in the ops word, one command * at a time in no particular order. Strip of each command * as we execute it. */ while (ops) { unsigned long which = ffz(~ops); ops &= ~(1 << which); BUG_ON(!irqs_disabled()); switch (which) { case IPI_NOP: smp_debug(100, KERN_INFO "cpu[%d]: " "IPI_NOP\n", cpuid); break; case IPI_RESCHEDULE: /* * Reschedule callback. Everything to be * done is done by the interrupt return path. */ smp_debug(200, KERN_INFO "cpu[%d]: " "IPI_RESCHEDULE\n", cpuid); break; case IPI_CALL_FUNC: smp_debug(100, KERN_INFO "cpu[%d]: " "IPI_CALL_FUNC\n", cpuid); generic_smp_call_function_interrupt(); break; case IPI_CALL_FUNC_SINGLE: smp_debug(100, KERN_INFO "cpu[%d]: " "IPI_CALL_FUNC_SINGLE\n", cpuid); generic_smp_call_function_single_interrupt(); break; case IPI_CPU_STOP: smp_debug(100, KERN_INFO "cpu[%d]: " "IPI_CPU_STOP\n", cpuid); smp_halt_processor(); break; #if !defined(CONFIG_LOCAL_TIMERS) case IPI_CPU_TIMER: smp_debug(100, KERN_INFO "cpu[%d]: " "IPI_CPU_TIMER\n", cpuid); #if defined(CONFIG_GENERIC_CLOCKEVENTS) local_timer_interrupt(); #else update_process_times(user_mode(get_irq_regs())); profile_tick(CPU_PROFILING); #endif #endif break; default: printk(KERN_CRIT "cpu[%d]: " "Unknown IPI: %lu\n", cpuid, which); return IRQ_NONE; } } } return IRQ_HANDLED; }
static inline void __smp_call_function_single_interrupt(void) { generic_smp_call_function_single_interrupt(); inc_irq_stat(irq_call_count); }