diff options
author | Jan Beulich <jbeulich@novell.com> | 2006-06-26 07:56:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-26 13:48:15 -0400 |
commit | 0a1ad60d7a7eb433095bc1b2c8b475f3f278f61d (patch) | |
tree | b7f0efd5d2afb879b8ff9bfbc44c6ea94b3e7a89 /arch/i386/kernel/io_apic.c | |
parent | a32073bffc656ca4bde6002b6cf7c1a8e0e22712 (diff) |
[PATCH] x86_64: serialize assign_irq_vector() use of static variables
Since assign_irq_vector() can be called at runtime, its access of static
variables should be protected by a lock.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index a62df3e764c5..43ffdd012d26 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -50,6 +50,7 @@ atomic_t irq_mis_count; | |||
50 | static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; | 50 | static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; |
51 | 51 | ||
52 | static DEFINE_SPINLOCK(ioapic_lock); | 52 | static DEFINE_SPINLOCK(ioapic_lock); |
53 | static DEFINE_SPINLOCK(vector_lock); | ||
53 | 54 | ||
54 | int timer_over_8254 __initdata = 1; | 55 | int timer_over_8254 __initdata = 1; |
55 | 56 | ||
@@ -1161,10 +1162,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; | |||
1161 | int assign_irq_vector(int irq) | 1162 | int assign_irq_vector(int irq) |
1162 | { | 1163 | { |
1163 | static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; | 1164 | static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; |
1165 | int vector; | ||
1166 | |||
1167 | BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); | ||
1168 | |||
1169 | spin_lock(&vector_lock); | ||
1164 | 1170 | ||
1165 | BUG_ON(irq >= NR_IRQ_VECTORS); | 1171 | if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { |
1166 | if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) | 1172 | spin_unlock(&vector_lock); |
1167 | return IO_APIC_VECTOR(irq); | 1173 | return IO_APIC_VECTOR(irq); |
1174 | } | ||
1168 | next: | 1175 | next: |
1169 | current_vector += 8; | 1176 | current_vector += 8; |
1170 | if (current_vector == SYSCALL_VECTOR) | 1177 | if (current_vector == SYSCALL_VECTOR) |
@@ -1172,16 +1179,21 @@ next: | |||
1172 | 1179 | ||
1173 | if (current_vector >= FIRST_SYSTEM_VECTOR) { | 1180 | if (current_vector >= FIRST_SYSTEM_VECTOR) { |
1174 | offset++; | 1181 | offset++; |
1175 | if (!(offset%8)) | 1182 | if (!(offset%8)) { |
1183 | spin_unlock(&vector_lock); | ||
1176 | return -ENOSPC; | 1184 | return -ENOSPC; |
1185 | } | ||
1177 | current_vector = FIRST_DEVICE_VECTOR + offset; | 1186 | current_vector = FIRST_DEVICE_VECTOR + offset; |
1178 | } | 1187 | } |
1179 | 1188 | ||
1180 | vector_irq[current_vector] = irq; | 1189 | vector = current_vector; |
1190 | vector_irq[vector] = irq; | ||
1181 | if (irq != AUTO_ASSIGN) | 1191 | if (irq != AUTO_ASSIGN) |
1182 | IO_APIC_VECTOR(irq) = current_vector; | 1192 | IO_APIC_VECTOR(irq) = vector; |
1193 | |||
1194 | spin_unlock(&vector_lock); | ||
1183 | 1195 | ||
1184 | return current_vector; | 1196 | return vector; |
1185 | } | 1197 | } |
1186 | 1198 | ||
1187 | static struct hw_interrupt_type ioapic_level_type; | 1199 | static struct hw_interrupt_type ioapic_level_type; |