mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 3/3] cciss: per disk queue support
@ 2005-03-09 22:28 mike.miller
  0 siblings, 0 replies; only message in thread
From: mike.miller @ 2005-03-09 22:28 UTC (permalink / raw)
  To: akpm, axboe; +Cc: linux-kernel, linux-scsi

This patch adds per disk queue functionality. It seems that the 2.6 kernel expects a queue per disk. If you have multiple logical drives on a controller all of the queues actually point back to the same queue. If a drive is deleted it blows us out of the water.
We hold the lock during any queue operations and have added what we call a
"fair-enough" algorithm to prevent starving out any drive.

Please consider this for inclusion.

Signed-off-by: Mike Miller <mike.miller@hp.com>

 cciss.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++----
 cciss.h |    5 +++++
 2 files changed, 53 insertions(+), 4 deletions(-)
----------------------------------------------------------------------------
diff -burNp lx2611-p002/drivers/block/cciss.c lx2611-p003/drivers/block/cciss.c
--- lx2611-p002/drivers/block/cciss.c	2005-03-08 16:50:47.149175280 -0600
+++ lx2611-p003/drivers/block/cciss.c	2005-03-08 17:17:50.148441888 -0600
@@ -2090,6 +2090,9 @@ static void do_cciss_request(request_que
 	drive_info_struct *drv;
 	int i, dir;
 
+	/* We call start_io here in case there is a command waiting on the
+	 * queue that has not been sent.
+	*/
 	if (blk_queue_plugged(q))
 		goto startio;
 
@@ -2178,6 +2181,9 @@ queue:
 full:
 	blk_stop_queue(q);
 startio:
+	/* We will already have the driver lock here so not need
+	 * to lock it.
+	*/
 	start_io(h);
 }
 
@@ -2187,7 +2193,8 @@ static irqreturn_t do_cciss_intr(int irq
 	CommandList_struct *c;
 	unsigned long flags;
 	__u32 a, a1;
-
+	int j;
+	int start_queue = h->next_to_run;
 
 	/* Is this interrupt for us? */
 	if (( h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0))
@@ -2234,13 +2241,50 @@ static irqreturn_t do_cciss_intr(int irq
 		}
 	}
 
-	/*
-	 * See if we can queue up some more IO
+ 	/* check to see if we have maxed out the number of commands that can
+ 	 * be placed on the queue.  If so then exit.  We do this check here
+ 	 * in case the interrupt we serviced was from an ioctl and did not
+ 	 * free any new commands.
 	 */
-	blk_start_queue(h->queue);
+ 	if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
+ 		goto cleanup;
+ 
+ 	/* We have room on the queue for more commands.  Now we need to queue
+ 	 * them up.  We will also keep track of the next queue to run so
+ 	 * that every queue gets a chance to be started first.
+ 	*/
+ 	for (j=0; j < NWD; j++){
+ 		int curr_queue = (start_queue + j) % NWD;
+ 		/* 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[curr_queue]->queue) || 
+		 		   !(h->drv[curr_queue].heads))
+ 			continue;
+ 		blk_start_queue(h->gendisk[curr_queue]->queue);
+ 
+ 		/* check to see if we have maxed out the number of commands 
+ 		 * that can be placed on the queue.  
+ 		*/
+ 		if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
+ 		{
+ 			if (curr_queue == start_queue){
+ 				h->next_to_run = (start_queue + 1) % NWD;
+ 				goto cleanup;
+ 			} else {
+ 				h->next_to_run = curr_queue;
+ 				goto cleanup;
+ 	}
+ 		} else {
+ 			curr_queue = (curr_queue + 1) % NWD;
+ 		}
+ 	}
+ 
+cleanup:
 	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 	return IRQ_HANDLED;
 }
+
 /* 
  *  We cannot read the structure directly, for portablity we must use 
  *   the io functions.
Files lx2611-p002/drivers/block/.cciss.c.rej.swp and lx2611-p003/drivers/block/.cciss.c.rej.swp differ
diff -burNp lx2611-p002/drivers/block/cciss.h lx2611-p003/drivers/block/cciss.h
--- lx2611-p002/drivers/block/cciss.h	2005-03-08 16:50:47.150175128 -0600
+++ lx2611-p003/drivers/block/cciss.h	2005-03-08 17:03:04.279114496 -0600
@@ -84,6 +84,11 @@ struct ctlr_info 
 	int			nr_frees; 
 	int			busy_configuring;
 
+	/* This element holds the zero based queue number of the last
+	 * queue to be started.  It is used for fairness.
+	*/
+	int			next_to_run;
+
 	// Disk structures we need to pass back
 	struct gendisk   *gendisk[NWD];
 #ifdef CONFIG_CISS_SCSI_TAPE

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-03-09 23:05 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-09 22:28 [PATCH 3/3] cciss: per disk queue support mike.miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®