diff options
author | Keir Fraser <keir@xen.org> | 2011-09-30 21:15:21 +0100 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-09-30 21:15:21 +0100 |
commit | 3a5a642a938cafc3e9eebd975b223e14610416e2 (patch) | |
tree | 941d5092b63045f9b0010af2859e3653278b2425 /xen/arch/x86/irq.c | |
parent | 10fd868e6ca92ac42057cb53199922b7ae13ba9c (diff) | |
download | xen-3a5a642a938cafc3e9eebd975b223e14610416e2.tar.gz xen-3a5a642a938cafc3e9eebd975b223e14610416e2.tar.bz2 xen-3a5a642a938cafc3e9eebd975b223e14610416e2.zip |
x86,irq: Clean up __clear_irq_vector
Fix and clean up the logic to __clear_irq_vector().
We always need to clear the things related to cfg->vector.
If the IRQ is currently in motion, then we need to also clear
out things related to cfg->old_vector.
This patch reorganizes the function to make the parallels between
the two clean-ups more obvious.
The main functional change here is with cfg->used_vectors; make
sure to clear cfg->vector always (even if !cfg->move_in_progress);
if cfg->move_in_progress, clear cfg->old_vector as well.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Diffstat (limited to 'xen/arch/x86/irq.c')
-rw-r--r-- | xen/arch/x86/irq.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index e0b2d01379..75041049bf 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -211,43 +211,57 @@ static void dynamic_irq_cleanup(unsigned int irq) static void __clear_irq_vector(int irq) { - int cpu, vector; + int cpu, vector, old_vector; cpumask_t tmp_mask; struct irq_cfg *cfg = irq_cfg(irq); BUG_ON(!cfg->vector); + /* Always clear cfg->vector */ vector = cfg->vector; cpus_and(tmp_mask, cfg->cpu_mask, cpu_online_map); - trace_irq_mask(TRC_HW_IRQ_CLEAR_VECTOR, irq, vector, &tmp_mask); - - for_each_cpu_mask(cpu, tmp_mask) + 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; cpus_clear(cfg->cpu_mask); + + if ( cfg->used_vectors ) + { + ASSERT(test_bit(vector, cfg->used_vectors)); + clear_bit(vector, cfg->used_vectors); + } + cfg->used = IRQ_UNUSED; + trace_irq_mask(TRC_HW_IRQ_CLEAR_VECTOR, irq, vector, &tmp_mask); + if (likely(!cfg->move_in_progress)) return; + /* If we were in motion, also clear cfg->old_vector */ + old_vector = cfg->old_vector; cpus_and(tmp_mask, cfg->old_cpu_mask, cpu_online_map); + for_each_cpu_mask(cpu, tmp_mask) { - ASSERT( per_cpu(vector_irq, cpu)[cfg->old_vector] == irq ); - TRACE_3D(TRC_HW_IRQ_MOVE_FINISH, irq, vector, cpu); - per_cpu(vector_irq, cpu)[cfg->old_vector] = -1; + ASSERT( per_cpu(vector_irq, cpu)[old_vector] == irq ); + TRACE_3D(TRC_HW_IRQ_MOVE_FINISH, irq, old_vector, cpu); + per_cpu(vector_irq, cpu)[old_vector] = -1; } + 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); + ASSERT(test_bit(old_vector, cfg->used_vectors)); + clear_bit(old_vector, cfg->used_vectors); } cfg->move_in_progress = 0; - cfg->old_vector = IRQ_VECTOR_UNASSIGNED; - cpus_clear(cfg->old_cpu_mask); } void clear_irq_vector(int irq) |