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 ?
~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
|