Skip to contentSkip to conversation

2.4.16: SCSI concurrent queueing

PATCH New Jonathan Lahr 1 participant 1 message Dec 6, 2001

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 2.4.16: SCSI concurrent queueing

Hello All,

Included is the latest SCSI io_request_lock patch, siorl-v1.2416. It can also be downloaded from http://sourceforge.net/projects/lse/.
This version further reduces code impact, further separates SCSI i/o from generic block i/o functions, and fixes some bugs. Thanks to Jens for comments on the previous patch.

In scsi_make_request, I removed references to ll_*merge*_fn, since initialize_merge_fn sets SCSI merge functions. I also removed head_active code, since SCSI always operates with head_active == 0.

Unlike previous iorl patches, this patch releases locks before calling scsi_dispatch_cmd, so baseline scsi_dispatch_cmd remains unchanged.

I also fixed some queue locking problems siorl-v0 had introduced into scsi_queue_next_request.

To summarize, this patch does the following:

- Creates scsi_plug_device, scsi_unplug_device, scsi_get_request, scsi_make_request, and scsi_init_queue based on the generic versions modified for concurrent queueing

- Modifies scsi_request_fn, scsi_unplug_device, scsi_get_request_wait, __scsi_insert_special, and scsi_queue_next_request for concurrent queueing

- Adds concurrent queue field to request_queue and Scsi_Host_Template

- Creates rq_lock macros to conditionally switch locking schemes

- Exports batch_requests, get_max_sectors, blk_init_free_list, attempt_back_merge, and attempt_front_merge symbols for use by SCSI code

- Moves blkdev_free_rq definition to blkdev.h so SCSI functions can use it

I have tested this with aic7xxx, lpfc, and IDE disks and CDROM.

Comments, testing results, performance measurements?

Jonathan

--
Jonathan Lahr
IBM Linux Technology Center
Beaverton, Oregon
[email protected]
503-578-3385

---------------------- siorl-v1.2416 patch ----------------------

include/linux/blkdev.h +17 -0
@@ -122,6 +122,8 @@
 	 * Tasks wait here for free request
 	 */
 	wait_queue_head_t	wait_for_request;
+
+	unsigned concurrent:1;
 };
 
 struct blk_dev_struct {
@@ -185,6 +187,7 @@
 #define blkdev_entry_prev_request(entry) blkdev_entry_to_request((entry)->prev)
 #define blkdev_next_request(req) blkdev_entry_to_request((req)->queue.next)
 #define blkdev_prev_request(req) blkdev_entry_to_request((req)->queue.prev)
+#define blkdev_free_rq(list) list_entry((list)->next, struct request, queue);
 
 extern void drive_stat_acct (kdev_t dev, int rw,
 					unsigned long nr_sectors, int new_io);
@@ -204,6 +207,20 @@
 
 #define blk_finished_io(nsects)	do { } while (0)
 #define blk_started_io(nsects)	do { } while (0)
+
+#define xrq_lock_irq(q)						\
+	{if (q->concurrent) spin_lock_irq(&q->queue_lock);	\
+		else spin_lock_irq(&io_request_lock);}
+
+#define xrq_unlock_irq(q)					\
+	{if (q->concurrent) spin_unlock_irq(&q->queue_lock);	\
+		else spin_unlock_irq(&io_request_lock);}
+
+#define rq_lock(q)						\
+	{if (q->concurrent) spin_lock(&q->queue_lock);}
+
+#define rq_unlock(q)						\
+	{if (q->concurrent) spin_unlock(&q->queue_lock);}
 
 static inline unsigned int blksize_bits(unsigned int size)
 {
drivers/block/ll_rw_blk.c +6 -6
@@ -121,9 +121,10 @@
  * How many reqeusts do we allocate per queue,
  * and how many do we "batch" on freeing them?
  */
-static int queue_nr_requests, batch_requests;
+static int queue_nr_requests;
+int batch_requests;
 
-static inline int get_max_sectors(kdev_t dev)
+inline int get_max_sectors(kdev_t dev)
 {
 	if (!max_sectors[MAJOR(dev)])
 		return MAX_SECTORS;
@@ -326,7 +327,7 @@
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
-static void blk_init_free_list(request_queue_t *q)
+void blk_init_free_list(request_queue_t *q)
 {
 	struct request *rq;
 	int i;
@@ -415,7 +416,6 @@
 	q->head_active    	= 1;
 }
 
-#define blkdev_free_rq(list) list_entry((list)->next, struct request, queue);
 /*
  * Get a free request. io_request_lock must be held and interrupts
  * disabled on the way in.
@@ -600,7 +600,7 @@
 	blkdev_release_request(next);
 }
 
-static inline void attempt_back_merge(request_queue_t * q,
+inline void attempt_back_merge(request_queue_t * q,
 				      struct request *req,
 				      int max_sectors,
 				      int max_segments)
@@ -610,7 +610,7 @@
 	attempt_merge(q, req, max_sectors, max_segments);
 }
 
-static inline void attempt_front_merge(request_queue_t * q,
+inline void attempt_front_merge(request_queue_t * q,
 				       struct list_head * head,
 				       struct request *req,
 				       int max_sectors,
drivers/scsi/hosts.h +2 -0
@@ -296,6 +296,8 @@
      */
     char *proc_name;
 
+    unsigned concurrent_queue:1;
+
 } Scsi_Host_Template;
 
 /*
drivers/scsi/scsi.c +1 -2
@@ -187,8 +187,7 @@
  *              to do the dirty deed.
  */
 void  scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) {
-	blk_init_queue(&SDpnt->request_queue, scsi_request_fn);
-        blk_queue_headactive(&SDpnt->request_queue, 0);
+	scsi_init_queue(&SDpnt->request_queue, SHpnt->hostt->concurrent_queue);
         SDpnt->request_queue.queuedata = (void *) SDpnt;
 }
 
drivers/scsi/scsi_lib.c +264 -9

355 lines not on this page · raw message