Commit 9c2c68b8 authored by Linus Torvalds's avatar Linus Torvalds

Merge home.transmeta.com:/home/torvalds/v2.5/blk-plug

into home.transmeta.com:/home/torvalds/v2.5/linux
parents b8391722 eba5b46c
...@@ -281,7 +281,7 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool) ...@@ -281,7 +281,7 @@ static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
if (i == NR_CMDS) if (i == NR_CMDS)
return NULL; return NULL;
} while(test_and_set_bit(i & 31, 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);
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk(KERN_DEBUG "cciss: using command buffer %d\n", i); printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
#endif #endif
...@@ -327,7 +327,7 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) ...@@ -327,7 +327,7 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
} else } else
{ {
i = c - h->cmd_pool; 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++; h->nr_frees++;
} }
} }
...@@ -338,7 +338,7 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) ...@@ -338,7 +338,7 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
static void cciss_geninit( int ctlr) static void cciss_geninit( int ctlr)
{ {
drive_info_struct *drv; drive_info_struct *drv;
int i,j; int i;
/* Loop through each real device */ /* Loop through each real device */
hba[ctlr]->gendisk.nr_real = 0; hba[ctlr]->gendisk.nr_real = 0;
...@@ -1883,6 +1883,7 @@ static void do_cciss_request(request_queue_t *q) ...@@ -1883,6 +1883,7 @@ static void do_cciss_request(request_queue_t *q)
goto queue; goto queue;
startio: startio:
blk_stop_queue(q);
start_io(h); start_io(h);
} }
...@@ -1943,8 +1944,8 @@ static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1943,8 +1944,8 @@ static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
/* /*
* See if we can queue up some more IO * See if we can queue up some more IO
*/ */
do_cciss_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr));
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
blk_start_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr));
} }
/* /*
* We cannot read the structure directly, for portablity we must use * We cannot read the structure directly, for portablity we must use
...@@ -2448,8 +2449,7 @@ static int __init cciss_init_one(struct pci_dev *pdev, ...@@ -2448,8 +2449,7 @@ static int __init cciss_init_one(struct pci_dev *pdev,
free_hba(i); free_hba(i);
return(-1); return(-1);
} }
hba[i]->cmd_pool_bits = (__u32*)kmalloc( hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent( hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent(
hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
&(hba[i]->cmd_pool_dhandle)); &(hba[i]->cmd_pool_dhandle));
...@@ -2484,7 +2484,7 @@ static int __init cciss_init_one(struct pci_dev *pdev, ...@@ -2484,7 +2484,7 @@ static int __init cciss_init_one(struct pci_dev *pdev,
pci_set_drvdata(pdev, hba[i]); pci_set_drvdata(pdev, hba[i]);
/* command and error info recs zeroed out before /* command and error info recs zeroed out before
they are used */ they are used */
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));
#ifdef CCISS_DEBUG #ifdef CCISS_DEBUG
printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i); printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i);
......
...@@ -76,7 +76,7 @@ struct ctlr_info ...@@ -76,7 +76,7 @@ struct ctlr_info
dma_addr_t cmd_pool_dhandle; dma_addr_t cmd_pool_dhandle;
ErrorInfo_struct *errinfo_pool; ErrorInfo_struct *errinfo_pool;
dma_addr_t errinfo_pool_dhandle; dma_addr_t errinfo_pool_dhandle;
__u32 *cmd_pool_bits; unsigned long *cmd_pool_bits;
int nr_allocs; int nr_allocs;
int nr_frees; int nr_frees;
......
...@@ -166,7 +166,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, ...@@ -166,7 +166,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset,
static void ida_geninit(int ctlr) static void ida_geninit(int ctlr)
{ {
int i,j; int i;
drv_info_t *drv; drv_info_t *drv;
for(i=0; i<NWD; i++) { for(i=0; i<NWD; i++) {
...@@ -409,8 +409,7 @@ int __init cpqarray_init(void) ...@@ -409,8 +409,7 @@ int __init cpqarray_init(void)
hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent( hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
&(hba[i]->cmd_pool_dhandle)); &(hba[i]->cmd_pool_dhandle));
hba[i]->cmd_pool_bits = (__u32*)kmalloc( hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL) if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
{ {
...@@ -441,7 +440,7 @@ int __init cpqarray_init(void) ...@@ -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, 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", printk(KERN_INFO "cpqarray: Finding drives on %s",
hba[i]->devname); hba[i]->devname);
getgeometry(i); getgeometry(i);
...@@ -916,6 +915,7 @@ DBGPX( printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg); ...@@ -916,6 +915,7 @@ DBGPX( printk("Submitting %d sectors in %d segments\n", creq->nr_sectors, seg);
goto queue_next; goto queue_next;
startio: startio:
blk_stop_queue(q);
start_io(h); start_io(h);
} }
...@@ -1066,8 +1066,8 @@ static void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -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 * 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); 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) ...@@ -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); i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
if (i == NR_CMDS) if (i == NR_CMDS)
return NULL; 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; c = h->cmd_pool + i;
cmd_dhandle = h->cmd_pool_dhandle + i*sizeof(cmdlist_t); cmd_dhandle = h->cmd_pool_dhandle + i*sizeof(cmdlist_t);
h->nr_allocs++; h->nr_allocs++;
...@@ -1353,7 +1353,7 @@ static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool) ...@@ -1353,7 +1353,7 @@ static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool)
c->busaddr); c->busaddr);
} else { } else {
i = c - h->cmd_pool; 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++; h->nr_frees++;
} }
} }
......
...@@ -104,7 +104,7 @@ struct ctlr_info { ...@@ -104,7 +104,7 @@ struct ctlr_info {
cmdlist_t *cmpQ; cmdlist_t *cmpQ;
cmdlist_t *cmd_pool; cmdlist_t *cmd_pool;
dma_addr_t cmd_pool_dhandle; dma_addr_t cmd_pool_dhandle;
__u32 *cmd_pool_bits; unsigned long *cmd_pool_bits;
spinlock_t lock; spinlock_t lock;
unsigned int Qdepth; unsigned int Qdepth;
......
...@@ -3894,7 +3894,7 @@ static int __floppy_read_block_0(struct block_device *bdev) ...@@ -3894,7 +3894,7 @@ static int __floppy_read_block_0(struct block_device *bdev)
bio.bi_end_io = floppy_rb0_complete; bio.bi_end_io = floppy_rb0_complete;
submit_bio(READ, &bio); submit_bio(READ, &bio);
run_task_queue(&tq_disk); generic_unplug_device(bdev_get_queue(bdev));
process_fd_request(); process_fd_request();
wait_for_completion(&complete); wait_for_completion(&complete);
......
...@@ -49,6 +49,9 @@ extern int mac_floppy_init(void); ...@@ -49,6 +49,9 @@ extern int mac_floppy_init(void);
*/ */
static kmem_cache_t *request_cachep; static kmem_cache_t *request_cachep;
static struct list_head blk_plug_list;
static spinlock_t blk_plug_lock = SPIN_LOCK_UNLOCKED;
/* /*
* The "disk" task queue is used to start the actual requests * The "disk" task queue is used to start the actual requests
* after a plug * after a plug
...@@ -791,8 +794,12 @@ void blk_plug_device(request_queue_t *q) ...@@ -791,8 +794,12 @@ void blk_plug_device(request_queue_t *q)
if (!elv_queue_empty(q)) if (!elv_queue_empty(q))
return; return;
if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) if (test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
queue_task(&q->plug_tq, &tq_disk); return;
spin_lock(&blk_plug_lock);
list_add_tail(&q->plug.list, &blk_plug_list);
spin_unlock(&blk_plug_lock);
} }
/* /*
...@@ -803,8 +810,13 @@ static inline void __generic_unplug_device(request_queue_t *q) ...@@ -803,8 +810,13 @@ static inline void __generic_unplug_device(request_queue_t *q)
/* /*
* not plugged * not plugged
*/ */
if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) if (!__test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
return;
if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) {
printk("queue was stopped\n");
return; return;
}
/* /*
* was plugged, fire request_fn if queue has stuff to do * was plugged, fire request_fn if queue has stuff to do
...@@ -815,7 +827,7 @@ static inline void __generic_unplug_device(request_queue_t *q) ...@@ -815,7 +827,7 @@ static inline void __generic_unplug_device(request_queue_t *q)
/** /**
* generic_unplug_device - fire a request queue * generic_unplug_device - fire a request queue
* @q: The &request_queue_t in question * @data: The &request_queue_t in question
* *
* Description: * Description:
* Linux uses plugging to build bigger requests queues before letting * Linux uses plugging to build bigger requests queues before letting
...@@ -826,6 +838,16 @@ static inline void __generic_unplug_device(request_queue_t *q) ...@@ -826,6 +838,16 @@ static inline void __generic_unplug_device(request_queue_t *q)
* queue is invoked and transfers started. * queue is invoked and transfers started.
**/ **/
void generic_unplug_device(void *data) void generic_unplug_device(void *data)
{
request_queue_t *q = data;
tasklet_schedule(&q->plug.task);
}
/*
* the plug tasklet
*/
static void blk_task_run(unsigned long data)
{ {
request_queue_t *q = (request_queue_t *) data; request_queue_t *q = (request_queue_t *) data;
unsigned long flags; unsigned long flags;
...@@ -835,6 +857,49 @@ void generic_unplug_device(void *data) ...@@ -835,6 +857,49 @@ void generic_unplug_device(void *data)
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} }
/*
* clear top flag and schedule tasklet for execution
*/
void blk_start_queue(request_queue_t *q)
{
if (test_and_clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
tasklet_enable(&q->plug.task);
tasklet_schedule(&q->plug.task);
}
/*
* set stop bit and disable any pending tasklet
*/
void blk_stop_queue(request_queue_t *q)
{
if (!test_and_set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
tasklet_disable(&q->plug.task);
}
/*
* the equivalent of the previous tq_disk run
*/
void blk_run_queues(void)
{
struct list_head *tmp, *n;
unsigned long flags;
/*
* we could splice to the stack prior to running
*/
spin_lock_irqsave(&blk_plug_lock, flags);
list_for_each_safe(tmp, n, &blk_plug_list) {
request_queue_t *q = list_entry(tmp, request_queue_t,plug.list);
if (!test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) {
list_del(&q->plug.list);
tasklet_schedule(&q->plug.task);
}
}
spin_unlock_irqrestore(&blk_plug_lock, flags);
}
static int __blk_cleanup_queue(struct request_list *list) static int __blk_cleanup_queue(struct request_list *list)
{ {
struct list_head *head = &list->free; struct list_head *head = &list->free;
...@@ -974,9 +1039,6 @@ int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, spinlock_t *lock) ...@@ -974,9 +1039,6 @@ int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, spinlock_t *lock)
q->front_merge_fn = ll_front_merge_fn; q->front_merge_fn = ll_front_merge_fn;
q->merge_requests_fn = ll_merge_requests_fn; q->merge_requests_fn = ll_merge_requests_fn;
q->prep_rq_fn = NULL; q->prep_rq_fn = NULL;
q->plug_tq.sync = 0;
q->plug_tq.routine = &generic_unplug_device;
q->plug_tq.data = q;
q->queue_flags = (1 << QUEUE_FLAG_CLUSTER); q->queue_flags = (1 << QUEUE_FLAG_CLUSTER);
q->queue_lock = lock; q->queue_lock = lock;
...@@ -987,6 +1049,10 @@ int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, spinlock_t *lock) ...@@ -987,6 +1049,10 @@ int blk_init_queue(request_queue_t *q, request_fn_proc *rfn, spinlock_t *lock)
blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
INIT_LIST_HEAD(&q->plug.list);
tasklet_init(&q->plug.task, blk_task_run, (unsigned long) q);
return 0; return 0;
} }
...@@ -1867,6 +1933,8 @@ int __init blk_dev_init(void) ...@@ -1867,6 +1933,8 @@ int __init blk_dev_init(void)
blk_max_low_pfn = max_low_pfn; blk_max_low_pfn = max_low_pfn;
blk_max_pfn = max_pfn; blk_max_pfn = max_pfn;
INIT_LIST_HEAD(&blk_plug_list);
#if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD) #if defined(CONFIG_IDE) && defined(CONFIG_BLK_DEV_HD)
hd_init(); hd_init();
#endif #endif
...@@ -1913,3 +1981,7 @@ EXPORT_SYMBOL(blk_queue_free_tags); ...@@ -1913,3 +1981,7 @@ EXPORT_SYMBOL(blk_queue_free_tags);
EXPORT_SYMBOL(blk_queue_start_tag); EXPORT_SYMBOL(blk_queue_start_tag);
EXPORT_SYMBOL(blk_queue_end_tag); EXPORT_SYMBOL(blk_queue_end_tag);
EXPORT_SYMBOL(blk_queue_invalidate_tags); EXPORT_SYMBOL(blk_queue_invalidate_tags);
EXPORT_SYMBOL(blk_start_queue);
EXPORT_SYMBOL(blk_stop_queue);
EXPORT_SYMBOL(blk_run_queues);
...@@ -252,7 +252,9 @@ static unsigned long smart1_completed(ctlr_info_t *h) ...@@ -252,7 +252,9 @@ static unsigned long smart1_completed(ctlr_info_t *h)
outb(CHANNEL_CLEAR, h->ioaddr + SMART1_LOCAL_DOORBELL); outb(CHANNEL_CLEAR, h->ioaddr + SMART1_LOCAL_DOORBELL);
#error Please convert me to Documentation/DMA-mapping.txt /*
* this is x86 (actually compaq x86) only, so it's ok
*/
if (cmd) ((cmdlist_t*)bus_to_virt(cmd))->req.hdr.rcode = status; if (cmd) ((cmdlist_t*)bus_to_virt(cmd))->req.hdr.rcode = status;
} else { } else {
cmd = 0; cmd = 0;
......
...@@ -491,7 +491,7 @@ static int sync_page_io(struct block_device *bdev, sector_t sector, int size, ...@@ -491,7 +491,7 @@ static int sync_page_io(struct block_device *bdev, sector_t sector, int size,
bio.bi_private = &event; bio.bi_private = &event;
bio.bi_end_io = bi_complete; bio.bi_end_io = bi_complete;
submit_bio(rw, &bio); submit_bio(rw, &bio);
run_task_queue(&tq_disk); blk_run_queues();
wait_for_completion(&event); wait_for_completion(&event);
return test_bit(BIO_UPTODATE, &bio.bi_flags); return test_bit(BIO_UPTODATE, &bio.bi_flags);
...@@ -2955,7 +2955,7 @@ int md_thread(void * arg) ...@@ -2955,7 +2955,7 @@ int md_thread(void * arg)
run = thread->run; run = thread->run;
if (run) { if (run) {
run(thread->data); run(thread->data);
run_task_queue(&tq_disk); blk_run_queues();
} }
if (signal_pending(current)) if (signal_pending(current))
flush_curr_signals(); flush_curr_signals();
...@@ -3411,7 +3411,7 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare) ...@@ -3411,7 +3411,7 @@ int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
last_check = j; last_check = j;
run_task_queue(&tq_disk); blk_run_queues();
repeat: repeat:
if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) { if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
......
...@@ -138,7 +138,7 @@ void __wait_on_buffer(struct buffer_head * bh) ...@@ -138,7 +138,7 @@ void __wait_on_buffer(struct buffer_head * bh)
get_bh(bh); get_bh(bh);
add_wait_queue(wq, &wait); add_wait_queue(wq, &wait);
do { do {
run_task_queue(&tq_disk); blk_run_queues();
set_task_state(tsk, TASK_UNINTERRUPTIBLE); set_task_state(tsk, TASK_UNINTERRUPTIBLE);
if (!buffer_locked(bh)) if (!buffer_locked(bh))
break; break;
...@@ -488,7 +488,7 @@ static void free_more_memory(void) ...@@ -488,7 +488,7 @@ static void free_more_memory(void)
wakeup_bdflush(); wakeup_bdflush();
try_to_free_pages(zone, GFP_NOFS, 0); try_to_free_pages(zone, GFP_NOFS, 0);
run_task_queue(&tq_disk); blk_run_queues();
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
yield(); yield();
} }
...@@ -1014,7 +1014,7 @@ create_buffers(struct page * page, unsigned long size, int async) ...@@ -1014,7 +1014,7 @@ create_buffers(struct page * page, unsigned long size, int async)
* the reserve list is empty, we're sure there are * the reserve list is empty, we're sure there are
* async buffer heads in use. * async buffer heads in use.
*/ */
run_task_queue(&tq_disk); blk_run_queues();
free_more_memory(); free_more_memory();
goto try_again; goto try_again;
...@@ -2475,7 +2475,7 @@ EXPORT_SYMBOL(try_to_free_buffers); ...@@ -2475,7 +2475,7 @@ EXPORT_SYMBOL(try_to_free_buffers);
int block_sync_page(struct page *page) int block_sync_page(struct page *page)
{ {
run_task_queue(&tq_disk); blk_run_queues();
return 0; return 0;
} }
......
...@@ -112,7 +112,7 @@ void kiobuf_wait_for_io(struct kiobuf *kiobuf) ...@@ -112,7 +112,7 @@ void kiobuf_wait_for_io(struct kiobuf *kiobuf)
repeat: repeat:
set_task_state(tsk, TASK_UNINTERRUPTIBLE); set_task_state(tsk, TASK_UNINTERRUPTIBLE);
if (atomic_read(&kiobuf->io_count) != 0) { if (atomic_read(&kiobuf->io_count) != 0) {
run_task_queue(&tq_disk); blk_run_queues();
schedule(); schedule();
if (atomic_read(&kiobuf->io_count) != 0) if (atomic_read(&kiobuf->io_count) != 0)
goto repeat; goto repeat;
......
...@@ -179,7 +179,7 @@ static void __flush_batch(struct buffer_head **bhs, int *batch_count) ...@@ -179,7 +179,7 @@ static void __flush_batch(struct buffer_head **bhs, int *batch_count)
spin_unlock(&journal_datalist_lock); spin_unlock(&journal_datalist_lock);
ll_rw_block(WRITE, *batch_count, bhs); ll_rw_block(WRITE, *batch_count, bhs);
run_task_queue(&tq_disk); blk_run_queues();
spin_lock(&journal_datalist_lock); spin_lock(&journal_datalist_lock);
for (i = 0; i < *batch_count; i++) { for (i = 0; i < *batch_count; i++) {
struct buffer_head *bh = bhs[i]; struct buffer_head *bh = bhs[i];
......
...@@ -32,7 +32,7 @@ void wait_buffer_until_released (const struct buffer_head * bh) ...@@ -32,7 +32,7 @@ void wait_buffer_until_released (const struct buffer_head * bh)
bh, repeat_counter, buffer_journaled(bh) ? ' ' : '!', bh, repeat_counter, buffer_journaled(bh) ? ' ' : '!',
buffer_journal_dirty(bh) ? ' ' : '!'); buffer_journal_dirty(bh) ? ' ' : '!');
} }
run_task_queue(&tq_disk); blk_run_queues();
yield(); yield();
} }
if (repeat_counter > 30000000) { if (repeat_counter > 30000000) {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/interrupt.h>
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
...@@ -136,6 +137,11 @@ struct blk_queue_tag { ...@@ -136,6 +137,11 @@ struct blk_queue_tag {
int max_depth; int max_depth;
}; };
struct blk_plug {
struct list_head list;
struct tasklet_struct task;
};
/* /*
* Default nr free requests per queue, ll_rw_blk will scale it down * Default nr free requests per queue, ll_rw_blk will scale it down
* according to available RAM at init time * according to available RAM at init time
...@@ -177,10 +183,7 @@ struct request_queue ...@@ -177,10 +183,7 @@ struct request_queue
unsigned long bounce_pfn; unsigned long bounce_pfn;
int bounce_gfp; int bounce_gfp;
/* struct blk_plug plug;
* This is used to remove the plug when tq_disk runs.
*/
struct tq_struct plug_tq;
/* /*
* various queue flags, see QUEUE_* below * various queue flags, see QUEUE_* below
...@@ -217,6 +220,7 @@ struct request_queue ...@@ -217,6 +220,7 @@ struct request_queue
#define QUEUE_FLAG_PLUGGED 0 /* queue is plugged */ #define QUEUE_FLAG_PLUGGED 0 /* queue is plugged */
#define QUEUE_FLAG_CLUSTER 1 /* cluster several segments into 1 */ #define QUEUE_FLAG_CLUSTER 1 /* cluster several segments into 1 */
#define QUEUE_FLAG_QUEUED 2 /* uses generic tag queueing */ #define QUEUE_FLAG_QUEUED 2 /* uses generic tag queueing */
#define QUEUE_FLAG_STOPPED 3 /* queue is stopped */
#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) #define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
#define blk_mark_plugged(q) set_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) #define blk_mark_plugged(q) set_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
...@@ -303,6 +307,8 @@ extern void blk_recount_segments(request_queue_t *, struct bio *); ...@@ -303,6 +307,8 @@ extern void blk_recount_segments(request_queue_t *, struct bio *);
extern inline int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *); extern inline int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *);
extern inline int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *); extern inline int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *);
extern int block_ioctl(struct block_device *, unsigned int, unsigned long); extern int block_ioctl(struct block_device *, unsigned int, unsigned long);
extern void blk_start_queue(request_queue_t *q);
extern void blk_stop_queue(request_queue_t *q);
/* /*
* get ready for proper ref counting * get ready for proper ref counting
......
...@@ -1086,6 +1086,7 @@ extern int blkdev_get(struct block_device *, mode_t, unsigned, int); ...@@ -1086,6 +1086,7 @@ extern int blkdev_get(struct block_device *, mode_t, unsigned, int);
extern int blkdev_put(struct block_device *, int); extern int blkdev_put(struct block_device *, int);
extern int bd_claim(struct block_device *, void *); extern int bd_claim(struct block_device *, void *);
extern void bd_release(struct block_device *); extern void bd_release(struct block_device *);
extern void blk_run_queues(void);
/* fs/devices.c */ /* fs/devices.c */
extern const struct block_device_operations *get_blkfops(unsigned int); extern const struct block_device_operations *get_blkfops(unsigned int);
......
...@@ -66,7 +66,7 @@ typedef struct list_head task_queue; ...@@ -66,7 +66,7 @@ typedef struct list_head task_queue;
#define DECLARE_TASK_QUEUE(q) LIST_HEAD(q) #define DECLARE_TASK_QUEUE(q) LIST_HEAD(q)
#define TQ_ACTIVE(q) (!list_empty(&q)) #define TQ_ACTIVE(q) (!list_empty(&q))
extern task_queue tq_timer, tq_immediate, tq_disk, tq_bdflush; extern task_queue tq_timer, tq_immediate, tq_bdflush;
/* /*
* To implement your own list of active bottom halfs, use the following * To implement your own list of active bottom halfs, use the following
......
...@@ -337,7 +337,6 @@ EXPORT_SYMBOL(ioctl_by_bdev); ...@@ -337,7 +337,6 @@ EXPORT_SYMBOL(ioctl_by_bdev);
EXPORT_SYMBOL(grok_partitions); EXPORT_SYMBOL(grok_partitions);
EXPORT_SYMBOL(register_disk); EXPORT_SYMBOL(register_disk);
EXPORT_SYMBOL(read_dev_sector); EXPORT_SYMBOL(read_dev_sector);
EXPORT_SYMBOL(tq_disk);
EXPORT_SYMBOL(init_buffer); EXPORT_SYMBOL(init_buffer);
EXPORT_SYMBOL(wipe_partitions); EXPORT_SYMBOL(wipe_partitions);
......
...@@ -220,7 +220,7 @@ void * mempool_alloc(mempool_t *pool, int gfp_mask) ...@@ -220,7 +220,7 @@ void * mempool_alloc(mempool_t *pool, int gfp_mask)
if (gfp_mask == gfp_nowait) if (gfp_mask == gfp_nowait)
return NULL; return NULL;
run_task_queue(&tq_disk); blk_run_queues();
add_wait_queue_exclusive(&pool->wait, &wait); add_wait_queue_exclusive(&pool->wait, &wait);
set_task_state(current, TASK_UNINTERRUPTIBLE); set_task_state(current, TASK_UNINTERRUPTIBLE);
......
...@@ -148,7 +148,7 @@ static void background_writeout(unsigned long _min_pages) ...@@ -148,7 +148,7 @@ static void background_writeout(unsigned long _min_pages)
writeback_unlocked_inodes(&nr_to_write, WB_SYNC_NONE, NULL); writeback_unlocked_inodes(&nr_to_write, WB_SYNC_NONE, NULL);
min_pages -= MAX_WRITEBACK_PAGES - nr_to_write; min_pages -= MAX_WRITEBACK_PAGES - nr_to_write;
} while (nr_to_write <= 0); } while (nr_to_write <= 0);
run_task_queue(&tq_disk); blk_run_queues();
} }
/* /*
...@@ -206,7 +206,7 @@ static void wb_kupdate(unsigned long arg) ...@@ -206,7 +206,7 @@ static void wb_kupdate(unsigned long arg)
next_jif = start_jif + wb_writeback_jifs; next_jif = start_jif + wb_writeback_jifs;
nr_to_write = ps.nr_dirty; nr_to_write = ps.nr_dirty;
writeback_unlocked_inodes(&nr_to_write, WB_SYNC_NONE, &oldest_jif); writeback_unlocked_inodes(&nr_to_write, WB_SYNC_NONE, &oldest_jif);
run_task_queue(&tq_disk); blk_run_queues();
yield(); yield();
if (time_before(next_jif, jiffies + HZ)) if (time_before(next_jif, jiffies + HZ))
......
...@@ -168,7 +168,7 @@ void do_page_cache_readahead(struct file *file, ...@@ -168,7 +168,7 @@ void do_page_cache_readahead(struct file *file,
* will then handle the error. * will then handle the error.
*/ */
read_pages(mapping, &page_pool, nr_to_really_read); read_pages(mapping, &page_pool, nr_to_really_read);
run_task_queue(&tq_disk); blk_run_queues();
BUG_ON(!list_empty(&page_pool)); BUG_ON(!list_empty(&page_pool));
return; return;
} }
......
...@@ -815,7 +815,7 @@ int kswapd(void *unused) ...@@ -815,7 +815,7 @@ int kswapd(void *unused)
* up on a more timely basis. * up on a more timely basis.
*/ */
kswapd_balance(); kswapd_balance();
run_task_queue(&tq_disk); blk_run_queues();
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment