aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/irq.c
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2011-09-30 21:15:21 +0100
committerKeir Fraser <keir@xen.org>2011-09-30 21:15:21 +0100
commit3a5a642a938cafc3e9eebd975b223e14610416e2 (patch)
tree941d5092b63045f9b0010af2859e3653278b2425 /xen/arch/x86/irq.c
parent10fd868e6ca92ac42057cb53199922b7ae13ba9c (diff)
downloadxen-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.c36
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)