aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/pktcdvd.c32
-rw-r--r--include/linux/pktcdvd.h9
2 files changed, 41 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;
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
index 8a94c717c266..9b1a185fb1e5 100644
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -112,6 +112,12 @@ struct pkt_ctrl_command {
112#include <linux/completion.h> 112#include <linux/completion.h>
113#include <linux/cdrom.h> 113#include <linux/cdrom.h>
114 114
115
116/* default bio write queue congestion marks */
117#define PKT_WRITE_CONGESTION_ON 10000
118#define PKT_WRITE_CONGESTION_OFF 9000
119
120
115struct packet_settings 121struct packet_settings
116{ 122{
117 __u32 size; /* packet size in (512 byte) sectors */ 123 __u32 size; /* packet size in (512 byte) sectors */
@@ -271,6 +277,9 @@ struct pktcdvd_device
271 277
272 struct packet_iosched iosched; 278 struct packet_iosched iosched;
273 struct gendisk *disk; 279 struct gendisk *disk;
280
281 int write_congestion_off;
282 int write_congestion_on;
274}; 283};
275 284
276#endif /* __KERNEL__ */ 285#endif /* __KERNEL__ */