]> git.neil.brown.name Git - history.git/commitdiff
fix queue run on returning I/O [axboe@suse.de]
authorJames Bottomley <jejb@mulgrave.(none)>
Tue, 19 Nov 2002 13:13:45 +0000 (07:13 -0600)
committerChristoph Hellwig <hch@lst.de>
Tue, 19 Nov 2002 13:13:45 +0000 (07:13 -0600)
On returning I/O, need to unplug the queue before we call the queue_fn.
This fixes a problem in 2.5.48 where the aic7xxx driver hangs under e2fsck.

drivers/block/ll_rw_blk.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
include/linux/blkdev.h

index 4e709cfffd67887ac75232e906e9f2d742199a39..336f0eb49cd83a13495bba5e92e928e05705e62f 100644 (file)
@@ -1037,6 +1037,16 @@ void blk_stop_queue(request_queue_t *q)
        spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
+/**
+ * blk_run_queue - run a single device queue
+ * @q  The queue to run
+ */
+void __blk_run_queue(request_queue_t *q)
+{
+       blk_remove_plug(q);
+       q->request_fn(q);
+}
+
 /**
  * blk_run_queues - fire all plugged queues
  *
@@ -2198,4 +2208,5 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags);
 EXPORT_SYMBOL(blk_start_queue);
 EXPORT_SYMBOL(blk_stop_queue);
 EXPORT_SYMBOL(__blk_stop_queue);
+EXPORT_SYMBOL(__blk_run_queue);
 EXPORT_SYMBOL(blk_run_queues);
index 88ca4b30877490fb4ef6d50df657c195856cbbbe..510a53260bc0578f9df0edc8a6a1bff078cdcfe9 100644 (file)
@@ -1479,8 +1479,6 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
         */
        spin_lock_irqsave(shost->host_lock, flags);
        for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
-               request_queue_t *q = &sdev->request_queue;
-
                if ((shost->can_queue > 0 &&
                     (shost->host_busy >= shost->can_queue))
                    || (shost->host_blocked)
@@ -1488,7 +1486,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
                        break;
                }
 
-               q->request_fn(q);
+               __blk_run_queue(&sdev->request_queue);
        }
        spin_unlock_irqrestore(shost->host_lock, flags);
 }
index 2098d8766e95d605bfd97924075079654ac6927f..7d4ef17f3cc2b16ddd3cc09feb802d5d4f55defb 100644 (file)
@@ -227,7 +227,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
        /*
         * Just hit the requeue function for the queue.
         */
-       q->request_fn(q);
+       __blk_run_queue(q);
 
        SDpnt = (Scsi_Device *) q->queuedata;
        SHpnt = SDpnt->host;
@@ -240,8 +240,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
         * use function pointers to pick the right one.
         */
        if (SDpnt->single_lun && blk_queue_empty(q) && SDpnt->device_busy ==0) {
-               request_queue_t *q;
-
                for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
                        if (((SHpnt->can_queue > 0)
                             && (SHpnt->host_busy >= SHpnt->can_queue))
@@ -251,8 +249,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
                                break;
                        }
 
-                       q = &SDpnt->request_queue;
-                       q->request_fn(q);
+                       __blk_run_queue(&SDpnt->request_queue);
                }
        }
 
@@ -267,7 +264,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
        all_clear = 1;
        if (SHpnt->some_device_starved) {
                for (SDpnt = SHpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
-                       request_queue_t *q;
                        if ((SHpnt->can_queue > 0 && (SHpnt->host_busy >= SHpnt->can_queue))
                            || (SHpnt->host_blocked) 
                            || (SHpnt->host_self_blocked)) {
@@ -276,8 +272,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
                        if (SDpnt->device_blocked || !SDpnt->starved) {
                                continue;
                        }
-                       q = &SDpnt->request_queue;
-                       q->request_fn(q);
+                       __blk_run_queue(&SDpnt->request_queue);
                        all_clear = 0;
                }
                if (SDpnt == NULL && all_clear) {
index d9b416ebc9665b14e265dfc23dfb1075f6010b4b..6730edd230e008aac71687c2a4f6d7315e2583d6 100644 (file)
@@ -321,6 +321,7 @@ extern int scsi_cmd_ioctl(struct block_device *, unsigned int, unsigned long);
 extern void blk_start_queue(request_queue_t *q);
 extern void blk_stop_queue(request_queue_t *q);
 extern void __blk_stop_queue(request_queue_t *q);
+extern void __blk_run_queue(request_queue_t *q);
 
 static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
 {