[patch] block/IDE/interrupt lockup

From: Andrew Morton (akpm@zip.com.au)
Date: Sat Mar 30 2002 - 00:45:24 EST


Marcelo,

my blk_grow_request_list() patch in -pre5 is buggy. It
can cause boot-time lockups. The window is fairly small,
but I just hit it.

drivers/ide/ide-probe.c:init_irq() does cli().
It calls down to blk_init_free_list() and
blk_grow_request_list().

blk_grow_request_list() does spin_unlock_irq(). Which
is illegal inside cli(). An interrupt comes in and
the CPU locks up in irq_enter(), spinning on global_irq_lock,
which this CPU already holds.

Below is the patch. (That's the last spin_lock_irq()
anyone will be seeing from me :))

Andre, init_irq() is somewhat broken - it appears to
be assuming that cli() will disable interrupts, but it's
calling functions which can sleep. If these functions
_do_ sleep, interrupts will be enabled, which is presumably
not what IDE wants to happen.

--- 2.4.19-pre5/drivers/block/ll_rw_blk.c~ide-lockup Fri Mar 29 21:19:11 2002
+++ 2.4.19-pre5-akpm/drivers/block/ll_rw_blk.c Fri Mar 29 21:20:04 2002
@@ -336,14 +336,16 @@ void generic_unplug_device(void *data)
  */
 int blk_grow_request_list(request_queue_t *q, int nr_requests)
 {
- spin_lock_irq(&io_request_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock, flags);
         while (q->nr_requests < nr_requests) {
                 struct request *rq;
                 int rw;
 
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irqrestore(&io_request_lock, flags);
                 rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
- spin_lock_irq(&io_request_lock);
+ spin_lock_irqsave(&io_request_lock, flags);
                 if (rq == NULL)
                         break;
                 memset(rq, 0, sizeof(*rq));
@@ -356,7 +358,7 @@ int blk_grow_request_list(request_queue_
         q->batch_requests = q->nr_requests / 4;
         if (q->batch_requests > 32)
                 q->batch_requests = 32;
- spin_unlock_irq(&io_request_lock);
+ spin_unlock_irqrestore(&io_request_lock, flags);
         return q->nr_requests;
 }
 

-
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Mar 31 2002 - 22:00:19 EST