RE: cciss per device queue patch for 2.6.4

From: Miller, Mike (OS Dev)
Date: Mon Mar 08 2004 - 15:39:35 EST


Thanks, Jens. I'll fix it & resubmit.

-----Original Message-----
From: Jens Axboe [mailto:axboe@xxxxxxx]
Sent: Monday, March 08, 2004 1:46 PM
To: Miller, Mike (OS Dev)
Cc: apkm@xxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx
Subject: Re: cciss per device queue patch for 2.6.4


On Mon, Mar 08 2004, mikem@xxxxxxxxxxxxxxxxxxxxxxx wrote:
> /*
> * See if we can queue up some more IO
> + * check every disk that exists on this controller
> + * and start it's IO
> */
> - blk_start_queue(h->queue);
> + for(j=0;j < NWD; j++) {
> + /* make sure the disk has been added and the drive is real */
> + /* because this can be called from the middle of init_one */
> + if(!(h->gendisk[j]->queue) || !(h->drv[j].nr_blocks) )
> + continue;
> + blk_start_queue(h->gendisk[j]->queue);
> + }
> spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
> return IRQ_HANDLED;

You can't do this, you must hold the specific queue lock for calling
blk_start_queue() for it. The comment for that functions states that,
too. It's even more important now that blk_start_queue() actually works
properly (included).

===== drivers/block/ll_rw_blk.c 1.228 vs edited =====
--- 1.228/drivers/block/ll_rw_blk.c Sun Feb 1 19:09:12 2004
+++ edited/drivers/block/ll_rw_blk.c Mon Mar 8 20:41:21 2004
@@ -1188,13 +1193,23 @@
* Description:
* blk_start_queue() will clear the stop flag on the queue, and call
* the request_fn for the queue if it was in a stopped state when
- * entered. Also see blk_stop_queue(). Must not be called from driver
- * request function due to recursion issues. Queue lock must be held.
+ * entered. Also see blk_stop_queue(). Queue lock must be held.
**/
void blk_start_queue(request_queue_t *q)
{
clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
- schedule_work(&q->unplug_work);
+
+ /*
+ * one level of recursion is ok and is much faster than kicking
+ * the unplug handling
+ */
+ if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
+ q->request_fn(q);
+ clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
+ } else {
+ blk_plug_device(q);
+ schedule_work(&q->unplug_work);
+ }
}

EXPORT_SYMBOL(blk_start_queue);


--
Jens Axboe

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