Commit dc72ef4ae35c2016fb594bcc85ce871376682174
Committed by
Jens Axboe
1 parent
981a79730d
Exists in
master
and in
7 other branches
[PATCH] Add blk_start_queueing() helper
CFQ implements this on its own now, but it's really block layer knowledge. Tells a device queue to start dispatching requests to the driver, taking care to unplug if needed. Also fixes the issue where as/cfq will invoke a stopped queue, which we really don't want. Signed-off-by: Jens Axboe <axboe@suse.de>
Showing 4 changed files with 26 additions and 25 deletions Side-by-side Diff
block/as-iosched.c
block/cfq-iosched.c
... | ... | @@ -1553,19 +1553,6 @@ |
1553 | 1553 | } |
1554 | 1554 | |
1555 | 1555 | /* |
1556 | - * should really be a ll_rw_blk.c helper | |
1557 | - */ | |
1558 | -static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |
1559 | -{ | |
1560 | - request_queue_t *q = cfqd->queue; | |
1561 | - | |
1562 | - if (!blk_queue_plugged(q)) | |
1563 | - q->request_fn(q); | |
1564 | - else | |
1565 | - __generic_unplug_device(q); | |
1566 | -} | |
1567 | - | |
1568 | -/* | |
1569 | 1556 | * Called when a new fs request (rq) is added (to cfqq). Check if there's |
1570 | 1557 | * something we should do about it |
1571 | 1558 | */ |
... | ... | @@ -1593,7 +1580,7 @@ |
1593 | 1580 | if (cic == cfqd->active_cic && |
1594 | 1581 | del_timer(&cfqd->idle_slice_timer)) { |
1595 | 1582 | cfq_slice_expired(cfqd, 0); |
1596 | - cfq_start_queueing(cfqd, cfqq); | |
1583 | + blk_start_queueing(cfqd->queue); | |
1597 | 1584 | } |
1598 | 1585 | return; |
1599 | 1586 | } |
... | ... | @@ -1614,7 +1601,7 @@ |
1614 | 1601 | if (cfq_cfqq_wait_request(cfqq)) { |
1615 | 1602 | cfq_mark_cfqq_must_dispatch(cfqq); |
1616 | 1603 | del_timer(&cfqd->idle_slice_timer); |
1617 | - cfq_start_queueing(cfqd, cfqq); | |
1604 | + blk_start_queueing(cfqd->queue); | |
1618 | 1605 | } |
1619 | 1606 | } else if (cfq_should_preempt(cfqd, cfqq, rq)) { |
1620 | 1607 | /* |
... | ... | @@ -1624,7 +1611,7 @@ |
1624 | 1611 | */ |
1625 | 1612 | cfq_preempt_queue(cfqd, cfqq); |
1626 | 1613 | cfq_mark_cfqq_must_dispatch(cfqq); |
1627 | - cfq_start_queueing(cfqd, cfqq); | |
1614 | + blk_start_queueing(cfqd->queue); | |
1628 | 1615 | } |
1629 | 1616 | } |
1630 | 1617 | |
... | ... | @@ -1832,8 +1819,7 @@ |
1832 | 1819 | unsigned long flags; |
1833 | 1820 | |
1834 | 1821 | spin_lock_irqsave(q->queue_lock, flags); |
1835 | - blk_remove_plug(q); | |
1836 | - q->request_fn(q); | |
1822 | + blk_start_queueing(q); | |
1837 | 1823 | spin_unlock_irqrestore(q->queue_lock, flags); |
1838 | 1824 | } |
1839 | 1825 |
block/ll_rw_blk.c
... | ... | @@ -2267,6 +2267,25 @@ |
2267 | 2267 | EXPORT_SYMBOL(blk_get_request); |
2268 | 2268 | |
2269 | 2269 | /** |
2270 | + * blk_start_queueing - initiate dispatch of requests to device | |
2271 | + * @q: request queue to kick into gear | |
2272 | + * | |
2273 | + * This is basically a helper to remove the need to know whether a queue | |
2274 | + * is plugged or not if someone just wants to initiate dispatch of requests | |
2275 | + * for this queue. | |
2276 | + * | |
2277 | + * The queue lock must be held with interrupts disabled. | |
2278 | + */ | |
2279 | +void blk_start_queueing(request_queue_t *q) | |
2280 | +{ | |
2281 | + if (!blk_queue_plugged(q)) | |
2282 | + q->request_fn(q); | |
2283 | + else | |
2284 | + __generic_unplug_device(q); | |
2285 | +} | |
2286 | +EXPORT_SYMBOL(blk_start_queueing); | |
2287 | + | |
2288 | +/** | |
2270 | 2289 | * blk_requeue_request - put a request back on queue |
2271 | 2290 | * @q: request queue where request should be inserted |
2272 | 2291 | * @rq: request to be inserted |
... | ... | @@ -2333,11 +2352,7 @@ |
2333 | 2352 | |
2334 | 2353 | drive_stat_acct(rq, rq->nr_sectors, 1); |
2335 | 2354 | __elv_add_request(q, rq, where, 0); |
2336 | - | |
2337 | - if (blk_queue_plugged(q)) | |
2338 | - __generic_unplug_device(q); | |
2339 | - else | |
2340 | - q->request_fn(q); | |
2355 | + blk_start_queueing(q); | |
2341 | 2356 | spin_unlock_irqrestore(q->queue_lock, flags); |
2342 | 2357 | } |
2343 | 2358 |
include/linux/blkdev.h
... | ... | @@ -635,6 +635,7 @@ |
635 | 635 | extern void blk_sync_queue(struct request_queue *q); |
636 | 636 | extern void __blk_stop_queue(request_queue_t *q); |
637 | 637 | extern void blk_run_queue(request_queue_t *); |
638 | +extern void blk_start_queueing(request_queue_t *); | |
638 | 639 | extern void blk_queue_activity_fn(request_queue_t *, activity_fn *, void *); |
639 | 640 | extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int); |
640 | 641 | extern int blk_rq_unmap_user(struct bio *, unsigned int); |