diff options
| -rw-r--r-- | block/blk-core.c | 29 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 6 |
2 files changed, 35 insertions, 0 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 3cc17e6064d6..e958c7a1e462 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -197,6 +197,32 @@ void blk_dump_rq_flags(struct request *rq, char *msg) | |||
| 197 | } | 197 | } |
| 198 | EXPORT_SYMBOL(blk_dump_rq_flags); | 198 | EXPORT_SYMBOL(blk_dump_rq_flags); |
| 199 | 199 | ||
| 200 | static void blk_delay_work(struct work_struct *work) | ||
| 201 | { | ||
| 202 | struct request_queue *q; | ||
| 203 | |||
| 204 | q = container_of(work, struct request_queue, delay_work.work); | ||
| 205 | spin_lock_irq(q->queue_lock); | ||
| 206 | q->request_fn(q); | ||
| 207 | spin_unlock_irq(q->queue_lock); | ||
| 208 | } | ||
| 209 | |||
| 210 | /** | ||
| 211 | * blk_delay_queue - restart queueing after defined interval | ||
| 212 | * @q: The &struct request_queue in question | ||
| 213 | * @msecs: Delay in msecs | ||
| 214 | * | ||
| 215 | * Description: | ||
| 216 | * Sometimes queueing needs to be postponed for a little while, to allow | ||
| 217 | * resources to come back. This function will make sure that queueing is | ||
| 218 | * restarted around the specified time. | ||
| 219 | */ | ||
| 220 | void blk_delay_queue(struct request_queue *q, unsigned long msecs) | ||
| 221 | { | ||
| 222 | schedule_delayed_work(&q->delay_work, msecs_to_jiffies(msecs)); | ||
| 223 | } | ||
| 224 | EXPORT_SYMBOL(blk_delay_queue); | ||
| 225 | |||
| 200 | /* | 226 | /* |
| 201 | * "plug" the device if there are no outstanding requests: this will | 227 | * "plug" the device if there are no outstanding requests: this will |
| 202 | * force the transfer to start only after we have put all the requests | 228 | * force the transfer to start only after we have put all the requests |
| @@ -363,6 +389,7 @@ EXPORT_SYMBOL(blk_start_queue); | |||
| 363 | void blk_stop_queue(struct request_queue *q) | 389 | void blk_stop_queue(struct request_queue *q) |
| 364 | { | 390 | { |
| 365 | blk_remove_plug(q); | 391 | blk_remove_plug(q); |
| 392 | cancel_delayed_work(&q->delay_work); | ||
| 366 | queue_flag_set(QUEUE_FLAG_STOPPED, q); | 393 | queue_flag_set(QUEUE_FLAG_STOPPED, q); |
| 367 | } | 394 | } |
| 368 | EXPORT_SYMBOL(blk_stop_queue); | 395 | EXPORT_SYMBOL(blk_stop_queue); |
| @@ -387,6 +414,7 @@ void blk_sync_queue(struct request_queue *q) | |||
| 387 | del_timer_sync(&q->timeout); | 414 | del_timer_sync(&q->timeout); |
| 388 | cancel_work_sync(&q->unplug_work); | 415 | cancel_work_sync(&q->unplug_work); |
| 389 | throtl_shutdown_timer_wq(q); | 416 | throtl_shutdown_timer_wq(q); |
| 417 | cancel_delayed_work_sync(&q->delay_work); | ||
| 390 | } | 418 | } |
| 391 | EXPORT_SYMBOL(blk_sync_queue); | 419 | EXPORT_SYMBOL(blk_sync_queue); |
| 392 | 420 | ||
| @@ -534,6 +562,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) | |||
| 534 | INIT_LIST_HEAD(&q->flush_queue[1]); | 562 | INIT_LIST_HEAD(&q->flush_queue[1]); |
| 535 | INIT_LIST_HEAD(&q->flush_data_in_flight); | 563 | INIT_LIST_HEAD(&q->flush_data_in_flight); |
| 536 | INIT_WORK(&q->unplug_work, blk_unplug_work); | 564 | INIT_WORK(&q->unplug_work, blk_unplug_work); |
| 565 | INIT_DELAYED_WORK(&q->delay_work, blk_delay_work); | ||
| 537 | 566 | ||
| 538 | kobject_init(&q->kobj, &blk_queue_ktype); | 567 | kobject_init(&q->kobj, &blk_queue_ktype); |
| 539 | 568 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e3ee74fc5903..f55b2a8b6610 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -300,6 +300,11 @@ struct request_queue | |||
| 300 | unsigned long unplug_delay; /* After this many jiffies */ | 300 | unsigned long unplug_delay; /* After this many jiffies */ |
| 301 | struct work_struct unplug_work; | 301 | struct work_struct unplug_work; |
| 302 | 302 | ||
| 303 | /* | ||
| 304 | * Delayed queue handling | ||
| 305 | */ | ||
| 306 | struct delayed_work delay_work; | ||
| 307 | |||
| 303 | struct backing_dev_info backing_dev_info; | 308 | struct backing_dev_info backing_dev_info; |
| 304 | 309 | ||
| 305 | /* | 310 | /* |
| @@ -677,6 +682,7 @@ extern int blk_insert_cloned_request(struct request_queue *q, | |||
| 677 | extern void blk_plug_device(struct request_queue *); | 682 | extern void blk_plug_device(struct request_queue *); |
| 678 | extern void blk_plug_device_unlocked(struct request_queue *); | 683 | extern void blk_plug_device_unlocked(struct request_queue *); |
| 679 | extern int blk_remove_plug(struct request_queue *); | 684 | extern int blk_remove_plug(struct request_queue *); |
| 685 | extern void blk_delay_queue(struct request_queue *, unsigned long); | ||
| 680 | extern void blk_recount_segments(struct request_queue *, struct bio *); | 686 | extern void blk_recount_segments(struct request_queue *, struct bio *); |
| 681 | extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, | 687 | extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, |
| 682 | unsigned int, void __user *); | 688 | unsigned int, void __user *); |
