static void nmi_shootdown_cpus(void) { unsigned long msecs; local_irq_disable(); crashing_cpu = smp_processor_id(); local_irq_count(crashing_cpu) = 0; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); /* Would it be better to replace the trap vector here? */ set_nmi_callback(crash_nmi_callback); /* Ensure the new callback function is set before sending out the NMI. */ wmb(); smp_send_nmi_allbutself(); msecs = 1000; /* Wait at most a second for the other cpus to stop */ while ( (atomic_read(&waiting_for_crash_ipi) > 0) && msecs ) { mdelay(1); msecs--; } __stop_this_cpu(); disable_IO_APIC(); local_irq_enable(); }
/* * SMP flags value to restore to: * 0 - global cli * 1 - global sti * 2 - local cli * 3 - local sti */ unsigned long __global_save_flags(void) { int retval; int local_enabled; unsigned long flags; int cpu; __save_flags(flags); local_enabled = (flags & ST0_IE); /* default to local */ retval = 2 + local_enabled; /* check for global flags if we're not in an interrupt */ preempt_disable(); cpu = smp_processor_id(); if (!local_irq_count(cpu)) { if (local_enabled) retval = 1; if (global_irq_holder == cpu) retval = 0; } preempt_enable(); return retval; }
void __global_sti(void) { int cpu = smp_processor_id(); if (!local_irq_count(cpu)) release_irqlock(cpu); __sti(); }
void disable_irq(unsigned int irq) { disable_irq_nosync(irq); if (!local_irq_count(smp_processor_id())) { do { barrier(); } while (irq_desc[irq].status & IRQ_INPROGRESS); } }
void __global_sti(void) { int cpu; preempt_disable(); cpu = smp_processor_id(); if (!local_irq_count(cpu)) release_irqlock(cpu); preempt_enable(); __sti(); }
void __global_cli(void) { unsigned long flags; __save_flags(flags); if (flags & ST0_IE) { int cpu = smp_processor_id(); __cli(); if (!local_irq_count(cpu)) get_irqlock(cpu); } }
/* Drop into the prom, with the chance to continue with the 'go' * prom command. */ void prom_cmdline(void) { unsigned long flags; __save_and_cli(flags); #ifdef CONFIG_SUN_CONSOLE if(!serial_console && prom_palette) prom_palette (1); #endif /* We always arrive here via a serial interrupt. * So in order for everything to work reliably, even * on SMP, we need to drop the IRQ locks we hold. */ #ifdef CONFIG_SMP irq_exit(smp_processor_id(), 0); smp_capture(); #else local_irq_count(smp_processor_id())--; #endif p1275_cmd ("enter", P1275_INOUT(0,0)); #ifdef CONFIG_SMP smp_release(); irq_enter(smp_processor_id(), 0); spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock); #else local_irq_count(smp_processor_id())++; #endif #ifdef CONFIG_SUN_CONSOLE if(!serial_console && prom_palette) prom_palette (0); #endif __restore_flags(flags); }
/* * This function must run with irq disabled! */ inline void cpu_raise_softirq(unsigned int cpu, unsigned int nr) { __cpu_raise_softirq(cpu, nr); /* * If we're in an interrupt or bh, we're done * (this also catches bh-disabled code). We will * actually run the softirq once we return from * the irq or bh. * * Otherwise we wake up ksoftirqd to make sure we * schedule the softirq soon. */ if (!(local_irq_count(cpu) | local_bh_count(cpu))) wakeup_softirqd(cpu); }
static void nmi_shootdown_cpus(void) { unsigned long msecs; local_irq_disable(); if ( hpet_broadcast_is_available() ) hpet_disable_legacy_broadcast(); crashing_cpu = smp_processor_id(); local_irq_count(crashing_cpu) = 0; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); /* Would it be better to replace the trap vector here? */ set_nmi_callback(crash_nmi_callback); /* Ensure the new callback function is set before sending out the NMI. */ wmb(); smp_send_nmi_allbutself(); msecs = 1000; /* Wait at most a second for the other cpus to stop */ while ( (atomic_read(&waiting_for_crash_ipi) > 0) && msecs ) { mdelay(1); msecs--; } /* Crash shutdown any IOMMU functionality as the crashdump kernel is not * happy when booting if interrupt/dma remapping is still enabled */ iommu_crash_shutdown(); __stop_this_cpu(); /* This is a bit of a hack due to the problems with the x2apic_enabled * variable, but we can't do any better without a significant refactoring * of the APIC code */ x2apic_enabled = (current_local_apic_mode() == APIC_MODE_X2APIC); disable_IO_APIC(); hpet_disable(); }