From: jbeulich@novell.com Subject: eliminate REBOOT_VECTOR Patch-mainline: n/a We can do without it, and can that way save one event channel per CPU (i.e. a significant number when having many CPUs, given that there are only 1024/4096 of them on 32-/64-bit). --- head-2010-04-15.orig/arch/x86/include/asm/hw_irq.h 2010-03-24 16:00:05.000000000 +0100 +++ head-2010-04-15/arch/x86/include/asm/hw_irq.h 2010-03-30 17:14:57.000000000 +0200 @@ -137,7 +137,6 @@ extern asmlinkage void smp_invalidate_in extern irqreturn_t smp_reschedule_interrupt(int, void *); extern irqreturn_t smp_call_function_interrupt(int, void *); extern irqreturn_t smp_call_function_single_interrupt(int, void *); -extern irqreturn_t smp_reboot_interrupt(int, void *); #endif #endif --- head-2010-04-15.orig/arch/x86/include/mach-xen/asm/irq_vectors.h 2010-03-29 18:11:31.000000000 +0200 +++ head-2010-04-15/arch/x86/include/mach-xen/asm/irq_vectors.h 2010-03-30 17:15:14.000000000 +0200 @@ -12,8 +12,7 @@ #define CALL_FUNCTION_VECTOR 1 #define CALL_FUNC_SINGLE_VECTOR 2 #define SPIN_UNLOCK_VECTOR 3 -#define REBOOT_VECTOR 4 -#define NR_IPIS 5 +#define NR_IPIS 4 /* * The maximum number of vectors supported by i386 processors --- head-2010-04-15.orig/arch/x86/kernel/smp-xen.c 2010-04-15 10:48:32.000000000 +0200 +++ head-2010-04-15/arch/x86/kernel/smp-xen.c 2010-04-15 11:43:22.000000000 +0200 @@ -29,6 +29,9 @@ #include #include #include + +static unsigned int __read_mostly reboot = NR_CPUS; + /* * Some notes on x86 processor bugs affecting SMP operation: * @@ -132,19 +135,6 @@ void xen_send_call_func_ipi(const struct xen_send_IPI_mask_allbutself(mask, CALL_FUNCTION_VECTOR); } -/* - * this function calls the 'stop' function on all other CPUs in the system. - */ - -irqreturn_t smp_reboot_interrupt(int irq, void *dev_id) -{ - irq_enter(); - stop_this_cpu(NULL); - irq_exit(); - - return IRQ_HANDLED; -} - void xen_smp_send_stop(void) { unsigned long flags; @@ -159,8 +149,10 @@ void xen_smp_send_stop(void) * (this implies we cannot stop CPUs spinning with irq off * currently) */ + reboot = raw_smp_processor_id(); + wmb(); if (num_online_cpus() > 1) { - xen_send_IPI_allbutself(REBOOT_VECTOR); + xen_send_IPI_allbutself(RESCHEDULE_VECTOR); /* Don't wait longer than a second */ wait = USEC_PER_SEC; @@ -180,7 +172,13 @@ void xen_smp_send_stop(void) */ irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id) { - inc_irq_stat(irq_resched_count); + if (likely(reboot >= NR_CPUS) || reboot == raw_smp_processor_id()) + inc_irq_stat(irq_resched_count); + else { + irq_enter(); + stop_this_cpu(NULL); + irq_exit(); + } return IRQ_HANDLED; } --- head-2010-04-15.orig/drivers/xen/core/smpboot.c 2010-03-25 14:39:15.000000000 +0100 +++ head-2010-04-15/drivers/xen/core/smpboot.c 2010-04-15 11:43:29.000000000 +0200 @@ -44,7 +44,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_info); static int __read_mostly resched_irq = -1; static int __read_mostly callfunc_irq = -1; static int __read_mostly call1func_irq = -1; -static int __read_mostly reboot_irq = -1; #ifdef CONFIG_X86_LOCAL_APIC #define set_cpu_to_apicid(cpu, apicid) (per_cpu(x86_cpu_to_apicid, cpu) = (apicid)) @@ -118,10 +117,6 @@ static int __cpuinit xen_smp_intr_init(u .handler = smp_call_function_single_interrupt, .flags = IRQF_DISABLED, .name = "call1func" - }, reboot_action = { - .handler = smp_reboot_interrupt, - .flags = IRQF_DISABLED, - .name = "reboot" }; int rc; @@ -155,19 +150,9 @@ static int __cpuinit xen_smp_intr_init(u else BUG_ON(call1func_irq != rc); - rc = bind_ipi_to_irqaction(REBOOT_VECTOR, - cpu, - &reboot_action); - if (rc < 0) - goto unbind_call1; - if (reboot_irq < 0) - reboot_irq = rc; - else - BUG_ON(reboot_irq != rc); - rc = xen_spinlock_init(cpu); if (rc < 0) - goto unbind_reboot; + goto unbind_call1; if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0)) goto fail; @@ -176,8 +161,6 @@ static int __cpuinit xen_smp_intr_init(u fail: xen_spinlock_cleanup(cpu); - unbind_reboot: - unbind_from_per_cpu_irq(reboot_irq, cpu, NULL); unbind_call1: unbind_from_per_cpu_irq(call1func_irq, cpu, NULL); unbind_call: @@ -196,7 +179,6 @@ static void __cpuinit xen_smp_intr_exit( unbind_from_per_cpu_irq(resched_irq, cpu, NULL); unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL); unbind_from_per_cpu_irq(call1func_irq, cpu, NULL); - unbind_from_per_cpu_irq(reboot_irq, cpu, NULL); xen_spinlock_cleanup(cpu); } #endif