Subject: fold IPIs onto a single IRQ each
Patch-mainline: obsolete
-Index: head-2008-12-01/arch/x86/kernel/genapic_xen_64.c
-===================================================================
---- head-2008-12-01.orig/arch/x86/kernel/genapic_xen_64.c 2008-11-25 13:12:11.000000000 +0100
-+++ head-2008-12-01/arch/x86/kernel/genapic_xen_64.c 2008-12-01 12:07:34.000000000 +0100
-@@ -25,13 +25,9 @@
+--- sle11-2009-06-04.orig/arch/x86/kernel/genapic_xen_64.c 2009-06-04 10:46:34.000000000 +0200
++++ sle11-2009-06-04/arch/x86/kernel/genapic_xen_64.c 2009-06-04 10:47:21.000000000 +0200
+@@ -25,13 +25,13 @@
#include <asm/genapic.h>
#include <xen/evtchn.h>
- int irq = per_cpu(ipi_to_irq, cpu)[vector];
- BUG_ON(irq < 0);
- notify_remote_via_irq(irq);
++#ifdef CONFIG_SMP
+ notify_remote_via_ipi(vector, cpu);
++#else
++ BUG();
++#endif
}
static void xen_send_IPI_shortcut(unsigned int shortcut,
-Index: head-2008-12-01/arch/x86/kernel/ipi-xen.c
-===================================================================
---- head-2008-12-01.orig/arch/x86/kernel/ipi-xen.c 2008-11-25 13:12:11.000000000 +0100
-+++ head-2008-12-01/arch/x86/kernel/ipi-xen.c 2008-12-01 12:07:34.000000000 +0100
+--- sle11-2009-06-04.orig/arch/x86/kernel/ipi-xen.c 2009-06-04 10:46:34.000000000 +0200
++++ sle11-2009-06-04/arch/x86/kernel/ipi-xen.c 2009-06-04 10:47:21.000000000 +0200
@@ -48,15 +48,6 @@ static inline int __prepare_ICR2(unsigne
}
#else
default:
printk("XXXXXX __send_IPI_shortcut %08x vector %d\n", shortcut,
@@ -165,7 +156,7 @@ void send_IPI_mask_bitmask(const cpumask
- WARN_ON(!cpus_empty(mask));
+ WARN_ON(!cpus_subset(*cpumask, cpu_online_map));
for_each_online_cpu(cpu)
- if (cpu_isset(cpu, cpumask))
+ if (cpu_isset(cpu, *cpumask))
- __send_IPI_one(cpu, vector);
+ notify_remote_via_ipi(vector, cpu);
#endif
local_irq_restore(flags);
}
-Index: head-2008-12-01/arch/x86/kernel/irq_32-xen.c
-===================================================================
---- head-2008-12-01.orig/arch/x86/kernel/irq_32-xen.c 2008-12-01 11:49:07.000000000 +0100
-+++ head-2008-12-01/arch/x86/kernel/irq_32-xen.c 2008-12-01 12:07:34.000000000 +0100
+--- sle11-2009-06-04.orig/arch/x86/kernel/irq_32-xen.c 2009-06-04 10:21:39.000000000 +0200
++++ sle11-2009-06-04/arch/x86/kernel/irq_32-xen.c 2009-06-04 10:47:21.000000000 +0200
@@ -404,6 +404,9 @@ void fixup_irqs(cpumask_t map)
if (irq == 2)
continue;
cpus_and(mask, irq_desc[irq].affinity, map);
if (any_online_cpu(mask) == NR_CPUS) {
/*printk("Breaking affinity for irq %i\n", irq);*/
-Index: head-2008-12-01/arch/x86/kernel/irq_64-xen.c
-===================================================================
---- head-2008-12-01.orig/arch/x86/kernel/irq_64-xen.c 2008-12-01 11:49:07.000000000 +0100
-+++ head-2008-12-01/arch/x86/kernel/irq_64-xen.c 2008-12-01 12:07:34.000000000 +0100
+--- sle11-2009-06-04.orig/arch/x86/kernel/irq_64-xen.c 2009-06-04 10:21:39.000000000 +0200
++++ sle11-2009-06-04/arch/x86/kernel/irq_64-xen.c 2009-06-04 10:47:21.000000000 +0200
@@ -245,6 +245,7 @@ void fixup_irqs(cpumask_t map)
spin_lock(&irq_desc[irq].lock);
cpus_equal(irq_desc[irq].affinity, map)) {
spin_unlock(&irq_desc[irq].lock);
continue;
-Index: head-2008-12-01/drivers/xen/Kconfig
-===================================================================
---- head-2008-12-01.orig/drivers/xen/Kconfig 2008-10-24 10:52:17.000000000 +0200
-+++ head-2008-12-01/drivers/xen/Kconfig 2008-12-01 12:07:34.000000000 +0100
+--- sle11-2009-06-04.orig/drivers/xen/Kconfig 2009-06-04 10:47:17.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/Kconfig 2009-06-04 10:47:21.000000000 +0200
@@ -4,6 +4,7 @@
config XEN
config NO_IDLE_HZ
def_bool y
-Index: head-2008-12-01/drivers/xen/core/evtchn.c
-===================================================================
---- head-2008-12-01.orig/drivers/xen/core/evtchn.c 2008-12-02 09:14:14.000000000 +0100
-+++ head-2008-12-01/drivers/xen/core/evtchn.c 2008-12-02 09:14:29.000000000 +0100
-@@ -57,6 +57,22 @@ static DEFINE_SPINLOCK(irq_mapping_updat
+--- sle11-2009-06-04.orig/drivers/xen/core/evtchn.c 2009-06-04 10:47:20.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/evtchn.c 2009-06-04 10:47:21.000000000 +0200
+@@ -58,6 +58,22 @@ static DEFINE_SPINLOCK(irq_mapping_updat
static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
[0 ... NR_EVENT_CHANNELS-1] = -1 };
+#endif
+#if defined(CONFIG_SMP) && defined(CONFIG_X86)
+static int ipi_to_irq[NR_IPIS] __read_mostly = {[0 ... NR_IPIS-1] = -1};
-+static DEFINE_PER_CPU(int[NR_IPIS], ipi_to_evtchn) = {[0 ... NR_IPIS-1] = -1};
++static DEFINE_PER_CPU(int[NR_IPIS], ipi_to_evtchn);
+#else
+#define PER_CPU_IPI_IRQ
+#endif
/* Packed IRQ information: binding type, sub-type index, and event channel. */
static u32 irq_info[NR_IRQS];
-@@ -97,10 +113,12 @@ static inline u32 mk_irq_info(u32 type,
+@@ -98,10 +114,12 @@ static inline u32 mk_irq_info(u32 type,
* Accessors for packed IRQ information.
*/
static inline unsigned int index_from_irq(int irq)
{
-@@ -112,14 +130,28 @@ static inline unsigned int type_from_irq
+@@ -113,14 +131,28 @@ static inline unsigned int type_from_irq
return irq_info[irq] >> (32 - _IRQT_BITS);
}
/* Reference counts for bindings to IRQs. */
static int irq_bindcount[NR_IRQS];
-@@ -144,8 +176,14 @@ static void bind_evtchn_to_cpu(unsigned
+@@ -145,8 +177,14 @@ static void bind_evtchn_to_cpu(unsigned
BUG_ON(!test_bit(chn, s->evtchn_mask));
clear_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu_evtchn[chn]]);
set_bit(chn, (unsigned long *)cpu_evtchn_mask[cpu]);
-@@ -439,6 +477,7 @@ static int bind_virq_to_irq(unsigned int
+@@ -315,14 +353,29 @@ asmlinkage void evtchn_do_upcall(struct
+ irq_exit();
+ }
+
+-static int find_unbound_irq(void)
++static struct irq_chip dynirq_chip;
++
++static int find_unbound_irq(bool percpu)
+ {
+ static int warned;
+ int irq;
+
+ for (irq = DYNIRQ_BASE; irq < (DYNIRQ_BASE + NR_DYNIRQS); irq++)
+- if (irq_bindcount[irq] == 0)
++ if (irq_bindcount[irq] == 0) {
++ irq_flow_handler_t handle;
++ const char *name;
++
++ if (!percpu) {
++ handle = handle_level_irq;
++ name = "level";
++ } else {
++ handle = handle_percpu_irq;
++ name = "percpu";
++ }
++ set_irq_chip_and_handler_name(irq, &dynirq_chip,
++ handle, name);
+ return irq;
++ }
+
+ if (!warned) {
+ warned = 1;
+@@ -340,7 +393,7 @@ static int bind_caller_port_to_irq(unsig
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((irq = evtchn_to_irq[caller_port]) == -1) {
+- if ((irq = find_unbound_irq()) < 0)
++ if ((irq = find_unbound_irq(false)) < 0)
+ goto out;
+
+ evtchn_to_irq[caller_port] = irq;
+@@ -362,7 +415,7 @@ static int bind_local_port_to_irq(unsign
+
+ BUG_ON(evtchn_to_irq[local_port] != -1);
+
+- if ((irq = find_unbound_irq()) < 0) {
++ if ((irq = find_unbound_irq(false)) < 0) {
+ struct evtchn_close close = { .port = local_port };
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
+ BUG();
+@@ -415,7 +468,7 @@ static int bind_virq_to_irq(unsigned int
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
+- if ((irq = find_unbound_irq()) < 0)
++ if ((irq = find_unbound_irq(false)) < 0)
+ goto out;
+
+ bind_virq.virq = virq;
+@@ -440,6 +493,7 @@ static int bind_virq_to_irq(unsigned int
return irq;
}
static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
struct evtchn_bind_ipi bind_ipi;
-@@ -470,6 +509,7 @@ static int bind_ipi_to_irq(unsigned int
+@@ -448,7 +502,7 @@ static int bind_ipi_to_irq(unsigned int
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
+- if ((irq = find_unbound_irq()) < 0)
++ if ((irq = find_unbound_irq(false)) < 0)
+ goto out;
+
+ bind_ipi.vcpu = cpu;
+@@ -471,6 +525,7 @@ static int bind_ipi_to_irq(unsigned int
spin_unlock(&irq_mapping_update_lock);
return irq;
}
static void unbind_from_irq(unsigned int irq)
{
-@@ -477,6 +517,7 @@ static void unbind_from_irq(unsigned int
+@@ -478,6 +533,7 @@ static void unbind_from_irq(unsigned int
unsigned int cpu;
int evtchn = evtchn_from_irq(irq);
spin_lock(&irq_mapping_update_lock);
if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
-@@ -490,10 +531,12 @@ static void unbind_from_irq(unsigned int
+@@ -491,10 +547,12 @@ static void unbind_from_irq(unsigned int
per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
[index_from_irq(irq)] = -1;
break;
default:
break;
}
-@@ -512,6 +555,46 @@ static void unbind_from_irq(unsigned int
+@@ -513,6 +571,46 @@ static void unbind_from_irq(unsigned int
spin_unlock(&irq_mapping_update_lock);
}
+
+ switch (type_from_irq(irq)) {
+ case IRQT_IPI:
-+ per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = -1;
++ per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = 0;
+ break;
+ default:
+ BUG();
int bind_caller_port_to_irqhandler(
unsigned int caller_port,
irq_handler_t handler,
-@@ -606,6 +689,8 @@ int bind_virq_to_irqhandler(
+@@ -607,6 +705,8 @@ int bind_virq_to_irqhandler(
}
EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
int bind_ipi_to_irqhandler(
unsigned int ipi,
unsigned int cpu,
-@@ -628,7 +713,72 @@ int bind_ipi_to_irqhandler(
+@@ -629,7 +729,71 @@ int bind_ipi_to_irqhandler(
return irq;
}
+
+ spin_lock(&irq_mapping_update_lock);
+
-+ if (per_cpu(ipi_to_evtchn, cpu)[ipi] != -1) {
++ if (VALID_EVTCHN(per_cpu(ipi_to_evtchn, cpu)[ipi])) {
+ spin_unlock(&irq_mapping_update_lock);
+ return -EBUSY;
+ }
+
+ if ((irq = ipi_to_irq[ipi]) == -1) {
-+ if ((irq = find_unbound_irq()) < 0) {
++ if ((irq = find_unbound_irq(true)) < 0) {
+ spin_unlock(&irq_mapping_update_lock);
+ return irq;
+ }
+
+ ipi_to_irq[ipi] = irq;
+ irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, 0);
-+ irq_desc[irq].handle_irq = handle_percpu_irq;
+ retval = 1;
+ }
+
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
-@@ -654,6 +804,7 @@ static void rebind_irq_to_cpu(unsigned i
+@@ -655,6 +819,7 @@ static void rebind_irq_to_cpu(unsigned i
{
int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
rebind_evtchn_to_cpu(evtchn, tcpu);
}
-@@ -737,6 +888,7 @@ static struct irq_chip dynirq_chip = {
+@@ -739,6 +904,7 @@ static struct irq_chip dynirq_chip = {
.unmask = unmask_dynirq,
.mask_ack = ack_dynirq,
.ack = ack_dynirq,
.end = end_dynirq,
#ifdef CONFIG_SMP
.set_affinity = set_affinity_irq,
-@@ -909,10 +1061,21 @@ int irq_ignore_unhandled(unsigned int ir
+@@ -918,10 +1084,21 @@ int irq_ignore_unhandled(unsigned int ir
return !!(irq_status.flags & XENIRQSTAT_shared);
}
if (VALID_EVTCHN(evtchn))
notify_remote_via_evtchn(evtchn);
}
-@@ -920,6 +1083,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
+@@ -929,6 +1106,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
int irq_to_evtchn_port(int irq)
{
return evtchn_from_irq(irq);
}
EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
-@@ -1035,11 +1199,16 @@ static void restore_cpu_virqs(unsigned i
+@@ -1044,11 +1222,17 @@ static void restore_cpu_virqs(unsigned i
static void restore_cpu_ipis(unsigned int cpu)
{
+#ifdef PER_CPU_IPI_IRQ
if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1)
+#else
-+ if ((irq = ipi_to_irq[ipi]) == -1)
++ if ((irq = ipi_to_irq[ipi]) == -1
++ || !VALID_EVTCHN(per_cpu(ipi_to_evtchn, cpu)[ipi]))
+#endif
continue;
BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
-@@ -1053,13 +1222,17 @@ static void restore_cpu_ipis(unsigned in
+@@ -1062,13 +1246,18 @@ static void restore_cpu_ipis(unsigned in
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
bind_evtchn_to_cpu(evtchn, cpu);
/* Ready for use. */
- unmask_evtchn(evtchn);
--
+ if (!(irq_desc[irq].status & IRQ_DISABLED))
+ unmask_evtchn(evtchn);
}
+#endif
}
static int evtchn_resume(struct sys_device *dev)
-@@ -1103,8 +1276,17 @@ static int evtchn_resume(struct sys_devi
+@@ -1239,8 +1428,6 @@ void __init xen_init_IRQ(void)
+ irq_bindcount[i] = 0;
- for_each_possible_cpu(cpu) {
- restore_cpu_virqs(cpu);
-+#ifdef PER_CPU_IPI_IRQ
- restore_cpu_ipis(cpu);
-+#else
-+ /* No IPI <-> event-channel mappings. */
-+ for (irq = 0; irq < NR_IPIS; ++irq)
-+ per_cpu(ipi_to_evtchn, cpu)[irq] = -1;
-+#endif
+ irq_desc[i].status |= IRQ_NOPROBE;
+- set_irq_chip_and_handler_name(i, &dynirq_chip,
+- handle_level_irq, "level");
}
-+#ifndef PER_CPU_IPI_IRQ
-+ restore_cpu_ipis(smp_processor_id());
-+#endif
- return 0;
- }
-Index: head-2008-12-01/drivers/xen/core/smpboot.c
-===================================================================
---- head-2008-12-01.orig/drivers/xen/core/smpboot.c 2008-12-01 12:07:15.000000000 +0100
-+++ head-2008-12-01/drivers/xen/core/smpboot.c 2008-12-01 12:07:34.000000000 +0100
-@@ -53,12 +53,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
- DEFINE_PER_CPU(int, cpu_state) = { 0 };
- #endif
+ /* Phys IRQ space is statically bound (1:1 mapping). Nail refcnts. */
+--- sle11-2009-06-04.orig/drivers/xen/core/smpboot.c 2009-06-04 10:47:07.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/smpboot.c 2009-06-04 10:47:21.000000000 +0200
+@@ -49,12 +49,9 @@ cpumask_t cpu_initialized_map;
+ DEFINE_PER_CPU(struct cpuinfo_x86, cpu_info);
+ EXPORT_PER_CPU_SYMBOL(cpu_info);
-static DEFINE_PER_CPU(int, resched_irq);
-static DEFINE_PER_CPU(int, callfunc_irq);
#ifdef CONFIG_X86_LOCAL_APIC
#define set_cpu_to_apicid(cpu, apicid) (per_cpu(x86_cpu_to_apicid, cpu) = (apicid))
-@@ -117,43 +114,50 @@ remove_siblinginfo(unsigned int cpu)
+@@ -109,47 +106,54 @@ remove_siblinginfo(unsigned int cpu)
static int __cpuinit xen_smp_intr_init(unsigned int cpu)
{
+ cpu,
+ &resched_action);
if (rc < 0)
- goto fail;
+- goto fail;
- per_cpu(resched_irq, cpu) = rc;
-
- sprintf(callfunc_name[cpu], "callfunc%u", cpu);
- IRQF_DISABLED|IRQF_NOBALANCING,
- callfunc_name[cpu],
- NULL);
++ return rc;
+ if (resched_irq < 0)
+ resched_irq = rc;
+ else
+ cpu,
+ &callfunc_action);
if (rc < 0)
- goto fail;
+- goto fail;
- per_cpu(callfunc_irq, cpu) = rc;
-
- sprintf(call1func_name[cpu], "call1func%u", cpu);
- IRQF_DISABLED|IRQF_NOBALANCING,
- call1func_name[cpu],
- NULL);
++ goto unbind_resched;
+ if (callfunc_irq < 0)
+ callfunc_irq = rc;
+ else
+ cpu,
+ &call1func_action);
if (rc < 0)
- goto fail;
+- goto fail;
- per_cpu(call1func_irq, cpu) = rc;
++ goto unbind_call;
+ if (call1func_irq < 0)
+ call1func_irq = rc;
+ else
rc = xen_spinlock_init(cpu);
if (rc < 0)
-@@ -165,12 +169,12 @@ static int __cpuinit xen_smp_intr_init(u
+- goto fail;
++ goto unbind_call1;
+
+ if ((cpu != 0) && ((rc = local_setup_timer(cpu)) != 0))
+ goto fail;
+@@ -157,13 +161,13 @@ static int __cpuinit xen_smp_intr_init(u
return 0;
fail:
- unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
- if (per_cpu(call1func_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(call1func_irq, cpu), NULL);
-+ if (resched_irq >= 0)
-+ unbind_from_per_cpu_irq(resched_irq, cpu);
-+ if (callfunc_irq >= 0)
-+ unbind_from_per_cpu_irq(callfunc_irq, cpu);
-+ if (call1func_irq >= 0)
-+ unbind_from_per_cpu_irq(call1func_irq, cpu);
xen_spinlock_cleanup(cpu);
++ unbind_call1:
++ unbind_from_per_cpu_irq(call1func_irq, cpu);
++ unbind_call:
++ unbind_from_per_cpu_irq(callfunc_irq, cpu);
++ unbind_resched:
++ unbind_from_per_cpu_irq(resched_irq, cpu);
return rc;
}
-@@ -181,9 +185,9 @@ static void __cpuinit xen_smp_intr_exit(
+
+@@ -173,9 +177,9 @@ static void __cpuinit xen_smp_intr_exit(
if (cpu != 0)
local_teardown_timer(cpu);
xen_spinlock_cleanup(cpu);
}
#endif
-Index: head-2008-12-01/drivers/xen/core/spinlock.c
-===================================================================
---- head-2008-12-01.orig/drivers/xen/core/spinlock.c 2008-12-01 11:51:53.000000000 +0100
-+++ head-2008-12-01/drivers/xen/core/spinlock.c 2008-12-01 12:07:34.000000000 +0100
-@@ -14,8 +14,7 @@
+--- sle11-2009-06-04.orig/drivers/xen/core/spinlock.c 2009-06-04 10:36:24.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/spinlock.c 2009-06-04 10:47:21.000000000 +0200
+@@ -16,8 +16,7 @@
extern irqreturn_t smp_reschedule_interrupt(int, void *);
struct spinning {
raw_spinlock_t *lock;
-@@ -32,34 +31,37 @@ static DEFINE_PER_CPU(raw_rwlock_t, spin
+@@ -34,34 +33,36 @@ static DEFINE_PER_CPU(raw_rwlock_t, spin
int __cpuinit xen_spinlock_init(unsigned int cpu)
{
- if (per_cpu(spinlock_irq, cpu) >= 0)
- unbind_from_irqhandler(per_cpu(spinlock_irq, cpu), NULL);
- per_cpu(spinlock_irq, cpu) = -1;
-+ if (spinlock_irq >= 0)
-+ unbind_from_per_cpu_irq(spinlock_irq, cpu);
++ unbind_from_per_cpu_irq(spinlock_irq, cpu);
}
int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
raw_rwlock_t *rm_lock;
unsigned long flags;
struct spinning spinning;
-@@ -153,7 +155,7 @@ void xen_spin_kick(raw_spinlock_t *lock,
+@@ -155,7 +156,7 @@ void xen_spin_kick(raw_spinlock_t *lock,
raw_local_irq_restore(flags);
if (unlikely(spinning)) {
return;
}
}
-Index: head-2008-12-01/include/xen/evtchn.h
-===================================================================
---- head-2008-12-01.orig/include/xen/evtchn.h 2008-12-01 12:07:30.000000000 +0100
-+++ head-2008-12-01/include/xen/evtchn.h 2008-12-01 12:07:34.000000000 +0100
+--- sle11-2009-06-04.orig/include/xen/evtchn.h 2009-06-04 10:47:20.000000000 +0200
++++ sle11-2009-06-04/include/xen/evtchn.h 2009-06-04 10:47:21.000000000 +0200
@@ -78,6 +78,8 @@ int bind_virq_to_irqhandler(
unsigned long irqflags,
const char *devname,