[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |