Commit 3b5cc090 authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by Tony Luck

[IA64] assign_irq_vector() should not panic

Current assign_irq_vector() will panic if interrupt vectors is running
out. But I think how to handle the case of lack of interrupt vectors
should be handled by the caller of this function. For example, some
PCI devices can raise the interrupt signal via both MSI and I/O
APIC. So even if the driver for these device fails to allocate a
vector for MSI, the driver still has a chance to use I/O APIC based
interrupt. But currently there is no chance for these driver to use
I/O APIC based interrupt because kernel will panic when
assign_irq_vector() fails to allocate interrupt vector.

The following patch changes assign_irq_vector() for ia64 to return
-ENOSPC on error instead of panic (as i386 and x86_64 versions do).
Signed-off-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 69913927
...@@ -191,7 +191,7 @@ simeth_probe1(void) ...@@ -191,7 +191,7 @@ simeth_probe1(void)
unsigned char mac_addr[ETH_ALEN]; unsigned char mac_addr[ETH_ALEN];
struct simeth_local *local; struct simeth_local *local;
struct net_device *dev; struct net_device *dev;
int fd, i, err; int fd, i, err, rc;
/* /*
* XXX Fix me * XXX Fix me
...@@ -228,7 +228,9 @@ simeth_probe1(void) ...@@ -228,7 +228,9 @@ simeth_probe1(void)
return err; return err;
} }
dev->irq = assign_irq_vector(AUTO_ASSIGN); if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
panic("%s: out of interrupt vectors!\n", __FUNCTION__);
dev->irq = rc;
/* /*
* attach the interrupt in the simulator, this does enable interrupts * attach the interrupt in the simulator, this does enable interrupts
......
...@@ -982,7 +982,7 @@ static struct tty_operations hp_ops = { ...@@ -982,7 +982,7 @@ static struct tty_operations hp_ops = {
static int __init static int __init
simrs_init (void) simrs_init (void)
{ {
int i; int i, rc;
struct serial_state *state; struct serial_state *state;
if (!ia64_platform_is("hpsim")) if (!ia64_platform_is("hpsim"))
...@@ -1017,7 +1017,10 @@ simrs_init (void) ...@@ -1017,7 +1017,10 @@ simrs_init (void)
if (state->type == PORT_UNKNOWN) continue; if (state->type == PORT_UNKNOWN) continue;
if (!state->irq) { if (!state->irq) {
state->irq = assign_irq_vector(AUTO_ASSIGN); if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
panic("%s: out of interrupt vectors!\n",
__FUNCTION__);
state->irq = rc;
ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
} }
......
...@@ -489,8 +489,6 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po ...@@ -489,8 +489,6 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po
} }
} }
} }
if (vector < 0)
panic("%s: out of interrupt vectors!\n", __FUNCTION__);
return vector; return vector;
} }
...@@ -506,6 +504,8 @@ iosapic_reassign_vector (int vector) ...@@ -506,6 +504,8 @@ iosapic_reassign_vector (int vector)
if (!list_empty(&iosapic_intr_info[vector].rtes)) { if (!list_empty(&iosapic_intr_info[vector].rtes)) {
new_vector = assign_irq_vector(AUTO_ASSIGN); new_vector = assign_irq_vector(AUTO_ASSIGN);
if (new_vector < 0)
panic("%s: out of interrupt vectors!\n", __FUNCTION__);
printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
sizeof(struct iosapic_intr_info)); sizeof(struct iosapic_intr_info));
...@@ -734,9 +734,12 @@ again: ...@@ -734,9 +734,12 @@ again:
spin_unlock_irqrestore(&iosapic_lock, flags); spin_unlock_irqrestore(&iosapic_lock, flags);
/* If vector is running out, we try to find a sharable vector */ /* If vector is running out, we try to find a sharable vector */
vector = assign_irq_vector_nopanic(AUTO_ASSIGN); vector = assign_irq_vector(AUTO_ASSIGN);
if (vector < 0) if (vector < 0) {
vector = iosapic_find_sharable_vector(trigger, polarity); vector = iosapic_find_sharable_vector(trigger, polarity);
if (vector < 0)
panic("%s: out of interrupt vectors!\n", __FUNCTION__);
}
spin_lock_irqsave(&irq_descp(vector)->lock, flags); spin_lock_irqsave(&irq_descp(vector)->lock, flags);
spin_lock(&iosapic_lock); spin_lock(&iosapic_lock);
...@@ -884,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, ...@@ -884,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
break; break;
case ACPI_INTERRUPT_INIT: case ACPI_INTERRUPT_INIT:
vector = assign_irq_vector(AUTO_ASSIGN); vector = assign_irq_vector(AUTO_ASSIGN);
if (vector < 0)
panic("%s: out of interrupt vectors!\n", __FUNCTION__);
delivery = IOSAPIC_INIT; delivery = IOSAPIC_INIT;
break; break;
case ACPI_INTERRUPT_CPEI: case ACPI_INTERRUPT_CPEI:
......
...@@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map); ...@@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map);
static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
int int
assign_irq_vector_nopanic (int irq) assign_irq_vector (int irq)
{ {
int pos, vector; int pos, vector;
again: again:
pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS); pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
vector = IA64_FIRST_DEVICE_VECTOR + pos; vector = IA64_FIRST_DEVICE_VECTOR + pos;
if (vector > IA64_LAST_DEVICE_VECTOR) if (vector > IA64_LAST_DEVICE_VECTOR)
return -1; return -ENOSPC;
if (test_and_set_bit(pos, ia64_vector_mask)) if (test_and_set_bit(pos, ia64_vector_mask))
goto again; goto again;
return vector; return vector;
} }
int
assign_irq_vector (int irq)
{
int vector = assign_irq_vector_nopanic(irq);
if (vector < 0)
panic("assign_irq_vector: out of interrupt vectors!");
return vector;
}
void void
free_irq_vector (int vector) free_irq_vector (int vector)
{ {
......
...@@ -81,7 +81,6 @@ extern __u8 isa_irq_to_vector_map[16]; ...@@ -81,7 +81,6 @@ extern __u8 isa_irq_to_vector_map[16];
extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */ extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */
extern int assign_irq_vector_nopanic (int irq); /* allocate a free vector without panic */
extern int assign_irq_vector (int irq); /* allocate a free vector */ extern int assign_irq_vector (int irq); /* allocate a free vector */
extern void free_irq_vector (int vector); extern void free_irq_vector (int vector);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment