# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID c76daba31026e77d3b6cbae2164a3d5315f9273d
# Parent f80709ba0e790af316c518eeb4ffab153801574f
In both i386 and x86-64 Linux, using a static variable (and thus
having the potential of missing synchronization there,
as I suspect exists in native Linux) is not needed with the hypercall
approach. In the hypervisor, the patch adds the
needed synchronization.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
diff -r f80709ba0e79 -r c76daba31026
linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Thu Apr 20
10:38:07 2006 +0100
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c Thu Apr 20
14:10:35 2006 +0100
@@ -1205,7 +1205,6 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos
int assign_irq_vector(int irq)
{
- static int current_vector = FIRST_DEVICE_VECTOR;
physdev_op_t op;
BUG_ON(irq >= NR_IRQ_VECTORS);
@@ -1216,13 +1215,12 @@ int assign_irq_vector(int irq)
op.u.irq_op.irq = irq;
if (HYPERVISOR_physdev_op(&op))
return -ENOSPC;
- current_vector = op.u.irq_op.vector;
-
- vector_irq[current_vector] = irq;
+
+ vector_irq[op.u.irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = current_vector;
-
- return current_vector;
+ IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
+
+ return op.u.irq_op.vector;
}
#ifndef CONFIG_XEN
diff -r f80709ba0e79 -r c76daba31026
linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Thu Apr 20
10:38:07 2006 +0100
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/io_apic-xen.c Thu Apr 20
14:10:35 2006 +0100
@@ -869,7 +869,6 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos
int assign_irq_vector(int irq)
{
- static int current_vector = FIRST_DEVICE_VECTOR;
physdev_op_t op;
BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
@@ -880,13 +879,12 @@ int assign_irq_vector(int irq)
op.u.irq_op.irq = irq;
if (HYPERVISOR_physdev_op(&op))
return -ENOSPC;
- current_vector = op.u.irq_op.vector;
-
- vector_irq[current_vector] = irq;
+
+ vector_irq[op.u.irq_op.vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = current_vector;
-
- return current_vector;
+ IO_APIC_VECTOR(irq) = op.u.irq_op.vector;
+
+ return op.u.irq_op.vector;
}
extern void (*interrupt[NR_IRQS])(void);
diff -r f80709ba0e79 -r c76daba31026 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c Thu Apr 20 10:38:07 2006 +0100
+++ b/xen/arch/x86/io_apic.c Thu Apr 20 14:10:35 2006 +0100
@@ -48,6 +48,7 @@ static struct { int pin, apic; } ioapic_
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock);
+static DEFINE_SPINLOCK(vector_lock);
int skip_ioapic_setup;
@@ -661,11 +662,17 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mos
int assign_irq_vector(int irq)
{
- static int current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
+ static unsigned current_vector = FIRST_DYNAMIC_VECTOR, offset = 0;
+ unsigned vector;
BUG_ON(irq >= NR_IRQ_VECTORS);
- if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
+ spin_lock(&vector_lock);
+
+ if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
+ spin_unlock(&vector_lock);
return IO_APIC_VECTOR(irq);
+ }
+
next:
current_vector += 8;
@@ -679,16 +686,21 @@ next:
if (current_vector > LAST_DYNAMIC_VECTOR) {
offset++;
- if (!(offset%8))
+ if (!(offset%8)) {
+ spin_unlock(&vector_lock);
return -ENOSPC;
+ }
current_vector = FIRST_DYNAMIC_VECTOR + offset;
}
- vector_irq[current_vector] = irq;
+ vector = current_vector;
+ vector_irq[vector] = irq;
if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = current_vector;
-
- return current_vector;
+ IO_APIC_VECTOR(irq) = vector;
+
+ spin_unlock(&vector_lock);
+
+ return vector;
}
static struct hw_interrupt_type ioapic_level_type;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|