[IA64] assign_irq_vector() should not panic
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Mon, 11 Jul 2005 04:49:00 +0000 (21:49 -0700)
committerTony Luck <tony.luck@intel.com>
Mon, 11 Jul 2005 17:30:07 +0000 (10:30 -0700)
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: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
arch/ia64/hp/sim/simeth.c
arch/ia64/hp/sim/simserial.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq_ia64.c
include/asm-ia64/hw_irq.h

index ae84a1018a89a3d24f400fe4943d6bc7ffc28e88..0639ec0ed015cb57d66c6b5526203c2ee47cf699 100644 (file)
@@ -191,7 +191,7 @@ simeth_probe1(void)
        unsigned char mac_addr[ETH_ALEN];
        struct simeth_local *local;
        struct net_device *dev;
-       int fd, i, err;
+       int fd, i, err, rc;
 
        /*
         * XXX Fix me
@@ -228,7 +228,9 @@ simeth_probe1(void)
                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
index 7a8ae0f4b3876f0c888752e2959ccd1e36e23cb1..7dcb8582ae0d6c0b5cc8384485034585899b7a57 100644 (file)
@@ -982,7 +982,7 @@ static struct tty_operations hp_ops = {
 static int __init
 simrs_init (void)
 {
-       int                     i;
+       int                     i, rc;
        struct serial_state     *state;
 
        if (!ia64_platform_is("hpsim"))
@@ -1017,7 +1017,10 @@ simrs_init (void)
                if (state->type == PORT_UNKNOWN) continue;
 
                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);
                }
 
index c170be095ccdcd56ea16aa0b3cfd087c949a26df..7936b62f7a2e323a0f1d5d4ee4c46a2894bf5682 100644 (file)
@@ -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;
 }
@@ -506,6 +504,8 @@ iosapic_reassign_vector (int vector)
 
        if (!list_empty(&iosapic_intr_info[vector].rtes)) {
                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);
                memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
                       sizeof(struct iosapic_intr_info));
@@ -734,9 +734,12 @@ again:
        spin_unlock_irqrestore(&iosapic_lock, flags);
 
        /* If vector is running out, we try to find a sharable vector */
-       vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
-       if (vector < 0)
+       vector = assign_irq_vector(AUTO_ASSIGN);
+       if (vector < 0) {
                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(&iosapic_lock);
@@ -884,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
                break;
              case ACPI_INTERRUPT_INIT:
                vector = assign_irq_vector(AUTO_ASSIGN);
+               if (vector < 0)
+                       panic("%s: out of interrupt vectors!\n", __FUNCTION__);
                delivery = IOSAPIC_INIT;
                break;
              case ACPI_INTERRUPT_CPEI:
index 4fe60c7a2e9069e5220a46de3aa9d3d340071a2f..6c4d59fd03641dbd6ec0543f0f00095e844b7a6b 100644 (file)
@@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map);
 static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
 
 int
-assign_irq_vector_nopanic (int irq)
+assign_irq_vector (int irq)
 {
        int pos, vector;
  again:
        pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
        vector = IA64_FIRST_DEVICE_VECTOR + pos;
        if (vector > IA64_LAST_DEVICE_VECTOR)
-               return -1;
+               return -ENOSPC;
        if (test_and_set_bit(pos, ia64_vector_mask))
                goto again;
        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
 free_irq_vector (int vector)
 {
index cd4e06b74ab6a6f9061fc34e3844148bd45660e3..041ab8c51a6409469c1e40e3652814ac666f9817 100644 (file)
@@ -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 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 void free_irq_vector (int vector);
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);