2.4.16: SCSI concurrent queueing
Subsystems (2)
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