149 lines
4.5 KiB
Plaintext
149 lines
4.5 KiB
Plaintext
|
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 <asm/proto.h>
|
||
|
#include <asm/ipi.h>
|
||
|
#include <xen/evtchn.h>
|
||
|
+
|
||
|
+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
|