Jan Beulich
2011-Oct-19 06:35 UTC
[Xen-devel] [PATCH 2/2] x86: move generic IRQ code out of io_apic.c
x86: move generic IRQ code out of io_apic.c While doing so, eliminate the use of struct irq_cfg and convert the CPU mask accessors to the new style ones as far as possible. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -528,133 +528,6 @@ static void clear_IO_APIC (void) } #ifdef CONFIG_SMP -fastcall void smp_irq_move_cleanup_interrupt(struct cpu_user_regs *regs) -{ - unsigned vector, me; - struct cpu_user_regs *old_regs = set_irq_regs(regs); - - ack_APIC_irq(); - this_cpu(irq_count)++; - irq_enter(); - - me = smp_processor_id(); - for (vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++) { - unsigned int irq; - unsigned int irr; - struct irq_desc *desc; - struct irq_cfg *cfg; - irq = __get_cpu_var(vector_irq)[vector]; - - if (irq == -1) - continue; - - desc = irq_to_desc(irq); - if (!desc) - continue; - - cfg = &desc->arch; - spin_lock(&desc->lock); - if (!cfg->move_cleanup_count) - goto unlock; - - if (vector == cfg->vector && cpu_isset(me, cfg->cpu_mask)) - goto unlock; - - irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); - /* - * Check if the vector that needs to be cleanedup is - * registered at the cpu''s IRR. If so, then this is not - * the best time to clean it up. Lets clean it up in the - * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR - * to myself. - */ - if (irr & (1 << (vector % 32))) { - genapic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); - TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY, - irq, vector, smp_processor_id()); - goto unlock; - } - - TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP, - irq, vector, smp_processor_id()); - - __get_cpu_var(vector_irq)[vector] = -1; - cfg->move_cleanup_count--; - - if ( cfg->move_cleanup_count == 0 ) - { - cfg->old_vector = IRQ_VECTOR_UNASSIGNED; - cpus_clear(cfg->old_cpu_mask); - - if ( cfg->used_vectors ) - { - ASSERT(test_bit(vector, cfg->used_vectors)); - clear_bit(vector, cfg->used_vectors); - } - } -unlock: - spin_unlock(&desc->lock); - } - - irq_exit(); - set_irq_regs(old_regs); -} - -static void send_cleanup_vector(struct irq_cfg *cfg) -{ - cpumask_t cleanup_mask; - - cpus_and(cleanup_mask, cfg->old_cpu_mask, cpu_online_map); - cfg->move_cleanup_count = cpus_weight(cleanup_mask); - genapic->send_IPI_mask(&cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); - - cfg->move_in_progress = 0; -} - -void irq_complete_move(struct irq_desc *desc) -{ - struct irq_cfg *cfg = &desc->arch; - unsigned vector, me; - - if (likely(!cfg->move_in_progress)) - return; - - vector = get_irq_regs()->entry_vector; - me = smp_processor_id(); - - if (vector == cfg->vector && cpu_isset(me, cfg->cpu_mask)) - send_cleanup_vector(cfg); -} - -unsigned int set_desc_affinity(struct irq_desc *desc, const cpumask_t *mask) -{ - struct irq_cfg *cfg; - unsigned int irq; - int ret; - unsigned long flags; - cpumask_t dest_mask; - - if (!cpus_intersects(*mask, cpu_online_map)) - return BAD_APICID; - - irq = desc->irq; - cfg = &desc->arch; - - local_irq_save(flags); - lock_vector_lock(); - ret = __assign_irq_vector(irq, cfg, mask); - unlock_vector_lock(); - local_irq_restore(flags); - - if (ret < 0) - return BAD_APICID; - - cpus_copy(desc->affinity, *mask); - cpus_and(dest_mask, *mask, cfg->cpu_mask); - - return cpu_mask_to_apicid(&dest_mask); -} - static void set_ioapic_affinity_irq(struct irq_desc *desc, const cpumask_t *mask) { --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -598,6 +598,128 @@ void move_native_irq(struct irq_desc *de desc->handler->enable(desc); } +fastcall void smp_irq_move_cleanup_interrupt(struct cpu_user_regs *regs) +{ + unsigned vector, me; + struct cpu_user_regs *old_regs = set_irq_regs(regs); + + ack_APIC_irq(); + this_cpu(irq_count)++; + irq_enter(); + + me = smp_processor_id(); + for (vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++) { + unsigned int irq; + unsigned int irr; + struct irq_desc *desc; + irq = __get_cpu_var(vector_irq)[vector]; + + if (irq == -1) + continue; + + desc = irq_to_desc(irq); + if (!desc) + continue; + + spin_lock(&desc->lock); + if (!desc->arch.move_cleanup_count) + goto unlock; + + if (vector == desc->arch.vector && cpumask_test_cpu(me, &desc->arch.cpu_mask)) + goto unlock; + + irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); + /* + * Check if the vector that needs to be cleanedup is + * registered at the cpu''s IRR. If so, then this is not + * the best time to clean it up. Lets clean it up in the + * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR + * to myself. + */ + if (irr & (1 << (vector % 32))) { + genapic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); + TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY, + irq, vector, smp_processor_id()); + goto unlock; + } + + TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP, + irq, vector, smp_processor_id()); + + __get_cpu_var(vector_irq)[vector] = -1; + desc->arch.move_cleanup_count--; + + if ( desc->arch.move_cleanup_count == 0 ) + { + desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED; + cpumask_clear(&desc->arch.old_cpu_mask); + + if ( desc->arch.used_vectors ) + { + ASSERT(test_bit(vector, desc->arch.used_vectors)); + clear_bit(vector, desc->arch.used_vectors); + } + } +unlock: + spin_unlock(&desc->lock); + } + + irq_exit(); + set_irq_regs(old_regs); +} + +static void send_cleanup_vector(struct irq_desc *desc) +{ + cpumask_t cleanup_mask; + + 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); + + desc->arch.move_in_progress = 0; +} + +void irq_complete_move(struct irq_desc *desc) +{ + unsigned vector, me; + + if (likely(!desc->arch.move_in_progress)) + return; + + vector = get_irq_regs()->entry_vector; + me = smp_processor_id(); + + if (vector == desc->arch.vector && cpumask_test_cpu(me, &desc->arch.cpu_mask)) + send_cleanup_vector(desc); +} + +unsigned int set_desc_affinity(struct irq_desc *desc, const cpumask_t *mask) +{ + unsigned int irq; + int ret; + unsigned long flags; + cpumask_t dest_mask; + + if (!cpus_intersects(*mask, cpu_online_map)) + return BAD_APICID; + + irq = desc->irq; + + local_irq_save(flags); + lock_vector_lock(); + ret = __assign_irq_vector(irq, &desc->arch, 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); + + return cpu_mask_to_apicid(&dest_mask); +} + /* For re-setting irq interrupt affinity for specific irq */ void irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask) { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Andrew Cooper
2011-Oct-19 09:51 UTC
Re: [Xen-devel] [PATCH 2/2] x86: move generic IRQ code out of io_apic.c
On 19/10/11 07:35, Jan Beulich wrote:> x86: move generic IRQ code out of io_apic.c > > While doing so, eliminate the use of struct irq_cfg and convert the > CPU mask accessors to the new style ones as far as possible. > > Signed-off-by: Jan Beulich <jbeulich@suse.com>Acked-by: Andrew Cooper <andrew.coooper3@citrix.com>> --- a/xen/arch/x86/io_apic.c > +++ b/xen/arch/x86/io_apic.c > @@ -528,133 +528,6 @@ static void clear_IO_APIC (void) > } > > #ifdef CONFIG_SMP > -fastcall void smp_irq_move_cleanup_interrupt(struct cpu_user_regs *regs) > -{ > - unsigned vector, me; > - struct cpu_user_regs *old_regs = set_irq_regs(regs); > - > - ack_APIC_irq(); > - this_cpu(irq_count)++; > - irq_enter(); > - > - me = smp_processor_id(); > - for (vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++) { > - unsigned int irq; > - unsigned int irr; > - struct irq_desc *desc; > - struct irq_cfg *cfg; > - irq = __get_cpu_var(vector_irq)[vector]; > - > - if (irq == -1) > - continue; > - > - desc = irq_to_desc(irq); > - if (!desc) > - continue; > - > - cfg = &desc->arch; > - spin_lock(&desc->lock); > - if (!cfg->move_cleanup_count) > - goto unlock; > - > - if (vector == cfg->vector && cpu_isset(me, cfg->cpu_mask)) > - goto unlock; > - > - irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); > - /* > - * Check if the vector that needs to be cleanedup is > - * registered at the cpu''s IRR. If so, then this is not > - * the best time to clean it up. Lets clean it up in the > - * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR > - * to myself. > - */ > - if (irr & (1 << (vector % 32))) { > - genapic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); > - TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY, > - irq, vector, smp_processor_id()); > - goto unlock; > - } > - > - TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP, > - irq, vector, smp_processor_id()); > - > - __get_cpu_var(vector_irq)[vector] = -1; > - cfg->move_cleanup_count--; > - > - if ( cfg->move_cleanup_count == 0 ) > - { > - cfg->old_vector = IRQ_VECTOR_UNASSIGNED; > - cpus_clear(cfg->old_cpu_mask); > - > - if ( cfg->used_vectors ) > - { > - ASSERT(test_bit(vector, cfg->used_vectors)); > - clear_bit(vector, cfg->used_vectors); > - } > - } > -unlock: > - spin_unlock(&desc->lock); > - } > - > - irq_exit(); > - set_irq_regs(old_regs); > -} > - > -static void send_cleanup_vector(struct irq_cfg *cfg) > -{ > - cpumask_t cleanup_mask; > - > - cpus_and(cleanup_mask, cfg->old_cpu_mask, cpu_online_map); > - cfg->move_cleanup_count = cpus_weight(cleanup_mask); > - genapic->send_IPI_mask(&cleanup_mask, IRQ_MOVE_CLEANUP_VECTOR); > - > - cfg->move_in_progress = 0; > -} > - > -void irq_complete_move(struct irq_desc *desc) > -{ > - struct irq_cfg *cfg = &desc->arch; > - unsigned vector, me; > - > - if (likely(!cfg->move_in_progress)) > - return; > - > - vector = get_irq_regs()->entry_vector; > - me = smp_processor_id(); > - > - if (vector == cfg->vector && cpu_isset(me, cfg->cpu_mask)) > - send_cleanup_vector(cfg); > -} > - > -unsigned int set_desc_affinity(struct irq_desc *desc, const cpumask_t *mask) > -{ > - struct irq_cfg *cfg; > - unsigned int irq; > - int ret; > - unsigned long flags; > - cpumask_t dest_mask; > - > - if (!cpus_intersects(*mask, cpu_online_map)) > - return BAD_APICID; > - > - irq = desc->irq; > - cfg = &desc->arch; > - > - local_irq_save(flags); > - lock_vector_lock(); > - ret = __assign_irq_vector(irq, cfg, mask); > - unlock_vector_lock(); > - local_irq_restore(flags); > - > - if (ret < 0) > - return BAD_APICID; > - > - cpus_copy(desc->affinity, *mask); > - cpus_and(dest_mask, *mask, cfg->cpu_mask); > - > - return cpu_mask_to_apicid(&dest_mask); > -} > - > static void > set_ioapic_affinity_irq(struct irq_desc *desc, const cpumask_t *mask) > { > --- a/xen/arch/x86/irq.c > +++ b/xen/arch/x86/irq.c > @@ -598,6 +598,128 @@ void move_native_irq(struct irq_desc *de > desc->handler->enable(desc); > } > > +fastcall void smp_irq_move_cleanup_interrupt(struct cpu_user_regs *regs) > +{ > + unsigned vector, me; > + struct cpu_user_regs *old_regs = set_irq_regs(regs); > + > + ack_APIC_irq(); > + this_cpu(irq_count)++; > + irq_enter(); > + > + me = smp_processor_id(); > + for (vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++) { > + unsigned int irq; > + unsigned int irr; > + struct irq_desc *desc; > + irq = __get_cpu_var(vector_irq)[vector]; > + > + if (irq == -1) > + continue; > + > + desc = irq_to_desc(irq); > + if (!desc) > + continue; > + > + spin_lock(&desc->lock); > + if (!desc->arch.move_cleanup_count) > + goto unlock; > + > + if (vector == desc->arch.vector && cpumask_test_cpu(me, &desc->arch.cpu_mask)) > + goto unlock; > + > + irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); > + /* > + * Check if the vector that needs to be cleanedup is > + * registered at the cpu''s IRR. If so, then this is not > + * the best time to clean it up. Lets clean it up in the > + * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR > + * to myself. > + */ > + if (irr & (1 << (vector % 32))) { > + genapic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR); > + TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP_DELAY, > + irq, vector, smp_processor_id()); > + goto unlock; > + } > + > + TRACE_3D(TRC_HW_IRQ_MOVE_CLEANUP, > + irq, vector, smp_processor_id()); > + > + __get_cpu_var(vector_irq)[vector] = -1; > + desc->arch.move_cleanup_count--; > + > + if ( desc->arch.move_cleanup_count == 0 ) > + { > + desc->arch.old_vector = IRQ_VECTOR_UNASSIGNED; > + cpumask_clear(&desc->arch.old_cpu_mask); > + > + if ( desc->arch.used_vectors ) > + { > + ASSERT(test_bit(vector, desc->arch.used_vectors)); > + clear_bit(vector, desc->arch.used_vectors); > + } > + } > +unlock: > + spin_unlock(&desc->lock); > + } > + > + irq_exit(); > + set_irq_regs(old_regs); > +} > + > +static void send_cleanup_vector(struct irq_desc *desc) > +{ > + cpumask_t cleanup_mask; > + > + 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); > + > + desc->arch.move_in_progress = 0; > +} > + > +void irq_complete_move(struct irq_desc *desc) > +{ > + unsigned vector, me; > + > + if (likely(!desc->arch.move_in_progress)) > + return; > + > + vector = get_irq_regs()->entry_vector; > + me = smp_processor_id(); > + > + if (vector == desc->arch.vector && cpumask_test_cpu(me, &desc->arch.cpu_mask)) > + send_cleanup_vector(desc); > +} > + > +unsigned int set_desc_affinity(struct irq_desc *desc, const cpumask_t *mask) > +{ > + unsigned int irq; > + int ret; > + unsigned long flags; > + cpumask_t dest_mask; > + > + if (!cpus_intersects(*mask, cpu_online_map)) > + return BAD_APICID; > + > + irq = desc->irq; > + > + local_irq_save(flags); > + lock_vector_lock(); > + ret = __assign_irq_vector(irq, &desc->arch, 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); > + > + return cpu_mask_to_apicid(&dest_mask); > +} > + > /* For re-setting irq interrupt affinity for specific irq */ > void irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask) > { > > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel-- Andrew Cooper - Dom0 Kernel Engineer, Citrix XenServer T: +44 (0)1223 225 900, http://www.citrix.com _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel