[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Rationalise the kernel event-channel binding interfaces. The



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 0915074c356e37017562298ded188c5c354ed463
# Parent  37ad91483bd3dc65475bbe35c15f7c547c3cacea
Rationalise the kernel event-channel binding interfaces. The
new interfaces are simpler and should be implementable by any
architecture.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c  Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c  Tue Nov  8 
14:58:31 2005
@@ -30,12 +30,6 @@
     return op.u.bind_virq.port;
 }
 
-int bind_virq_to_irq(int virq, int cpu)
-{
-       printk("bind_virq_to_irq called... FIXME??\n");
-       while(1);
-}
-
 #if 0
 void notify_remote_via_irq(int virq)
 {
@@ -43,19 +37,6 @@
        while(1);
 }
 #endif
-
-void unbind_virq_from_evtchn(int virq)
-{
-    evtchn_op_t op;
-
-    op.cmd = EVTCHNOP_close;
-//    op.u.close.dom = DOMID_SELF;
-    op.u.close.port = virq_to_evtchn[virq];
-    if ( HYPERVISOR_event_channel_op(&op) != 0 )
-       BUG();
-
-    virq_to_evtchn[virq] = -1;
-}
 
 int bind_evtchn_to_irqhandler(unsigned int evtchn,
                    irqreturn_t (*handler)(int, void *, struct pt_regs *),
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c   Tue Nov  8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c   Tue Nov  8 14:58:31 2005
@@ -127,13 +127,13 @@
        return SET_APIC_DEST_FIELD(mask);
 }
 
-DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
 
 static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
-       int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
-       BUG_ON(evtchn < 0);
-       notify_remote_via_evtchn(evtchn);
+       int irq = per_cpu(ipi_to_irq, cpu)[vector];
+       BUG_ON(irq < 0);
+       notify_remote_via_irq(irq);
 }
 
 void __send_IPI_shortcut(unsigned int shortcut, int vector)
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Tue Nov  8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c  Tue Nov  8 14:58:31 2005
@@ -748,10 +748,19 @@
 /* Dynamically-mapped IRQ. */
 DEFINE_PER_CPU(int, timer_irq);
 
-static struct irqaction irq_timer = {
-       timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer0",
-       NULL, NULL
-};
+extern void (*late_time_init)(void);
+static void setup_cpu0_timer_irq(void)
+{
+       per_cpu(timer_irq, 0) =
+               bind_virq_to_irqhandler(
+                       VIRQ_TIMER,
+                       0,
+                       timer_interrupt,
+                       SA_INTERRUPT,
+                       "timer0",
+                       NULL);
+       BUG_ON(per_cpu(timer_irq, 0) < 0);
+}
 
 void __init time_init(void)
 {
@@ -785,8 +794,8 @@
        rdtscll(vxtime.last_tsc);
 #endif
 
-       per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER, 0);
-       (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
+       /* Cannot request_irq() until kmem is initialised. */
+       late_time_init = setup_cpu0_timer_irq;
 }
 
 /* Convert jiffies to system time. */
@@ -865,17 +874,22 @@
                        per_cpu(shadow_time, cpu).system_timestamp;
        } while (read_seqretry(&xtime_lock, seq));
 
-       per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER, cpu);
        sprintf(timer_name[cpu], "timer%d", cpu);
-       BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt,
-                          SA_INTERRUPT, timer_name[cpu], NULL));
+       per_cpu(timer_irq, cpu) =
+               bind_virq_to_irqhandler(
+                       VIRQ_TIMER,
+                       cpu,
+                       timer_interrupt,
+                       SA_INTERRUPT,
+                       timer_name[cpu],
+                       NULL);
+       BUG_ON(per_cpu(timer_irq, cpu) < 0);
 }
 
 void local_teardown_timer(unsigned int cpu)
 {
        BUG_ON(cpu == 0);
-       free_irq(per_cpu(timer_irq, cpu), NULL);
-       unbind_virq_from_irq(VIRQ_TIMER, cpu);
+       unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
 }
 #endif
 
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Nov  8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c     Tue Nov  8 14:58:31 2005
@@ -52,16 +52,29 @@
 
 /* IRQ <-> event-channel mappings. */
 static int evtchn_to_irq[NR_EVENT_CHANNELS];
-static int irq_to_evtchn[NR_IRQS];
+
+/* Packed IRQ information: binding type, sub-type index, and event channel. */
+static u32 irq_info[NR_IRQS];
+/* Binding types. */
+enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
+/* Constructor for packed IRQ information. */
+#define mk_irq_info(type, index, evtchn)                               \
+       (((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
+/* Convenient shorthand for packed representation of an unbound IRQ. */
+#define IRQ_UNBOUND    mk_irq_info(IRQT_UNBOUND, 0, 0)
+/* Accessor macros for packed IRQ information. */
+#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
+#define index_from_irq(irq)  ((u8)(irq_info[irq] >> 16))
+#define type_from_irq(irq)   ((u8)(irq_info[irq] >> 24))
 
 /* IRQ <-> VIRQ mapping. */
 DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]);
 
-/* evtchn <-> IPI mapping. */
+/* IRQ <-> IPI mapping. */
 #ifndef NR_IPIS
 #define NR_IPIS 1 
 #endif
-DEFINE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
 
 /* Reference counts for bindings to IRQs. */
 static int irq_bindcount[NR_IRQS];
@@ -92,6 +105,8 @@
        memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
        memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
 }
+
+#define cpu_from_evtchn(evtchn)                (cpu_evtchn[evtchn])
 
 #else
 
@@ -100,6 +115,7 @@
         ~(sh)->evtchn_mask[idx])
 #define bind_evtchn_to_cpu(chn,cpu)    ((void)0)
 #define init_evtchn_cpu_bindings()     ((void)0)
+#define cpu_from_evtchn(evtchn)                (0)
 
 #endif
 
@@ -121,7 +137,8 @@
 } while (0)
 #endif
 
-#define VALID_EVTCHN(_chn) ((_chn) >= 0)
+/* Xen will never allocate port zero for any purpose. */
+#define VALID_EVTCHN(chn)      ((chn) != 0)
 
 /*
  * Force a proper event-channel callback from Xen after clearing the
@@ -179,7 +196,26 @@
        return irq;
 }
 
-int bind_virq_to_irq(int virq, int cpu)
+static int bind_evtchn_to_irq(unsigned int evtchn)
+{
+       int irq;
+
+       spin_lock(&irq_mapping_update_lock);
+
+       if ((irq = evtchn_to_irq[evtchn]) == -1) {
+               irq = find_unbound_irq();
+               evtchn_to_irq[evtchn] = irq;
+               irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
+       }
+
+       irq_bindcount[irq]++;
+
+       spin_unlock(&irq_mapping_update_lock);
+    
+       return irq;
+}
+
+static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
 {
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
        int evtchn, irq;
@@ -194,7 +230,7 @@
 
                irq = find_unbound_irq();
                evtchn_to_irq[evtchn] = irq;
-               irq_to_evtchn[irq]    = evtchn;
+               irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
 
                per_cpu(virq_to_irq, cpu)[virq] = irq;
 
@@ -207,59 +243,26 @@
     
        return irq;
 }
-EXPORT_SYMBOL(bind_virq_to_irq);
-
-void unbind_virq_from_irq(int virq, int cpu)
-{
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
-       int irq    = per_cpu(virq_to_irq, cpu)[virq];
-       int evtchn = irq_to_evtchn[irq];
-
-       spin_lock(&irq_mapping_update_lock);
-
-       if (--irq_bindcount[irq] == 0) {
-               op.u.close.port = evtchn;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-
-               /*
-                * This is a slight hack. Interdomain ports can be allocated 
-                * directly by userspace, and at that point they get bound by 
-                * Xen to vcpu 0. We therefore need to make sure that if we get
-                * an event on an event channel we don't know about vcpu 0 
-                * handles it. Binding channels to vcpu 0 when closing them
-                * achieves this.
-                */
-               bind_evtchn_to_cpu(evtchn, 0);
-               evtchn_to_irq[evtchn] = -1;
-               irq_to_evtchn[irq]    = -1;
-               per_cpu(virq_to_irq, cpu)[virq] = -1;
-       }
-
-       spin_unlock(&irq_mapping_update_lock);
-}
-EXPORT_SYMBOL(unbind_virq_from_irq);
-
-int bind_ipi_to_irq(int ipi, int cpu)
+
+static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
 {
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
        int evtchn, irq;
 
        spin_lock(&irq_mapping_update_lock);
 
-       if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
+       if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
                op.u.bind_ipi.vcpu = cpu;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_ipi.port;
 
                irq = find_unbound_irq();
                evtchn_to_irq[evtchn] = irq;
-               irq_to_evtchn[irq]    = evtchn;
-
-               per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
+               irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
+
+               per_cpu(ipi_to_irq, cpu)[ipi] = irq;
 
                bind_evtchn_to_cpu(evtchn, cpu);
-       } else {
-               irq = evtchn_to_irq[evtchn];
        }
 
        irq_bindcount[irq]++;
@@ -268,63 +271,36 @@
 
        return irq;
 }
-EXPORT_SYMBOL(bind_ipi_to_irq);
-
-void unbind_ipi_from_irq(int ipi, int cpu)
+
+static void unbind_from_irq(unsigned int irq)
 {
        evtchn_op_t op = { .cmd = EVTCHNOP_close };
-       int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
-       int irq    = evtchn_to_irq[evtchn];
+       int evtchn = evtchn_from_irq(irq);
 
        spin_lock(&irq_mapping_update_lock);
 
-       if (--irq_bindcount[irq] == 0) {
+       if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
                op.u.close.port = evtchn;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
 
-               /* See comments in unbind_virq_from_irq */
+               switch (type_from_irq(irq)) {
+               case IRQT_VIRQ:
+                       per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
+                               [index_from_irq(irq)] = -1;
+                       break;
+               case IRQT_IPI:
+                       per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
+                               [index_from_irq(irq)] = -1;
+                       break;
+               default:
+                       break;
+               }
+
+               /* Closed ports are implicitly re-bound to VCPU0. */
                bind_evtchn_to_cpu(evtchn, 0);
+
                evtchn_to_irq[evtchn] = -1;
-               irq_to_evtchn[irq]    = -1;
-               per_cpu(ipi_to_evtchn, cpu)[ipi] = -1;
-       }
-
-       spin_unlock(&irq_mapping_update_lock);
-}
-EXPORT_SYMBOL(unbind_ipi_from_irq);
-
-static int bind_evtchn_to_irq(unsigned int evtchn)
-{
-       int irq;
-
-       spin_lock(&irq_mapping_update_lock);
-
-       if ((irq = evtchn_to_irq[evtchn]) == -1) {
-               irq = find_unbound_irq();
-               evtchn_to_irq[evtchn] = irq;
-               irq_to_evtchn[irq]    = evtchn;
-       }
-
-       irq_bindcount[irq]++;
-
-       spin_unlock(&irq_mapping_update_lock);
-    
-       return irq;
-}
-
-static void unbind_evtchn_from_irq(unsigned int irq)
-{
-       evtchn_op_t op = { .cmd = EVTCHNOP_close };
-       int evtchn = irq_to_evtchn[irq];
-
-       spin_lock(&irq_mapping_update_lock);
-
-       if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
-               op.u.close.port = evtchn;
-               BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-
-               evtchn_to_irq[evtchn] = -1;
-               irq_to_evtchn[irq]    = -1;
+               irq_info[irq] = IRQ_UNBOUND;
        }
 
        spin_unlock(&irq_mapping_update_lock);
@@ -343,7 +319,7 @@
        irq = bind_evtchn_to_irq(evtchn);
        retval = request_irq(irq, handler, irqflags, devname, dev_id);
        if (retval != 0) {
-               unbind_evtchn_from_irq(irq);
+               unbind_from_irq(irq);
                return retval;
        }
 
@@ -351,12 +327,56 @@
 }
 EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
 
-void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
+int bind_virq_to_irqhandler(
+       unsigned int virq,
+       unsigned int cpu,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id)
+{
+       unsigned int irq;
+       int retval;
+
+       irq = bind_virq_to_irq(virq, cpu);
+       retval = request_irq(irq, handler, irqflags, devname, dev_id);
+       if (retval != 0) {
+               unbind_from_irq(irq);
+               return retval;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL(bind_virq_to_irqhandler);
+
+int bind_ipi_to_irqhandler(
+       unsigned int ipi,
+       unsigned int cpu,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id)
+{
+       unsigned int irq;
+       int retval;
+
+       irq = bind_ipi_to_irq(ipi, cpu);
+       retval = request_irq(irq, handler, irqflags, devname, dev_id);
+       if (retval != 0) {
+               unbind_from_irq(irq);
+               return retval;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL(bind_ipi_to_irqhandler);
+
+void unbind_from_irqhandler(unsigned int irq, void *dev_id)
 {
        free_irq(irq, dev_id);
-       unbind_evtchn_from_irq(irq);
-}
-EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
+       unbind_from_irq(irq);
+}
+EXPORT_SYMBOL(unbind_from_irqhandler);
 
 #ifdef CONFIG_SMP
 static void do_nothing_function(void *ign)
@@ -371,7 +391,8 @@
        int evtchn;
 
        spin_lock(&irq_mapping_update_lock);
-       evtchn = irq_to_evtchn[irq];
+
+       evtchn = evtchn_from_irq(irq);
        if (!VALID_EVTCHN(evtchn)) {
                spin_unlock(&irq_mapping_update_lock);
                return;
@@ -418,7 +439,7 @@
 
 static unsigned int startup_dynirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                unmask_evtchn(evtchn);
@@ -427,7 +448,7 @@
 
 static void shutdown_dynirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                mask_evtchn(evtchn);
@@ -435,7 +456,7 @@
 
 static void enable_dynirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                unmask_evtchn(evtchn);
@@ -443,7 +464,7 @@
 
 static void disable_dynirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                mask_evtchn(evtchn);
@@ -451,7 +472,7 @@
 
 static void ack_dynirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn)) {
                mask_evtchn(evtchn);
@@ -461,7 +482,7 @@
 
 static void end_dynirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
                unmask_evtchn(evtchn);
@@ -507,7 +528,7 @@
 static unsigned int startup_pirq(unsigned int irq)
 {
        evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                goto out;
@@ -527,7 +548,7 @@
 
        bind_evtchn_to_cpu(evtchn, 0);
        evtchn_to_irq[evtchn] = irq;
-       irq_to_evtchn[irq]    = evtchn;
+       irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);
 
  out:
        unmask_evtchn(evtchn);
@@ -539,7 +560,7 @@
 static void shutdown_pirq(unsigned int irq)
 {
        evtchn_op_t op = { .cmd = EVTCHNOP_close };
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (!VALID_EVTCHN(evtchn))
                return;
@@ -551,12 +572,12 @@
 
        bind_evtchn_to_cpu(evtchn, 0);
        evtchn_to_irq[evtchn] = -1;
-       irq_to_evtchn[irq]    = -1;
+       irq_info[irq] = IRQ_UNBOUND;
 }
 
 static void enable_pirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn)) {
                unmask_evtchn(evtchn);
@@ -566,7 +587,7 @@
 
 static void disable_pirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                mask_evtchn(evtchn);
@@ -574,7 +595,7 @@
 
 static void ack_pirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn)) {
                mask_evtchn(evtchn);
@@ -584,7 +605,7 @@
 
 static void end_pirq(unsigned int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
                unmask_evtchn(evtchn);
@@ -605,7 +626,7 @@
 
 void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
 {
-       int evtchn = irq_to_evtchn[i];
+       int evtchn = evtchn_from_irq(i);
        shared_info_t *s = HYPERVISOR_shared_info;
        if (!VALID_EVTCHN(evtchn))
                return;
@@ -615,7 +636,7 @@
 
 void notify_remote_via_irq(int irq)
 {
-       int evtchn = irq_to_evtchn[irq];
+       int evtchn = evtchn_from_irq(irq);
 
        if (VALID_EVTCHN(evtchn))
                notify_remote_via_evtchn(evtchn);
@@ -635,24 +656,28 @@
 
        /* Check that no PIRQs are still bound. */
        for (pirq = 0; pirq < NR_PIRQS; pirq++)
-               BUG_ON(irq_to_evtchn[pirq_to_irq(pirq)] != -1);
+               BUG_ON(irq_info[pirq_to_irq(pirq)] != IRQ_UNBOUND);
 
        /* Secondary CPUs must have no VIRQ or IPI bindings. */
        for (cpu = 1; cpu < NR_CPUS; cpu++) {
                for (virq = 0; virq < NR_VIRQS; virq++)
                        BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
                for (ipi = 0; ipi < NR_IPIS; ipi++)
-                       BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
-       }
-
-       /* No IRQ -> event-channel mappings. */
+                       BUG_ON(per_cpu(ipi_to_irq, cpu)[ipi] != -1);
+       }
+
+       /* No IRQ <-> event-channel mappings. */
        for (irq = 0; irq < NR_IRQS; irq++)
-               irq_to_evtchn[irq] = -1;
+               irq_info[irq] &= ~0xFFFF; /* zap event-channel binding */
+       for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
+               evtchn_to_irq[evtchn] = -1;
 
        /* Primary CPU: rebind VIRQs automatically. */
        for (virq = 0; virq < NR_VIRQS; virq++) {
                if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
                        continue;
+
+               BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
 
                /* Get a new binding from Xen. */
                memset(&op, 0, sizeof(op));
@@ -664,7 +689,7 @@
         
                /* Record the new mapping. */
                evtchn_to_irq[evtchn] = irq;
-               irq_to_evtchn[irq]    = evtchn;
+               irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
 
                /* Ready for use. */
                unmask_evtchn(evtchn);
@@ -672,11 +697,10 @@
 
        /* Primary CPU: rebind IPIs automatically. */
        for (ipi = 0; ipi < NR_IPIS; ipi++) {
-               if ((evtchn = per_cpu(ipi_to_evtchn, 0)[ipi]) == -1)
+               if ((irq = per_cpu(ipi_to_irq, 0)[ipi]) == -1)
                        continue;
 
-               irq = evtchn_to_irq[evtchn];
-               evtchn_to_irq[evtchn] = -1;
+               BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
 
                /* Get a new binding from Xen. */
                memset(&op, 0, sizeof(op));
@@ -687,17 +711,10 @@
         
                /* Record the new mapping. */
                evtchn_to_irq[evtchn] = irq;
-               irq_to_evtchn[irq]    = evtchn;
+               irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
 
                /* Ready for use. */
                unmask_evtchn(evtchn);
-       }
-
-       /* Remove defunct event-channel -> IRQ mappings. */
-       for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
-               if ((evtchn_to_irq[evtchn] != -1) &&
-                   (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
-                       evtchn_to_irq[evtchn] = -1;
        }
 }
 
@@ -717,7 +734,7 @@
                for (i = 0; i < NR_VIRQS; i++)
                        per_cpu(virq_to_irq, cpu)[i] = -1;
                for (i = 0; i < NR_IPIS; i++)
-                       per_cpu(ipi_to_evtchn, cpu)[i] = -1;
+                       per_cpu(ipi_to_irq, cpu)[i] = -1;
        }
 
        /* No event-channel -> IRQ mappings. */
@@ -728,7 +745,7 @@
 
        /* No IRQ -> event-channel mappings. */
        for (i = 0; i < NR_IRQS; i++)
-               irq_to_evtchn[i] = -1;
+               irq_info[i] = IRQ_UNBOUND;
 
        /* Dynamic IRQ space is currently unbound. Zero the refcnts. */
        for (i = 0; i < NR_DYNIRQS; i++) {
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c    Tue Nov  8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c    Tue Nov  8 14:58:31 2005
@@ -87,18 +87,27 @@
 
 static void xen_smp_intr_init(unsigned int cpu)
 {
+       sprintf(resched_name[cpu], "resched%d", cpu);
        per_cpu(resched_irq, cpu) =
-               bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu);
-       sprintf(resched_name[cpu], "resched%d", cpu);
-       BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
-                          SA_INTERRUPT, resched_name[cpu], NULL));
-
+               bind_ipi_to_irqhandler(
+                       RESCHEDULE_VECTOR,
+                       cpu,
+                       smp_reschedule_interrupt,
+                       SA_INTERRUPT,
+                       resched_name[cpu],
+                       NULL);
+       BUG_ON(per_cpu(resched_irq, cpu) < 0);
+
+       sprintf(callfunc_name[cpu], "callfunc%d", cpu);
        per_cpu(callfunc_irq, cpu) =
-               bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu);
-       sprintf(callfunc_name[cpu], "callfunc%d", cpu);
-       BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
-                          smp_call_function_interrupt,
-                          SA_INTERRUPT, callfunc_name[cpu], NULL));
+               bind_ipi_to_irqhandler(
+                       CALL_FUNCTION_VECTOR,
+                       cpu,
+                       smp_call_function_interrupt,
+                       SA_INTERRUPT,
+                       callfunc_name[cpu],
+                       NULL);
+       BUG_ON(per_cpu(callfunc_irq, cpu) < 0);
 
        if (cpu != 0)
                local_setup_timer(cpu);
@@ -110,11 +119,8 @@
        if (cpu != 0)
                local_teardown_timer(cpu);
 
-       free_irq(per_cpu(resched_irq, cpu), NULL);
-       unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu);
-
-       free_irq(per_cpu(callfunc_irq, cpu), NULL);
-       unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu);
+       unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
+       unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
 }
 #endif
 
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Tue Nov  8 
14:58:31 2005
@@ -27,13 +27,13 @@
 #endif
 #include <asm-xen/evtchn.h>
 
-DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
 
 static inline void __send_IPI_one(unsigned int cpu, int vector)
 {
-       int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
-       BUG_ON(evtchn < 0);
-       notify_remote_via_evtchn(evtchn);
+       int irq = per_cpu(ipi_to_irq, cpu)[vector];
+       BUG_ON(irq < 0);
+       notify_remote_via_irq(irq);
 }
 
 void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int 
dest)
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c      Tue Nov  8 
14:58:31 2005
@@ -119,7 +119,7 @@
        if (!blkif->irq)
                return;
 
-       unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+       unbind_from_irqhandler(blkif->irq, blkif);
        blkif->irq = 0;
 
        vbd_free(&blkif->vbd);
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c      Tue Nov  8 
14:58:31 2005
@@ -358,7 +358,7 @@
                info->ring.sring = NULL;
        }
        if (info->irq)
-               unbind_evtchn_from_irqhandler(info->irq, info); 
+               unbind_from_irqhandler(info->irq, info); 
        info->evtchn = info->irq = 0;
 }
 
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c       Tue Nov  8 
14:58:31 2005
@@ -113,7 +113,7 @@
        blkif_t *blkif = (blkif_t *)arg;
 
        if (blkif->irq)
-               unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+               unbind_from_irqhandler(blkif->irq, blkif);
 
        if (blkif->blk_ring.sring) {
                unmap_frontend_page(blkif);
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c        Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c        Tue Nov  8 
14:58:31 2005
@@ -771,15 +771,14 @@
 #endif
 
        if (xen_start_info->flags & SIF_INITDOMAIN) {
-#ifdef __ia64__
-               xencons_priv_irq = bind_virq_to_evtchn(VIRQ_CONSOLE);
-               bind_evtchn_to_irqhandler(xencons_priv_irq,
-                               xencons_priv_interrupt, 0, "console", NULL);
-#else
-               xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
-               (void)request_irq(xencons_priv_irq,
-                                 xencons_priv_interrupt, 0, "console", NULL);
-#endif
+               xencons_priv_irq = bind_virq_to_irqhandler(
+                       VIRQ_CONSOLE,
+                       0,
+                       xencons_priv_interrupt,
+                       0,
+                       "console",
+                       NULL);
+               BUG_ON(xencons_priv_irq < 0);
        } else {
                xencons_ring_register_receiver(xencons_rx);
        }
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c   Tue Nov  8 
14:58:31 2005
@@ -86,7 +86,7 @@
        int err;
 
        if (xencons_irq)
-               unbind_evtchn_from_irqhandler(xencons_irq, NULL);
+               unbind_from_irqhandler(xencons_irq, NULL);
        xencons_irq = 0;
 
        if (!xen_start_info->console_evtchn)
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c      Tue Nov  8 
14:58:31 2005
@@ -241,7 +241,7 @@
        if (!netif->irq)
                return;
 
-       unbind_evtchn_from_irqhandler(netif->irq, netif);
+       unbind_from_irqhandler(netif->irq, netif);
        netif->irq = 0;
 
        unregister_netdev(netif->dev);
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Tue Nov  8 
14:58:31 2005
@@ -822,9 +822,13 @@
 
        netif_xenbus_init();
 
-       (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG, 0),
-                         netif_be_dbg, SA_SHIRQ, 
-                         "net-be-dbg", &netif_be_dbg);
+       (void)bind_virq_to_irqhandler(
+               VIRQ_DEBUG,
+               0,
+               netif_be_dbg,
+               SA_SHIRQ, 
+               "net-be-dbg",
+               &netif_be_dbg);
 
        return 0;
 }
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Nov  8 
14:58:31 2005
@@ -1049,7 +1049,7 @@
        info->rx = NULL;
 
        if (info->irq)
-               unbind_evtchn_from_irqhandler(info->irq, info->netdev);
+               unbind_from_irqhandler(info->irq, info->netdev);
        info->evtchn = info->irq = 0;
 }
 
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c      Tue Nov  8 
14:58:31 2005
@@ -162,7 +162,7 @@
        tpmif_t *tpmif = (tpmif_t *) arg;
 
        if (tpmif->irq)
-               unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
+               unbind_from_irqhandler(tpmif->irq, tpmif);
 
        if (tpmif->tx) {
                unmap_frontend_page(tpmif);
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c      Tue Nov  8 
14:58:31 2005
@@ -300,7 +300,7 @@
        }
 
        if (tp->irq)
-               unbind_evtchn_from_irqhandler(tp->irq, NULL);
+               unbind_from_irqhandler(tp->irq, NULL);
        tp->evtchn = tp->irq = 0;
 }
 
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Tue Nov  8 
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c    Tue Nov  8 
14:58:31 2005
@@ -177,7 +177,7 @@
        int err;
 
        if (xenbus_irq)
-               unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
+               unbind_from_irqhandler(xenbus_irq, &xb_waitq);
 
        err = bind_evtchn_to_irqhandler(
                xen_start_info->store_evtchn, wake_waiting,
diff -r 37ad91483bd3 -r 0915074c356e 
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Tue Nov  8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h     Tue Nov  8 14:58:31 2005
@@ -43,29 +43,41 @@
  * LOW-LEVEL DEFINITIONS
  */
 
-/* Dynamically bind a VIRQ source to Linux IRQ space. */
-extern int  bind_virq_to_irq(int virq, int cpu);
-extern void unbind_virq_from_irq(int virq, int cpu);
-
-/* Dynamically bind an IPI source to Linux IRQ space. */
-extern int  bind_ipi_to_irq(int ipi, int cpu);
-extern void unbind_ipi_from_irq(int ipi, int cpu);
-
 /*
- * Dynamically bind an event-channel port to an IRQ-like callback handler.
+ * Dynamically bind an event source to an IRQ-like callback handler.
  * On some platforms this may not be implemented via the Linux IRQ subsystem.
  * The IRQ argument passed to the callback handler is the same as returned
  * from the bind call. It may not correspond to a Linux IRQ number.
- * BIND:   Returns IRQ or error.
+ * Returns IRQ or negative errno.
  * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
  */
-extern int  bind_evtchn_to_irqhandler(
+extern int bind_evtchn_to_irqhandler(
        unsigned int evtchn,
        irqreturn_t (*handler)(int, void *, struct pt_regs *),
        unsigned long irqflags,
        const char *devname,
        void *dev_id);
-extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
+extern int bind_virq_to_irqhandler(
+       unsigned int virq,
+       unsigned int cpu,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id);
+extern int bind_ipi_to_irqhandler(
+       unsigned int ipi,
+       unsigned int cpu,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id);
+
+/*
+ * Common unbind function for all event sources. Takes IRQ to unbind from.
+ * Automatically closes the underlying event channel (even for bindings
+ * made with bind_evtchn_to_irqhandler()).
+ */
+extern void unbind_from_irqhandler(unsigned int irq, void *dev_id);
 
 /*
  * Unlike notify_remote_via_evtchn(), this is safe to use across

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.