diff options
| author | Jens Axboe <axboe@suse.de> | 2002-05-28 05:39:17 -0700 |
|---|---|---|
| committer | Jens Axboe <axboe@suse.de> | 2002-05-28 05:39:17 -0700 |
| commit | eba5b46c3c8002cf528a0472b70356d77438ca98 (patch) | |
| tree | c053b6a6e69830a23230d966d4f1e8f90cadc851 /drivers/block/cpqarray.c | |
| parent | c43626f4822b7c6183fa864b53d3b39c2180cdae (diff) | |
[PATCH] block plugging reworked
This patch provides the ability for a block driver to signal it's too
busy to receive more work and temporarily halt the request queue. In
concept it's similar to the networking netif_{start,stop}_queue helpers.
To do this cleanly, I've ripped out the old tq_disk task queue. Instead
an internal list of plugged queues is maintained which will honor the
current queue state (see QUEUE_FLAG_STOPPED bit). Execution of
request_fn has been moved to tasklet context. blk_run_queues() provides
similar functionality to the old run_task_queue(&tq_disk).
Now, this only works at the request_fn level and not at the
make_request_fn level. This is on purpose: drivers working at the
make_request_fn level are essentially providing a piece of the block
level infrastructure themselves. There are basically two reasons for
doing make_request_fn style setups:
o block remappers. start/stop functionality will be done at the target
device in this case, which is the level that will signal hardware full
(or continue) anyways.
o drivers who wish to receive single entities of "buffers" and not
merged requests etc. This could use the start/stop functionality. I'd
suggest _still_ using a request_fn for these, but set the queue
options so that no merging etc ever takes place. This has the added
bonus of providing the usual request depletion throttling at the block
level.
Diffstat (limited to 'drivers/block/cpqarray.c')
| -rw-r--r-- | drivers/block/cpqarray.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 593bb0ca3796..c826dcb71ef4 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -166,7 +166,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, static void ida_geninit(int ctlr) { - int i,j; + int i; drv_info_t *drv; for(i=0; i<NWD; i++) { @@ -409,8 +409,7 @@ int __init cpqarray_init(void) hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = (__u32*)kmalloc( - ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL); + hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL) { @@ -441,7 +440,7 @@ int __init cpqarray_init(void) } memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32)); + memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long)); printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname); getgeometry(i); @@ -916,6 +915,7 @@ DBGPX( printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); goto queue_next; startio: + blk_stop_queue(q); start_io(h); } @@ -1066,8 +1066,8 @@ static void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs) /* * See if we can queue up some more IO */ - do_ida_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr)); spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); + blk_start_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr)); } /* @@ -1333,7 +1333,7 @@ static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool) i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); if (i == NR_CMDS) return NULL; - } while(test_and_set_bit(i%32, h->cmd_pool_bits+(i/32)) != 0); + } while(test_and_set_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG)) != 0); c = h->cmd_pool + i; cmd_dhandle = h->cmd_pool_dhandle + i*sizeof(cmdlist_t); h->nr_allocs++; @@ -1353,7 +1353,7 @@ static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool) c->busaddr); } else { i = c - h->cmd_pool; - clear_bit(i%32, h->cmd_pool_bits+(i/32)); + clear_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG)); h->nr_frees++; } } |
