aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Maier <balagi@justmail.de>2006-12-08 05:36:11 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:38 -0500
commit0a0fc9601dd1024ec7171993bf075a789246e1ed (patch)
treec606a35beb9c56ccfeff57cb594e6a7e5b12a80c /drivers
parent2d4eeec563a0472b68de3597c17f2d3b11c49c00 (diff)
[PATCH] pktcdvd: bio write congestion using congestion_wait()
This adds a bio write queue congestion control to the pktcdvd driver with fixed on/off marks. It prevents that the driver consumes a unlimited amount of write requests. [akpm@osdl.org: sync with congestion_wait() renaming] Signed-off-by: Thomas Maier <balagi@justmail.de> Cc: Peter Osterlund <petero2@telia.com> Cc: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/pktcdvd.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 7e7b892f621a..91fbe7fd6d0b 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -84,6 +84,8 @@
84static struct pktcdvd_device *pkt_devs[MAX_WRITERS]; 84static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
85static struct proc_dir_entry *pkt_proc; 85static struct proc_dir_entry *pkt_proc;
86static int pktdev_major; 86static int pktdev_major;
87static int write_congestion_on = PKT_WRITE_CONGESTION_ON;
88static int write_congestion_off = PKT_WRITE_CONGESTION_OFF;
87static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */ 89static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */
88static mempool_t *psd_pool; 90static mempool_t *psd_pool;
89 91
@@ -894,6 +896,7 @@ static int pkt_handle_queue(struct pktcdvd_device *pd)
894 sector_t zone = 0; /* Suppress gcc warning */ 896 sector_t zone = 0; /* Suppress gcc warning */
895 struct pkt_rb_node *node, *first_node; 897 struct pkt_rb_node *node, *first_node;
896 struct rb_node *n; 898 struct rb_node *n;
899 int wakeup;
897 900
898 VPRINTK("handle_queue\n"); 901 VPRINTK("handle_queue\n");
899 902
@@ -966,7 +969,13 @@ try_next_bio:
966 pkt->write_size += bio->bi_size / CD_FRAMESIZE; 969 pkt->write_size += bio->bi_size / CD_FRAMESIZE;
967 spin_unlock(&pkt->lock); 970 spin_unlock(&pkt->lock);
968 } 971 }
972 /* check write congestion marks, and if bio_queue_size is
973 below, wake up any waiters */
974 wakeup = (pd->write_congestion_on > 0
975 && pd->bio_queue_size <= pd->write_congestion_off);
969 spin_unlock(&pd->lock); 976 spin_unlock(&pd->lock);
977 if (wakeup)
978 blk_clear_queue_congested(pd->disk->queue, WRITE);
970 979
971 pkt->sleep_time = max(PACKET_WAIT_TIME, 1); 980 pkt->sleep_time = max(PACKET_WAIT_TIME, 1);
972 pkt_set_state(pkt, PACKET_WAITING_STATE); 981 pkt_set_state(pkt, PACKET_WAITING_STATE);
@@ -2179,6 +2188,23 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
2179 } 2188 }
2180 spin_unlock(&pd->cdrw.active_list_lock); 2189 spin_unlock(&pd->cdrw.active_list_lock);
2181 2190
2191 /*
2192 * Test if there is enough room left in the bio work queue
2193 * (queue size >= congestion on mark).
2194 * If not, wait till the work queue size is below the congestion off mark.
2195 */
2196 spin_lock(&pd->lock);
2197 if (pd->write_congestion_on > 0
2198 && pd->bio_queue_size >= pd->write_congestion_on) {
2199 blk_set_queue_congested(q, WRITE);
2200 do {
2201 spin_unlock(&pd->lock);
2202 congestion_wait(WRITE, HZ);
2203 spin_lock(&pd->lock);
2204 } while(pd->bio_queue_size > pd->write_congestion_off);
2205 }
2206 spin_unlock(&pd->lock);
2207
2182 /* 2208 /*
2183 * No matching packet found. Store the bio in the work queue. 2209 * No matching packet found. Store the bio in the work queue.
2184 */ 2210 */
@@ -2298,6 +2324,9 @@ static int pkt_seq_show(struct seq_file *m, void *p)
2298 seq_printf(m, "\tstate:\t\t\ti:%d ow:%d rw:%d ww:%d rec:%d fin:%d\n", 2324 seq_printf(m, "\tstate:\t\t\ti:%d ow:%d rw:%d ww:%d rec:%d fin:%d\n",
2299 states[0], states[1], states[2], states[3], states[4], states[5]); 2325 states[0], states[1], states[2], states[3], states[4], states[5]);
2300 2326
2327 seq_printf(m, "\twrite congestion marks:\toff=%d on=%d\n",
2328 pd->write_congestion_off,
2329 pd->write_congestion_on);
2301 return 0; 2330 return 0;
2302} 2331}
2303 2332
@@ -2474,6 +2503,9 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
2474 init_waitqueue_head(&pd->wqueue); 2503 init_waitqueue_head(&pd->wqueue);
2475 pd->bio_queue = RB_ROOT; 2504 pd->bio_queue = RB_ROOT;
2476 2505
2506 pd->write_congestion_on = write_congestion_on;
2507 pd->write_congestion_off = write_congestion_off;
2508
2477 disk = alloc_disk(1); 2509 disk = alloc_disk(1);
2478 if (!disk) 2510 if (!disk)
2479 goto out_mem; 2511 goto out_mem;