Subject: fold per-CPU VIRQs onto a single IRQ each
Patch-mainline: obsolete
-Index: head-2008-12-01/arch/x86/kernel/time_32-xen.c
-===================================================================
---- head-2008-12-01.orig/arch/x86/kernel/time_32-xen.c 2008-12-01 12:07:30.000000000 +0100
-+++ head-2008-12-01/arch/x86/kernel/time_32-xen.c 2008-12-01 12:08:40.000000000 +0100
-@@ -729,19 +729,17 @@ int xen_update_persistent_clock(void)
+--- sle11-2009-06-04.orig/arch/x86/kernel/time_32-xen.c 2009-06-04 10:47:20.000000000 +0200
++++ sle11-2009-06-04/arch/x86/kernel/time_32-xen.c 2009-06-04 10:47:28.000000000 +0200
+@@ -725,19 +725,17 @@ int xen_update_persistent_clock(void)
}
/* Dynamically-mapped IRQ. */
}
void __init time_init(void)
-@@ -868,8 +866,6 @@ void xen_halt(void)
+@@ -864,8 +862,6 @@ void xen_halt(void)
EXPORT_SYMBOL(xen_halt);
#ifdef CONFIG_SMP
int __cpuinit local_setup_timer(unsigned int cpu)
{
int seq, irq;
-@@ -895,16 +891,10 @@ int __cpuinit local_setup_timer(unsigned
+@@ -891,16 +887,10 @@ int __cpuinit local_setup_timer(unsigned
init_missing_ticks_accounting(cpu);
} while (read_seqretry(&xtime_lock, seq));
return 0;
}
-@@ -912,7 +902,7 @@ int __cpuinit local_setup_timer(unsigned
+@@ -908,7 +898,7 @@ int __cpuinit local_setup_timer(unsigned
void __cpuinit local_teardown_timer(unsigned int cpu)
{
BUG_ON(cpu == 0);
}
#endif
-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:29.000000000 +0100
-+++ head-2008-12-01/drivers/xen/core/evtchn.c 2008-12-03 15:54:25.000000000 +0100
-@@ -57,6 +57,23 @@ static DEFINE_SPINLOCK(irq_mapping_updat
+--- sle11-2009-06-04.orig/drivers/xen/core/evtchn.c 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/evtchn.c 2009-06-04 10:47:28.000000000 +0200
+@@ -58,6 +58,23 @@ static DEFINE_SPINLOCK(irq_mapping_updat
static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
[0 ... NR_EVENT_CHANNELS-1] = -1 };
+} *virq_actions[NR_VIRQS];
+/* IRQ <-> VIRQ mapping. */
+static DECLARE_BITMAP(virq_per_cpu, NR_VIRQS) __read_mostly;
-+static DEFINE_PER_CPU(int[NR_VIRQS], virq_to_evtchn) = {[0 ... NR_VIRQS-1] = -1};
++static DEFINE_PER_CPU(int[NR_VIRQS], virq_to_evtchn);
+#define BUG_IF_VIRQ_PER_CPU(irq) \
+ BUG_ON(type_from_irq(irq) == IRQT_VIRQ \
+ && test_bit(index_from_irq(irq), virq_per_cpu))
/* IRQ <-> IPI mapping. */
#ifndef NR_IPIS
#define NR_IPIS 1
-@@ -113,13 +130,6 @@ static inline u32 mk_irq_info(u32 type,
+@@ -114,13 +131,6 @@ static inline u32 mk_irq_info(u32 type,
* Accessors for packed IRQ information.
*/
static inline unsigned int index_from_irq(int irq)
{
return (irq_info[irq] >> _EVTCHN_BITS) & ((1U << _INDEX_BITS) - 1);
-@@ -130,20 +140,34 @@ static inline unsigned int type_from_irq
+@@ -131,20 +141,35 @@ static inline unsigned int type_from_irq
return irq_info[irq] >> (32 - _IRQT_BITS);
}
+#endif
+ }
+ BUG();
++ return 0;
}
static inline unsigned int evtchn_from_irq(unsigned int irq)
/* IRQ <-> VIRQ mapping. */
DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
-@@ -463,6 +487,14 @@ static int bind_virq_to_irq(unsigned int
+@@ -479,6 +504,14 @@ static int bind_virq_to_irq(unsigned int
evtchn = bind_virq.port;
evtchn_to_irq[evtchn] = irq;
irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
per_cpu(virq_to_irq, cpu)[virq] = irq;
-@@ -517,7 +549,9 @@ static void unbind_from_irq(unsigned int
+@@ -533,7 +566,9 @@ 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)) {
-@@ -530,6 +564,11 @@ static void unbind_from_irq(unsigned int
+@@ -546,6 +581,11 @@ static void unbind_from_irq(unsigned int
case IRQT_VIRQ:
per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
[index_from_irq(irq)] = -1;
+#ifndef PER_CPU_VIRQ_IRQ
+ for_each_possible_cpu(cpu)
+ per_cpu(virq_to_evtchn, cpu)
-+ [index_from_irq(irq)] = -1;
++ [index_from_irq(irq)] = 0;
+#endif
break;
#if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
case IRQT_IPI:
-@@ -555,11 +594,13 @@ static void unbind_from_irq(unsigned int
+@@ -571,11 +611,13 @@ static void unbind_from_irq(unsigned int
spin_unlock(&irq_mapping_update_lock);
}
spin_lock(&irq_mapping_update_lock);
-@@ -570,6 +611,32 @@ void unbind_from_per_cpu_irq(unsigned in
+@@ -586,6 +628,32 @@ void unbind_from_per_cpu_irq(unsigned in
BUG_ON(irq_bindcount[irq] <= 1);
irq_bindcount[irq]--;
cpu_clear(cpu, desc->affinity);
close.port = evtchn;
-@@ -577,9 +644,16 @@ void unbind_from_per_cpu_irq(unsigned in
+@@ -593,9 +661,16 @@ void unbind_from_per_cpu_irq(unsigned in
BUG();
switch (type_from_irq(irq)) {
+#ifndef PER_CPU_VIRQ_IRQ
+ case IRQT_VIRQ:
-+ per_cpu(virq_to_evtchn, cpu)[index_from_irq(irq)] = -1;
++ per_cpu(virq_to_evtchn, cpu)[index_from_irq(irq)] = 0;
+ break;
+#endif
+#ifndef PER_CPU_IPI_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;
+#endif
default:
BUG();
break;
-@@ -591,9 +665,16 @@ void unbind_from_per_cpu_irq(unsigned in
+@@ -607,9 +682,16 @@ void unbind_from_per_cpu_irq(unsigned in
evtchn_to_irq[evtchn] = -1;
}
int bind_caller_port_to_irqhandler(
unsigned int caller_port,
-@@ -675,6 +756,8 @@ int bind_virq_to_irqhandler(
+@@ -691,6 +773,8 @@ int bind_virq_to_irqhandler(
{
int irq, retval;
irq = bind_virq_to_irq(virq, cpu);
if (irq < 0)
return irq;
-@@ -690,6 +773,108 @@ int bind_virq_to_irqhandler(
+@@ -706,6 +790,108 @@ int bind_virq_to_irqhandler(
EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
#ifdef CONFIG_SMP
+
+ BUG_ON(!retval);
+
-+ if ((irq = find_unbound_irq()) < 0) {
++ if ((irq = find_unbound_irq(true)) < 0) {
+ if (cur)
+ virq_actions[virq] = cur->next;
+ spin_unlock(&irq_mapping_update_lock);
+ for_each_possible_cpu(cpu)
+ per_cpu(virq_to_irq, cpu)[virq] = irq;
+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, 0);
-+ irq_desc[irq].handle_irq = handle_percpu_irq;
+ }
+
-+ if ((evtchn = per_cpu(virq_to_evtchn, cpu)[virq]) == -1) {
++ evtchn = per_cpu(virq_to_evtchn, cpu)[virq];
++ if (!VALID_EVTCHN(evtchn)) {
+ bind_virq.virq = virq;
+ bind_virq.vcpu = cpu;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
#ifdef PER_CPU_IPI_IRQ
int bind_ipi_to_irqhandler(
unsigned int ipi,
-@@ -769,7 +954,7 @@ int __cpuinit bind_ipi_to_irqaction(
+@@ -784,7 +970,7 @@ int __cpuinit bind_ipi_to_irqaction(
action->flags |= IRQF_PERCPU;
retval = setup_irq(irq, action);
if (retval) {
BUG_ON(retval > 0);
irq = retval;
}
-@@ -804,7 +989,9 @@ static void rebind_irq_to_cpu(unsigned i
+@@ -819,7 +1005,9 @@ static void rebind_irq_to_cpu(unsigned i
{
int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
rebind_evtchn_to_cpu(evtchn, tcpu);
}
-@@ -1075,7 +1262,9 @@ void notify_remote_via_irq(int irq)
+@@ -1098,7 +1286,9 @@ void notify_remote_via_irq(int irq)
{
int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
notify_remote_via_evtchn(evtchn);
}
-@@ -1083,6 +1272,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
+@@ -1106,6 +1296,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
int irq_to_evtchn_port(int irq)
{
BUG_IF_IPI(irq);
return evtchn_from_irq(irq);
}
-@@ -1177,6 +1367,20 @@ static void restore_cpu_virqs(unsigned i
+@@ -1200,6 +1391,12 @@ static void restore_cpu_virqs(unsigned i
if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
continue;
+#ifndef PER_CPU_VIRQ_IRQ
-+ if (test_bit(virq, virq_per_cpu)) {
-+ const struct per_cpu_irqaction *cur;
-+
-+ if(cpu != smp_processor_id())
-+ continue;
-+ for (cur = virq_actions[virq]; cur; cur = cur->next)
-+ if (cpu_isset(cpu, cur->cpus))
-+ break;
-+ if (!cur)
-+ continue;
-+ }
++ if (test_bit(virq, virq_per_cpu)
++ && !VALID_EVTCHN(per_cpu(virq_to_evtchn, cpu)[virq]))
++ continue;
+#endif
+
BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
/* Get a new binding from Xen. */
-@@ -1189,7 +1393,19 @@ static void restore_cpu_virqs(unsigned i
+@@ -1212,7 +1409,19 @@ static void restore_cpu_virqs(unsigned i
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
-+#ifndef PER_CPU_VIRQ_IRQ
++#ifdef PER_CPU_VIRQ_IRQ
+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
++#else
+ if (test_bit(virq, virq_per_cpu))
+ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
+ else {
+ for_each_possible_cpu(cpu)
+ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
+ }
-+#else
- irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
+#endif
bind_evtchn_to_cpu(evtchn, cpu);
/* Ready for use. */
-@@ -1242,7 +1458,11 @@ static int evtchn_resume(struct sys_devi
+@@ -1267,7 +1476,11 @@ static int evtchn_resume(struct sys_devi
/* Avoid doing anything in the 'suspend cancelled' case. */
status.dom = DOMID_SELF;
if (HYPERVISOR_event_channel_op(EVTCHNOP_status, &status))
BUG();
if (status.status == EVTCHNSTAT_virq
-@@ -1391,6 +1611,15 @@ void __init xen_init_IRQ(void)
+@@ -1407,6 +1620,15 @@ void __init xen_init_IRQ(void)
unsigned int i;
- struct physdev_pirq_eoi_mfn eoi_mfn;
+ struct physdev_pirq_eoi_gmfn eoi_gmfn;
+#ifndef PER_CPU_VIRQ_IRQ
+ __set_bit(VIRQ_TIMER, virq_per_cpu);
+
init_evtchn_cpu_bindings();
- BUG_ON(!bitmap_empty(pirq_needs_eoi, PAGE_SIZE * 8));
-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:34.000000000 +0100
-+++ head-2008-12-01/drivers/xen/core/smpboot.c 2008-12-01 12:08:40.000000000 +0100
-@@ -170,11 +170,11 @@ static int __cpuinit xen_smp_intr_init(u
-
+ pirq_needs_eoi = alloc_bootmem_pages(sizeof(unsigned long)
+--- sle11-2009-06-04.orig/drivers/xen/core/smpboot.c 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/smpboot.c 2009-06-04 10:47:28.000000000 +0200
+@@ -163,11 +163,11 @@ static int __cpuinit xen_smp_intr_init(u
fail:
- if (resched_irq >= 0)
-- unbind_from_per_cpu_irq(resched_irq, cpu);
-+ unbind_from_per_cpu_irq(resched_irq, cpu, NULL);
- if (callfunc_irq >= 0)
-- unbind_from_per_cpu_irq(callfunc_irq, cpu);
-+ unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL);
- if (call1func_irq >= 0)
-- unbind_from_per_cpu_irq(call1func_irq, cpu);
-+ unbind_from_per_cpu_irq(call1func_irq, cpu, NULL);
xen_spinlock_cleanup(cpu);
+ unbind_call1:
+- unbind_from_per_cpu_irq(call1func_irq, cpu);
++ unbind_from_per_cpu_irq(call1func_irq, cpu, NULL);
+ unbind_call:
+- unbind_from_per_cpu_irq(callfunc_irq, cpu);
++ unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL);
+ unbind_resched:
+- unbind_from_per_cpu_irq(resched_irq, cpu);
++ unbind_from_per_cpu_irq(resched_irq, cpu, NULL);
return rc;
}
-@@ -185,9 +185,9 @@ static void __cpuinit xen_smp_intr_exit(
+
+@@ -177,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 12:07:34.000000000 +0100
-+++ head-2008-12-01/drivers/xen/core/spinlock.c 2008-12-01 12:08:40.000000000 +0100
-@@ -56,7 +56,7 @@ int __cpuinit xen_spinlock_init(unsigned
+--- sle11-2009-06-04.orig/drivers/xen/core/spinlock.c 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/spinlock.c 2009-06-04 10:47:28.000000000 +0200
+@@ -57,7 +57,7 @@ int __cpuinit xen_spinlock_init(unsigned
+
void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
{
- if (spinlock_irq >= 0)
-- unbind_from_per_cpu_irq(spinlock_irq, cpu);
-+ unbind_from_per_cpu_irq(spinlock_irq, cpu, NULL);
+- unbind_from_per_cpu_irq(spinlock_irq, cpu);
++ unbind_from_per_cpu_irq(spinlock_irq, cpu, NULL);
}
int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
-Index: head-2008-12-01/drivers/xen/netback/netback.c
-===================================================================
---- head-2008-12-01.orig/drivers/xen/netback/netback.c 2008-12-01 11:36:55.000000000 +0100
-+++ head-2008-12-01/drivers/xen/netback/netback.c 2008-12-01 12:08:40.000000000 +0100
-@@ -1543,6 +1543,12 @@ static irqreturn_t netif_be_dbg(int irq,
+--- sle11-2009-06-04.orig/drivers/xen/netback/netback.c 2009-06-04 10:20:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/netback/netback.c 2009-06-04 10:47:28.000000000 +0200
+@@ -1561,6 +1561,12 @@ static irqreturn_t netif_be_dbg(int irq,
return IRQ_HANDLED;
}
#endif
static int __init netback_init(void)
-@@ -1602,12 +1608,9 @@ static int __init netback_init(void)
+@@ -1620,12 +1626,9 @@ static int __init netback_init(void)
netif_xenbus_init();
#ifdef NETBE_DEBUG_INTERRUPT
#endif
return 0;
-Index: head-2008-12-01/drivers/xen/xenoprof/xenoprofile.c
-===================================================================
---- head-2008-12-01.orig/drivers/xen/xenoprof/xenoprofile.c 2008-12-01 11:37:10.000000000 +0100
-+++ head-2008-12-01/drivers/xen/xenoprof/xenoprofile.c 2008-12-01 12:08:40.000000000 +0100
-@@ -212,6 +212,11 @@ static irqreturn_t xenoprof_ovf_interrup
+--- sle11-2009-06-04.orig/drivers/xen/xenoprof/xenoprofile.c 2009-06-04 10:20:39.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/xenoprof/xenoprofile.c 2009-06-04 10:47:28.000000000 +0200
+@@ -210,6 +210,11 @@ static irqreturn_t xenoprof_ovf_interrup
return IRQ_HANDLED;
}
static void unbind_virq(void)
{
-@@ -219,7 +224,7 @@ static void unbind_virq(void)
+@@ -217,7 +222,7 @@ static void unbind_virq(void)
for_each_online_cpu(i) {
if (ovf_irq[i] >= 0) {
ovf_irq[i] = -1;
}
}
-@@ -232,12 +237,7 @@ static int bind_virq(void)
+@@ -230,12 +235,7 @@ static int bind_virq(void)
int result;
for_each_online_cpu(i) {
if (result < 0) {
unbind_virq();
-Index: head-2008-12-01/include/xen/evtchn.h
-===================================================================
---- head-2008-12-01.orig/include/xen/evtchn.h 2008-12-01 12:07:34.000000000 +0100
-+++ head-2008-12-01/include/xen/evtchn.h 2008-12-01 12:08:40.000000000 +0100
+--- sle11-2009-06-04.orig/include/xen/evtchn.h 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/include/xen/evtchn.h 2009-06-04 10:47:28.000000000 +0200
@@ -78,6 +78,17 @@ int bind_virq_to_irqhandler(
unsigned long irqflags,
const char *devname,