IRQ: allocate CPU masks dynamically This includes delaying the initialization of dynamically created IRQs until their actual first use and some further elimination of uses of struct irq_cfg. Signed-off-by: Jan Beulich --- a/xen/arch/ia64/linux-xen/irq_ia64.c +++ b/xen/arch/ia64/linux-xen/irq_ia64.c @@ -303,6 +303,9 @@ int __init request_irq_vector(unsigned i void __init init_IRQ (void) { +#ifdef XEN + BUG_ON(init_irq_data()); +#endif register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL); #ifdef CONFIG_SMP register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); --- a/xen/arch/ia64/xen/irq.c +++ b/xen/arch/ia64/xen/irq.c @@ -74,17 +74,30 @@ unsigned int __ia64_local_vector_to_irq /* * Controller mappings for all interrupt sources: */ -irq_desc_t irq_desc[NR_IRQS] = { - [0 ... NR_IRQS-1] = { - .status = IRQ_DISABLED, - .handler = &no_irq_type, - .lock = SPIN_LOCK_UNLOCKED - .arch = { - .vector = -1, - .cpu_mask = CPU_MASK_ALL, - } +irq_desc_t irq_desc[NR_IRQS]; + +int __init arch_init_one_irq_desc(struct irq_desc *desc) +{ + if (!alloc_cpumask_var(&desc->arch.cpu_mask)) + return -ENOMEM; + + desc->arch.vector = -1; + cpumask_setall(desc->arch.cpu_mask); + + return 0; +} + +int __init init_irq_data(void) +{ + unsigned int irq; + + for (irq = 0; irq < NR_IRQS; irq++) { + struct irq_desc *desc = irq_to_desc(irq); + + desc->irq = irq; + init_one_irq_desc(desc); } -}; +} void __do_IRQ_guest(int irq); --- a/xen/arch/x86/i8259.c +++ b/xen/arch/x86/i8259.c @@ -398,7 +398,7 @@ void __init init_IRQ(void) desc->handler = &i8259A_irq_type; per_cpu(vector_irq, cpu)[FIRST_LEGACY_VECTOR + irq] = irq; - cpumask_copy(&desc->arch.cpu_mask, cpumask_of(cpu)); + cpumask_copy(desc->arch.cpu_mask, cpumask_of(cpu)); desc->arch.vector = FIRST_LEGACY_VECTOR + irq; } --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -648,20 +648,21 @@ static int pin_2_irq(int idx, int apic, void /*__init*/ setup_ioapic_dest(void) { int pin, ioapic, irq, irq_entry; - struct irq_cfg *cfg; if (skip_ioapic_setup) return; for (ioapic = 0; ioapic < nr_ioapics; ioapic++) { for (pin = 0; pin < nr_ioapic_entries[ioapic]; pin++) { + struct irq_desc *desc; + irq_entry = find_irq_entry(ioapic, pin, mp_INT); if (irq_entry == -1) continue; irq = pin_2_irq(irq_entry, ioapic, pin); - cfg = irq_cfg(irq); - BUG_ON(cpus_empty(cfg->cpu_mask)); - set_ioapic_affinity_irq(irq_to_desc(irq), &cfg->cpu_mask); + desc = irq_to_desc(irq); + BUG_ON(cpumask_empty(desc->arch.cpu_mask)); + set_ioapic_affinity_irq(desc, desc->arch.cpu_mask); } } @@ -956,12 +957,12 @@ static void __init setup_IO_APIC_irqs(vo struct IO_APIC_route_entry entry; int apic, pin, idx, irq, first_notcon = 1, vector; unsigned long flags; - struct irq_cfg *cfg; apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); for (apic = 0; apic < nr_ioapics; apic++) { for (pin = 0; pin < nr_ioapic_entries[apic]; pin++) { + struct irq_desc *desc; /* * add it to the IO-APIC irq-routing table: @@ -1016,9 +1017,9 @@ static void __init setup_IO_APIC_irqs(vo if (!apic && platform_legacy_irq(irq)) disable_8259A_irq(irq_to_desc(irq)); } - cfg = irq_cfg(irq); + desc = irq_to_desc(irq); SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest, - cpu_mask_to_apicid(&cfg->cpu_mask)); + cpu_mask_to_apicid(desc->arch.cpu_mask)); spin_lock_irqsave(&ioapic_lock, flags); __ioapic_write_entry(apic, pin, 0, entry); set_native_irq_info(irq, TARGET_CPUS); @@ -2372,7 +2373,7 @@ int ioapic_guest_write(unsigned long phy rte.vector = cfg->vector; SET_DEST(rte.dest.dest32, rte.dest.logical.logical_dest, - cpu_mask_to_apicid(&cfg->cpu_mask)); + cpu_mask_to_apicid(desc->arch.cpu_mask)); io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0)); io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1)); --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -25,6 +25,7 @@ #include static void parse_irq_vector_map_param(char *s); +static int __assign_irq_vector(int irq, struct irq_desc *, const cpumask_t *); /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */ bool_t __read_mostly opt_noirqbalance = 0; @@ -110,7 +111,7 @@ static int __init __bind_irq_vector(int { cpumask_t online_mask; int cpu; - struct irq_cfg *cfg = irq_cfg(irq); + struct irq_desc *desc = irq_to_desc(irq); BUG_ON((unsigned)irq >= nr_irqs); BUG_ON((unsigned)vector >= NR_VECTORS); @@ -118,21 +119,22 @@ static int __init __bind_irq_vector(int cpumask_and(&online_mask, cpu_mask, &cpu_online_map); if (cpumask_empty(&online_mask)) return -EINVAL; - if ((cfg->vector == vector) && cpumask_equal(&cfg->cpu_mask, &online_mask)) + if ( (desc->arch.vector == vector) && + cpumask_equal(desc->arch.cpu_mask, &online_mask) ) return 0; - if (cfg->vector != IRQ_VECTOR_UNASSIGNED) + if ( desc->arch.vector != IRQ_VECTOR_UNASSIGNED ) return -EBUSY; trace_irq_mask(TRC_HW_IRQ_BIND_VECTOR, irq, vector, &online_mask); for_each_cpu_mask(cpu, online_mask) per_cpu(vector_irq, cpu)[vector] = irq; - cfg->vector = vector; - cpumask_copy(&cfg->cpu_mask, &online_mask); - if ( cfg->used_vectors ) + desc->arch.vector = vector; + cpumask_copy(desc->arch.cpu_mask, &online_mask); + if ( desc->arch.used_vectors ) { - ASSERT(!test_bit(vector, cfg->used_vectors)); - set_bit(vector, cfg->used_vectors); + ASSERT(!test_bit(vector, desc->arch.used_vectors)); + set_bit(vector, desc->arch.used_vectors); } - cfg->used = IRQ_USED; + desc->arch.used = IRQ_USED; if (IO_APIC_IRQ(irq)) irq_vector[irq] = vector; return 0; @@ -166,14 +168,17 @@ int create_irq(void) { unsigned long flags; int irq, ret; - irq = -ENOSPC; + struct irq_desc *desc; spin_lock_irqsave(&vector_lock, flags); irq = find_unassigned_irq(); if (irq < 0) goto out; - ret = __assign_irq_vector(irq, irq_cfg(irq), TARGET_CPUS); + desc = irq_to_desc(irq); + ret = init_one_irq_desc(desc); + if (!ret) + ret = __assign_irq_vector(irq, desc, TARGET_CPUS); if (ret < 0) irq = ret; out: @@ -197,7 +202,7 @@ static void dynamic_irq_cleanup(unsigned desc->msi_desc = NULL; desc->handler = &no_irq_type; desc->arch.used_vectors = NULL; - cpumask_setall(&desc->affinity); + cpumask_setall(desc->affinity); spin_unlock_irqrestore(&desc->lock, flags); /* Wait to make sure it's not being used on another CPU */ @@ -211,38 +216,38 @@ static void __clear_irq_vector(int irq) { int cpu, vector, old_vector; cpumask_t tmp_mask; - struct irq_cfg *cfg = irq_cfg(irq); + struct irq_desc *desc = irq_to_desc(irq); - BUG_ON(!cfg->vector); + BUG_ON(!desc->arch.vector); - /* Always clear cfg->vector */ - vector = cfg->vector; - cpumask_and(&tmp_mask, &cfg->cpu_mask, &cpu_online_map); + /* Always clear desc->arch.vector */ + vector = desc->arch.vector; + cpumask_and(&tmp_mask, desc->arch.cpu_mask, &cpu_online_map); for_each_cpu_mask(cpu, tmp_mask) { ASSERT( per_cpu(vector_irq, cpu)[vector] == irq ); per_cpu(vector_irq, cpu)[vector] = -1; } - cfg->vector = IRQ_VECTOR_UNASSIGNED; - cpumask_clear(&cfg->cpu_mask); + desc->arch.vector = IRQ_VECTOR_UNASSIGNED; + cpumask_clear(desc->arch.cpu_mask); - if ( cfg->used_vectors ) + if ( desc->arch.used_vectors ) { - ASSERT(test_bit(vector, cfg->used_vectors)); - clear_bit(vector, cfg->used_vectors); + ASSERT(test_bit(vector, desc->arch.used_vectors)); + clear_bit(vector, desc->arch.used_vectors); } - cfg->used = IRQ_UNUSED; + desc->arch.used = IRQ_UNUSED; trace_irq_mask(TRC_HW_IRQ_CLEAR_VECTOR, irq, vector, &tmp_mask); - if (likely(!cfg->move_in_progress)) + if ( likely(!desc->arch.move_in_progress) ) return; - /* If we were in motion, also clear cfg->old_vector */ - old_vector = cfg->old_vector; - cpumask_and(&tmp_mask, &cfg->old_cpu_mask, &cpu_online_map); + /* If we were in motion, also clear desc->arch.old_vector */ + old_vector = desc->arch.old_vector; + cpumask_and(&tmp_mask, desc->arch.old_cpu_mask, &cpu_online_map); for_each_cpu_mask(cpu, tmp_mask) { ASSERT( per_cpu(vector_irq, cpu)[old_vector] == irq ); @@ -250,16 +255,16 @@ static void __clear_irq_vector(int irq) per_cpu(vector_irq, cpu)[old_vector] = -1; } - cfg->old_vector = IRQ_VECTOR_UNASSIGNED; - cpumask_clear(&cfg->old_cpu_mask); + desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED; + cpumask_clear(desc->arch.old_cpu_mask); - if ( cfg->used_vectors ) + if ( desc->arch.used_vectors ) { - ASSERT(test_bit(old_vector, cfg->used_vectors)); - clear_bit(old_vector, cfg->used_vectors); + ASSERT(test_bit(old_vector, desc->arch.used_vectors)); + clear_bit(old_vector, desc->arch.used_vectors); } - cfg->move_in_progress = 0; + desc->arch.move_in_progress = 0; } void clear_irq_vector(int irq) @@ -296,25 +301,28 @@ int irq_to_vector(int irq) return vector; } -static void __init init_one_irq_desc(struct irq_desc *desc) +int arch_init_one_irq_desc(struct irq_desc *desc) { - desc->status = IRQ_DISABLED; - desc->handler = &no_irq_type; - desc->action = NULL; - desc->msi_desc = NULL; - spin_lock_init(&desc->lock); - cpumask_setall(&desc->affinity); - INIT_LIST_HEAD(&desc->rl_link); -} + if ( !zalloc_cpumask_var(&desc->arch.cpu_mask) ) + return -ENOMEM; + + if ( !alloc_cpumask_var(&desc->arch.old_cpu_mask) ) + { + free_cpumask_var(desc->arch.cpu_mask); + return -ENOMEM; + } -static void __init init_one_irq_cfg(struct irq_cfg *cfg) -{ - cfg->vector = IRQ_VECTOR_UNASSIGNED; - cfg->old_vector = IRQ_VECTOR_UNASSIGNED; - cpumask_clear(&cfg->cpu_mask); - cpumask_clear(&cfg->old_cpu_mask); - cfg->used_vectors = NULL; - cfg->used = IRQ_UNUSED; + if ( !alloc_cpumask_var(&desc->arch.pending_mask) ) + { + free_cpumask_var(desc->arch.old_cpu_mask); + free_cpumask_var(desc->arch.cpu_mask); + return -ENOMEM; + } + + desc->arch.vector = IRQ_VECTOR_UNASSIGNED; + desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED; + + return 0; } int __init init_irq_data(void) @@ -331,12 +339,13 @@ int __init init_irq_data(void) if ( !irq_desc || !irq_vector ) return -ENOMEM; - for (irq = 0; irq < nr_irqs; irq++) { + for (irq = 0; irq < nr_irqs_gsi; irq++) { desc = irq_to_desc(irq); desc->irq = irq; init_one_irq_desc(desc); - init_one_irq_cfg(&desc->arch); } + for (; irq < nr_irqs; irq++) + irq_to_desc(irq)->irq = irq; /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */ set_bit(LEGACY_SYSCALL_VECTOR, used_vectors); @@ -403,7 +412,8 @@ static vmask_t *irq_get_used_vector_mask return ret; } -int __assign_irq_vector(int irq, struct irq_cfg *cfg, const cpumask_t *mask) +static int __assign_irq_vector( + int irq, struct irq_desc *desc, const cpumask_t *mask) { /* * NOTE! The local APIC isn't very good at handling @@ -426,13 +436,13 @@ int __assign_irq_vector(int irq, struct old_vector = irq_to_vector(irq); if (old_vector) { cpumask_and(&tmp_mask, mask, &cpu_online_map); - if (cpumask_intersects(&tmp_mask, &cfg->cpu_mask)) { - cfg->vector = old_vector; + if (cpumask_intersects(&tmp_mask, desc->arch.cpu_mask)) { + desc->arch.vector = old_vector; return 0; } } - if ((cfg->move_in_progress) || cfg->move_cleanup_count) + if ( desc->arch.move_in_progress || desc->arch.move_cleanup_count ) return -EAGAIN; err = -ENOSPC; @@ -440,9 +450,9 @@ int __assign_irq_vector(int irq, struct /* This is the only place normal IRQs are ever marked * as "in use". If they're not in use yet, check to see * if we need to assign a global vector mask. */ - if ( cfg->used == IRQ_USED ) + if ( desc->arch.used == IRQ_USED ) { - irq_used_vectors = cfg->used_vectors; + irq_used_vectors = desc->arch.used_vectors; } else irq_used_vectors = irq_get_used_vector_mask(irq); @@ -485,29 +495,29 @@ next: current_offset = offset; local_irq_save(flags); if (old_vector) { - cfg->move_in_progress = 1; - cpumask_copy(&cfg->old_cpu_mask, &cfg->cpu_mask); - cfg->old_vector = cfg->vector; + desc->arch.move_in_progress = 1; + cpumask_copy(desc->arch.old_cpu_mask, desc->arch.cpu_mask); + desc->arch.old_vector = desc->arch.vector; } trace_irq_mask(TRC_HW_IRQ_ASSIGN_VECTOR, irq, vector, &tmp_mask); for_each_cpu_mask(new_cpu, tmp_mask) per_cpu(vector_irq, new_cpu)[vector] = irq; - cfg->vector = vector; - cpumask_copy(&cfg->cpu_mask, &tmp_mask); + desc->arch.vector = vector; + cpumask_copy(desc->arch.cpu_mask, &tmp_mask); - cfg->used = IRQ_USED; - ASSERT((cfg->used_vectors == NULL) - || (cfg->used_vectors == irq_used_vectors)); - cfg->used_vectors = irq_used_vectors; + desc->arch.used = IRQ_USED; + ASSERT((desc->arch.used_vectors == NULL) + || (desc->arch.used_vectors == irq_used_vectors)); + desc->arch.used_vectors = irq_used_vectors; if (IO_APIC_IRQ(irq)) irq_vector[irq] = vector; - if ( cfg->used_vectors ) + if ( desc->arch.used_vectors ) { - ASSERT(!test_bit(vector, cfg->used_vectors)); + ASSERT(!test_bit(vector, desc->arch.used_vectors)); - set_bit(vector, cfg->used_vectors); + set_bit(vector, desc->arch.used_vectors); } err = 0; @@ -521,16 +531,15 @@ int assign_irq_vector(int irq) { int ret; unsigned long flags; - struct irq_cfg *cfg = irq_cfg(irq); struct irq_desc *desc = irq_to_desc(irq); BUG_ON(irq >= nr_irqs || irq <0); spin_lock_irqsave(&vector_lock, flags); - ret = __assign_irq_vector(irq, cfg, TARGET_CPUS); + ret = __assign_irq_vector(irq, desc, TARGET_CPUS); if (!ret) { - ret = cfg->vector; - cpumask_copy(&desc->affinity, &cfg->cpu_mask); + ret = desc->arch.vector; + cpumask_copy(desc->affinity, desc->arch.cpu_mask); } spin_unlock_irqrestore(&vector_lock, flags); return ret; @@ -543,15 +552,16 @@ int assign_irq_vector(int irq) void __setup_vector_irq(int cpu) { int irq, vector; - struct irq_cfg *cfg; /* Clear vector_irq */ for (vector = 0; vector < NR_VECTORS; ++vector) per_cpu(vector_irq, cpu)[vector] = -1; /* Mark the inuse vectors */ for (irq = 0; irq < nr_irqs; ++irq) { - cfg = irq_cfg(irq); - if (!cpu_isset(cpu, cfg->cpu_mask)) + struct irq_desc *desc = irq_to_desc(irq); + + if (!irq_desc_initialized(desc) || + !cpumask_test_cpu(cpu, desc->arch.cpu_mask)) continue; vector = irq_to_vector(irq); per_cpu(vector_irq, cpu)[vector] = irq; @@ -560,12 +570,14 @@ void __setup_vector_irq(int cpu) void move_masked_irq(struct irq_desc *desc) { + cpumask_t *pending_mask = desc->arch.pending_mask; + if (likely(!(desc->status & IRQ_MOVE_PENDING))) return; desc->status &= ~IRQ_MOVE_PENDING; - if (unlikely(cpus_empty(desc->pending_mask))) + if (unlikely(cpumask_empty(pending_mask))) return; if (!desc->handler->set_affinity) @@ -580,10 +592,10 @@ void move_masked_irq(struct irq_desc *de * * For correct operation this depends on the caller masking the irqs. */ - if (likely(cpus_intersects(desc->pending_mask, cpu_online_map))) - desc->handler->set_affinity(desc, &desc->pending_mask); + if ( likely(cpumask_intersects(pending_mask, &cpu_online_map)) ) + desc->handler->set_affinity(desc, pending_mask); - cpumask_clear(&desc->pending_mask); + cpumask_clear(pending_mask); } void move_native_irq(struct irq_desc *desc) @@ -626,7 +638,8 @@ fastcall void smp_irq_move_cleanup_inter if (!desc->arch.move_cleanup_count) goto unlock; - if (vector == desc->arch.vector && cpumask_test_cpu(me, &desc->arch.cpu_mask)) + if ( vector == desc->arch.vector && + cpumask_test_cpu(me, desc->arch.cpu_mask) ) goto unlock; irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); @@ -653,7 +666,7 @@ fastcall void smp_irq_move_cleanup_inter if ( desc->arch.move_cleanup_count == 0 ) { desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED; - cpumask_clear(&desc->arch.old_cpu_mask); + cpumask_clear(desc->arch.old_cpu_mask); if ( desc->arch.used_vectors ) { @@ -673,7 +686,7 @@ static void send_cleanup_vector(struct i { cpumask_t cleanup_mask; - cpumask_and(&cleanup_mask, &desc->arch.old_cpu_mask, &cpu_online_map); + cpumask_and(&cleanup_mask, desc->arch.old_cpu_mask, &cpu_online_map); desc->arch.move_cleanup_count = cpumask_weight(&cleanup_mask); genapic->send_IPI_mask(&cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); @@ -690,7 +703,8 @@ void irq_complete_move(struct irq_desc * vector = get_irq_regs()->entry_vector; me = smp_processor_id(); - if (vector == desc->arch.vector && cpumask_test_cpu(me, &desc->arch.cpu_mask)) + if ( vector == desc->arch.vector && + cpumask_test_cpu(me, desc->arch.cpu_mask) ) send_cleanup_vector(desc); } @@ -708,15 +722,15 @@ unsigned int set_desc_affinity(struct ir local_irq_save(flags); lock_vector_lock(); - ret = __assign_irq_vector(irq, &desc->arch, mask); + ret = __assign_irq_vector(irq, desc, mask); unlock_vector_lock(); local_irq_restore(flags); if (ret < 0) return BAD_APICID; - cpumask_copy(&desc->affinity, mask); - cpumask_and(&dest_mask, mask, &desc->arch.cpu_mask); + cpumask_copy(desc->affinity, mask); + cpumask_and(&dest_mask, mask, desc->arch.cpu_mask); return cpu_mask_to_apicid(&dest_mask); } @@ -730,7 +744,7 @@ void irq_set_affinity(struct irq_desc *d ASSERT(spin_is_locked(&desc->lock)); desc->status &= ~IRQ_MOVE_PENDING; wmb(); - cpumask_copy(&desc->pending_mask, mask); + cpumask_copy(desc->arch.pending_mask, mask); wmb(); desc->status |= IRQ_MOVE_PENDING; } @@ -1992,13 +2006,13 @@ static void dump_irqs(unsigned char key) desc = irq_to_desc(irq); - if ( !desc->handler || desc->handler == &no_irq_type ) + if ( !irq_desc_initialized(desc) || desc->handler == &no_irq_type ) continue; spin_lock_irqsave(&desc->lock, flags); cpumask_scnprintf(keyhandler_scratch, sizeof(keyhandler_scratch), - &desc->affinity); + desc->affinity); printk(" IRQ:%4d affinity:%s vec:%02x type=%-15s" " status=%08x ", irq, keyhandler_scratch, desc->arch.vector, @@ -2073,10 +2087,12 @@ void fixup_irqs(void) continue; desc = irq_to_desc(irq); + if ( !irq_desc_initialized(desc) ) + continue; spin_lock(&desc->lock); - cpumask_copy(&affinity, &desc->affinity); + cpumask_copy(&affinity, desc->affinity); if ( !desc->action || cpumask_subset(&affinity, &cpu_online_map) ) { spin_unlock(&desc->lock); --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -125,13 +125,13 @@ void msi_compose_msg(struct irq_desc *de unsigned dest; int vector = desc->arch.vector; - if ( cpumask_empty(&desc->arch.cpu_mask) ) { + if ( cpumask_empty(desc->arch.cpu_mask) ) { dprintk(XENLOG_ERR,"%s, compose msi message error!!\n", __func__); return; } if ( vector ) { - dest = cpu_mask_to_apicid(&desc->arch.cpu_mask); + dest = cpu_mask_to_apicid(desc->arch.cpu_mask); msg->address_hi = MSI_ADDR_BASE_HI; msg->address_lo = --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -1011,7 +1011,7 @@ void __init smp_intr_init(void) irq_vector[irq] = FIRST_HIPRIORITY_VECTOR + seridx + 1; per_cpu(vector_irq, cpu)[FIRST_HIPRIORITY_VECTOR + seridx + 1] = irq; irq_to_desc(irq)->arch.vector = FIRST_HIPRIORITY_VECTOR + seridx + 1; - cpumask_copy(&irq_to_desc(irq)->arch.cpu_mask, &cpu_online_map); + cpumask_copy(irq_to_desc(irq)->arch.cpu_mask, &cpu_online_map); } /* IPI for cleanuping vectors after irq move */ --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -5,6 +5,7 @@ obj-y += domctl.o obj-y += domain.o obj-y += event_channel.o obj-y += grant_table.o +obj-y += irq.o obj-y += kernel.o obj-y += keyhandler.o obj-y += kexec.o --- /dev/null +++ a/xen/common/irq.c @@ -0,0 +1,28 @@ +#include +#include + +int init_one_irq_desc(struct irq_desc *desc) +{ + int err; + + if (irq_desc_initialized(desc)) + return 0; + + if ( !alloc_cpumask_var(&desc->affinity) ) + return -ENOMEM; + + desc->status = IRQ_DISABLED; + desc->handler = &no_irq_type; + spin_lock_init(&desc->lock); + cpumask_setall(desc->affinity); + INIT_LIST_HEAD(&desc->rl_link); + + err = arch_init_one_irq_desc(desc); + if ( err ) + { + free_cpumask_var(desc->affinity); + desc->handler = NULL; + } + + return err; +} --- a/xen/drivers/passthrough/vtd/iommu.c +++ b/xen/drivers/passthrough/vtd/iommu.c @@ -1965,17 +1965,18 @@ static int init_vtd_hw(void) struct iommu_flush *flush = NULL; int ret; unsigned long flags; - struct irq_cfg *cfg; /* * Basic VT-d HW init: set VT-d interrupt, clear VT-d faults. */ for_each_drhd_unit ( drhd ) { + struct irq_desc *desc; + iommu = drhd->iommu; - cfg = irq_cfg(iommu->irq); - dma_msi_set_affinity(irq_to_desc(iommu->irq), &cfg->cpu_mask); + desc = irq_to_desc(iommu->irq); + dma_msi_set_affinity(desc, desc->arch.cpu_mask); clear_fault_bits(iommu); --- a/xen/include/asm-ia64/linux-xen/asm/irq.h +++ b/xen/include/asm-ia64/linux-xen/asm/irq.h @@ -18,8 +18,10 @@ struct irq_cfg { #define arch_irq_desc irq_cfg int vector; - cpumask_t cpu_mask; + cpumask_var_t cpu_mask; }; + +int init_irq_data(void); #endif static __inline__ int --- a/xen/include/asm-x86/irq.h +++ b/xen/include/asm-x86/irq.h @@ -33,8 +33,9 @@ struct irq_cfg { #define arch_irq_desc irq_cfg s16 vector; /* vector itself is only 8 bits, */ s16 old_vector; /* but we use -1 for unassigned */ - cpumask_t cpu_mask; - cpumask_t old_cpu_mask; + cpumask_var_t cpu_mask; + cpumask_var_t old_cpu_mask; + cpumask_var_t pending_mask; unsigned move_cleanup_count; vmask_t *used_vectors; u8 move_in_progress : 1; @@ -174,8 +175,6 @@ void __setup_vector_irq(int cpu); void move_native_irq(struct irq_desc *); void move_masked_irq(struct irq_desc *); -int __assign_irq_vector(int irq, struct irq_cfg *, const cpumask_t *); - int bind_irq_vector(int irq, int vector, const cpumask_t *); void irq_set_affinity(struct irq_desc *, const cpumask_t *mask); --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -76,8 +76,7 @@ typedef struct irq_desc { int irq; spinlock_t lock; struct arch_irq_desc arch; - cpumask_t affinity; - cpumask_t pending_mask; /* IRQ migration pending mask */ + cpumask_var_t affinity; /* irq ratelimit */ s_time_t rl_quantum_start; @@ -85,6 +84,11 @@ typedef struct irq_desc { struct list_head rl_link; } __cacheline_aligned irq_desc_t; +int init_one_irq_desc(struct irq_desc *); +int arch_init_one_irq_desc(struct irq_desc *); + +#define irq_desc_initialized(desc) ((desc)->handler != NULL) + #if defined(__ia64__) extern irq_desc_t irq_desc[NR_VECTORS]; @@ -153,7 +157,7 @@ extern irq_desc_t *pirq_spin_lock_irq_de static inline void set_native_irq_info(unsigned int irq, const cpumask_t *mask) { - cpumask_copy(&irq_desc[irq].affinity, mask); + cpumask_copy(irq_to_desc(irq)->affinity, mask); } unsigned int set_desc_affinity(struct irq_desc *, const cpumask_t *);