WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Rationalise the kernel event-channel binding interfaces. The
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 08 Nov 2005 16:54:07 +0000
Delivery-date: Tue, 08 Nov 2005 16:54:26 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Rationalise the kernel event-channel binding interfaces. The, Xen patchbot -unstable <=