[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1/2] IRQ: allocate CPU masks dynamically
On 03/11/11 15:17, Jan Beulich wrote: >>>> On 03.11.11 at 15:49, Andrew Cooper <andrew.cooper3@xxxxxxxxxx> wrote: >> On 03/11/11 14:26, Jan Beulich wrote: >>> 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 <jbeulich@xxxxxxxx> >> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> >> >> One query which may or may not affect the patch. Would we get better >> caching characteristics if all cpumasks were allocated in consecutive >> memory, rather than having 3 individual allocs in arch_init_one_irq_desc ? > That was what the first version of the patch did, rejected by Keir > (and not liked too much by me either). > > Jan My understanding of the objection was hiding the variables themselves as an array in the code. An alternative approach such as alloc'ing 3*sizeof(cpu mask) (cache aligned) and assigning the relevant pointers to the current cpumask_var_t's would be a suitable approach which causes the cpumasks to be in contiguous memory, but not changing how they are referenced in the code. ~Andrew >>> --- 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 <public/physdev.h> >>> >>> 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 <xen/config.h> >>> +#include <xen/irq.h> >>> + >>> +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 *); >>> >>> > > -- Andrew Cooper - Dom0 Kernel Engineer, Citrix XenServer T: +44 (0)1223 225 900, http://www.citrix.com _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |