aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/as-iosched.c13
-rw-r--r--block/cfq-iosched.c98
-rw-r--r--block/deadline-iosched.c13
-rw-r--r--block/elevator.c63
-rw-r--r--block/ll_rw_blk.c26
-rw-r--r--block/noop-iosched.c7
6 files changed, 139 insertions, 81 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c
index ed336ab453ba..0c750393be4a 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -1647,17 +1647,17 @@ static void as_exit_queue(elevator_t *e)
1647 * initialize elevator private data (as_data), and alloc a arq for 1647 * initialize elevator private data (as_data), and alloc a arq for
1648 * each request on the free lists 1648 * each request on the free lists
1649 */ 1649 */
1650static int as_init_queue(request_queue_t *q, elevator_t *e) 1650static void *as_init_queue(request_queue_t *q, elevator_t *e)
1651{ 1651{
1652 struct as_data *ad; 1652 struct as_data *ad;
1653 int i; 1653 int i;
1654 1654
1655 if (!arq_pool) 1655 if (!arq_pool)
1656 return -ENOMEM; 1656 return NULL;
1657 1657
1658 ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node); 1658 ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
1659 if (!ad) 1659 if (!ad)
1660 return -ENOMEM; 1660 return NULL;
1661 memset(ad, 0, sizeof(*ad)); 1661 memset(ad, 0, sizeof(*ad));
1662 1662
1663 ad->q = q; /* Identify what queue the data belongs to */ 1663 ad->q = q; /* Identify what queue the data belongs to */
@@ -1666,7 +1666,7 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
1666 GFP_KERNEL, q->node); 1666 GFP_KERNEL, q->node);
1667 if (!ad->hash) { 1667 if (!ad->hash) {
1668 kfree(ad); 1668 kfree(ad);
1669 return -ENOMEM; 1669 return NULL;
1670 } 1670 }
1671 1671
1672 ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, 1672 ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
@@ -1674,7 +1674,7 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
1674 if (!ad->arq_pool) { 1674 if (!ad->arq_pool) {
1675 kfree(ad->hash); 1675 kfree(ad->hash);
1676 kfree(ad); 1676 kfree(ad);
1677 return -ENOMEM; 1677 return NULL;
1678 } 1678 }
1679 1679
1680 /* anticipatory scheduling helpers */ 1680 /* anticipatory scheduling helpers */
@@ -1695,14 +1695,13 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
1695 ad->antic_expire = default_antic_expire; 1695 ad->antic_expire = default_antic_expire;
1696 ad->batch_expire[REQ_SYNC] = default_read_batch_expire; 1696 ad->batch_expire[REQ_SYNC] = default_read_batch_expire;
1697 ad->batch_expire[REQ_ASYNC] = default_write_batch_expire; 1697 ad->batch_expire[REQ_ASYNC] = default_write_batch_expire;
1698 e->elevator_data = ad;
1699 1698
1700 ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; 1699 ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC];
1701 ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10; 1700 ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10;
1702 if (ad->write_batch_count < 2) 1701 if (ad->write_batch_count < 2)
1703 ad->write_batch_count = 2; 1702 ad->write_batch_count = 2;
1704 1703
1705 return 0; 1704 return ad;
1706} 1705}
1707 1706
1708/* 1707/*
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 01c416ba8437..6200d9b9af28 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -33,7 +33,7 @@ static int cfq_slice_idle = HZ / 70;
33 33
34#define CFQ_KEY_ASYNC (0) 34#define CFQ_KEY_ASYNC (0)
35 35
36static DEFINE_RWLOCK(cfq_exit_lock); 36static DEFINE_SPINLOCK(cfq_exit_lock);
37 37
38/* 38/*
39 * for the hash of cfqq inside the cfqd 39 * for the hash of cfqq inside the cfqd
@@ -128,6 +128,7 @@ struct cfq_data {
128 mempool_t *crq_pool; 128 mempool_t *crq_pool;
129 129
130 int rq_in_driver; 130 int rq_in_driver;
131 int hw_tag;
131 132
132 /* 133 /*
133 * schedule slice state info 134 * schedule slice state info
@@ -495,10 +496,13 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
495 496
496 /* 497 /*
497 * if queue was preempted, just add to front to be fair. busy_rr 498 * if queue was preempted, just add to front to be fair. busy_rr
498 * isn't sorted. 499 * isn't sorted, but insert at the back for fairness.
499 */ 500 */
500 if (preempted || list == &cfqd->busy_rr) { 501 if (preempted || list == &cfqd->busy_rr) {
501 list_add(&cfqq->cfq_list, list); 502 if (preempted)
503 list = list->prev;
504
505 list_add_tail(&cfqq->cfq_list, list);
502 return; 506 return;
503 } 507 }
504 508
@@ -658,6 +662,15 @@ static void cfq_activate_request(request_queue_t *q, struct request *rq)
658 struct cfq_data *cfqd = q->elevator->elevator_data; 662 struct cfq_data *cfqd = q->elevator->elevator_data;
659 663
660 cfqd->rq_in_driver++; 664 cfqd->rq_in_driver++;
665
666 /*
667 * If the depth is larger 1, it really could be queueing. But lets
668 * make the mark a little higher - idling could still be good for
669 * low queueing, and a low queueing number could also just indicate
670 * a SCSI mid layer like behaviour where limit+1 is often seen.
671 */
672 if (!cfqd->hw_tag && cfqd->rq_in_driver > 4)
673 cfqd->hw_tag = 1;
661} 674}
662 675
663static void cfq_deactivate_request(request_queue_t *q, struct request *rq) 676static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
@@ -873,6 +886,13 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd)
873 cfqq = list_entry_cfqq(cfqd->cur_rr.next); 886 cfqq = list_entry_cfqq(cfqd->cur_rr.next);
874 887
875 /* 888 /*
889 * If no new queues are available, check if the busy list has some
890 * before falling back to idle io.
891 */
892 if (!cfqq && !list_empty(&cfqd->busy_rr))
893 cfqq = list_entry_cfqq(cfqd->busy_rr.next);
894
895 /*
876 * if we have idle queues and no rt or be queues had pending 896 * if we have idle queues and no rt or be queues had pending
877 * requests, either allow immediate service if the grace period 897 * requests, either allow immediate service if the grace period
878 * has passed or arm the idle grace timer 898 * has passed or arm the idle grace timer
@@ -1278,7 +1298,7 @@ static void cfq_exit_io_context(struct io_context *ioc)
1278 /* 1298 /*
1279 * put the reference this task is holding to the various queues 1299 * put the reference this task is holding to the various queues
1280 */ 1300 */
1281 read_lock_irqsave(&cfq_exit_lock, flags); 1301 spin_lock_irqsave(&cfq_exit_lock, flags);
1282 1302
1283 n = rb_first(&ioc->cic_root); 1303 n = rb_first(&ioc->cic_root);
1284 while (n != NULL) { 1304 while (n != NULL) {
@@ -1288,7 +1308,7 @@ static void cfq_exit_io_context(struct io_context *ioc)
1288 n = rb_next(n); 1308 n = rb_next(n);
1289 } 1309 }
1290 1310
1291 read_unlock_irqrestore(&cfq_exit_lock, flags); 1311 spin_unlock_irqrestore(&cfq_exit_lock, flags);
1292} 1312}
1293 1313
1294static struct cfq_io_context * 1314static struct cfq_io_context *
@@ -1297,17 +1317,12 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
1297 struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask); 1317 struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
1298 1318
1299 if (cic) { 1319 if (cic) {
1300 RB_CLEAR(&cic->rb_node); 1320 memset(cic, 0, sizeof(*cic));
1301 cic->key = NULL; 1321 RB_CLEAR_COLOR(&cic->rb_node);
1302 cic->cfqq[ASYNC] = NULL;
1303 cic->cfqq[SYNC] = NULL;
1304 cic->last_end_request = jiffies; 1322 cic->last_end_request = jiffies;
1305 cic->ttime_total = 0; 1323 INIT_LIST_HEAD(&cic->queue_list);
1306 cic->ttime_samples = 0;
1307 cic->ttime_mean = 0;
1308 cic->dtor = cfq_free_io_context; 1324 cic->dtor = cfq_free_io_context;
1309 cic->exit = cfq_exit_io_context; 1325 cic->exit = cfq_exit_io_context;
1310 INIT_LIST_HEAD(&cic->queue_list);
1311 atomic_inc(&ioc_count); 1326 atomic_inc(&ioc_count);
1312 } 1327 }
1313 1328
@@ -1394,17 +1409,17 @@ static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
1394 struct cfq_io_context *cic; 1409 struct cfq_io_context *cic;
1395 struct rb_node *n; 1410 struct rb_node *n;
1396 1411
1397 write_lock(&cfq_exit_lock); 1412 spin_lock(&cfq_exit_lock);
1398 1413
1399 n = rb_first(&ioc->cic_root); 1414 n = rb_first(&ioc->cic_root);
1400 while (n != NULL) { 1415 while (n != NULL) {
1401 cic = rb_entry(n, struct cfq_io_context, rb_node); 1416 cic = rb_entry(n, struct cfq_io_context, rb_node);
1402 1417
1403 changed_ioprio(cic); 1418 changed_ioprio(cic);
1404 n = rb_next(n); 1419 n = rb_next(n);
1405 } 1420 }
1406 1421
1407 write_unlock(&cfq_exit_lock); 1422 spin_unlock(&cfq_exit_lock);
1408 1423
1409 return 0; 1424 return 0;
1410} 1425}
@@ -1452,7 +1467,8 @@ retry:
1452 * set ->slice_left to allow preemption for a new process 1467 * set ->slice_left to allow preemption for a new process
1453 */ 1468 */
1454 cfqq->slice_left = 2 * cfqd->cfq_slice_idle; 1469 cfqq->slice_left = 2 * cfqd->cfq_slice_idle;
1455 cfq_mark_cfqq_idle_window(cfqq); 1470 if (!cfqd->hw_tag)
1471 cfq_mark_cfqq_idle_window(cfqq);
1456 cfq_mark_cfqq_prio_changed(cfqq); 1472 cfq_mark_cfqq_prio_changed(cfqq);
1457 cfq_init_prio_data(cfqq); 1473 cfq_init_prio_data(cfqq);
1458 } 1474 }
@@ -1469,9 +1485,10 @@ out:
1469static void 1485static void
1470cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic) 1486cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic)
1471{ 1487{
1472 read_lock(&cfq_exit_lock); 1488 spin_lock(&cfq_exit_lock);
1473 rb_erase(&cic->rb_node, &ioc->cic_root); 1489 rb_erase(&cic->rb_node, &ioc->cic_root);
1474 read_unlock(&cfq_exit_lock); 1490 list_del_init(&cic->queue_list);
1491 spin_unlock(&cfq_exit_lock);
1475 kmem_cache_free(cfq_ioc_pool, cic); 1492 kmem_cache_free(cfq_ioc_pool, cic);
1476 atomic_dec(&ioc_count); 1493 atomic_dec(&ioc_count);
1477} 1494}
@@ -1539,11 +1556,11 @@ restart:
1539 BUG(); 1556 BUG();
1540 } 1557 }
1541 1558
1542 read_lock(&cfq_exit_lock); 1559 spin_lock(&cfq_exit_lock);
1543 rb_link_node(&cic->rb_node, parent, p); 1560 rb_link_node(&cic->rb_node, parent, p);
1544 rb_insert_color(&cic->rb_node, &ioc->cic_root); 1561 rb_insert_color(&cic->rb_node, &ioc->cic_root);
1545 list_add(&cic->queue_list, &cfqd->cic_list); 1562 list_add(&cic->queue_list, &cfqd->cic_list);
1546 read_unlock(&cfq_exit_lock); 1563 spin_unlock(&cfq_exit_lock);
1547} 1564}
1548 1565
1549/* 1566/*
@@ -1642,7 +1659,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1642{ 1659{
1643 int enable_idle = cfq_cfqq_idle_window(cfqq); 1660 int enable_idle = cfq_cfqq_idle_window(cfqq);
1644 1661
1645 if (!cic->ioc->task || !cfqd->cfq_slice_idle) 1662 if (!cic->ioc->task || !cfqd->cfq_slice_idle || cfqd->hw_tag)
1646 enable_idle = 0; 1663 enable_idle = 0;
1647 else if (sample_valid(cic->ttime_samples)) { 1664 else if (sample_valid(cic->ttime_samples)) {
1648 if (cic->ttime_mean > cfqd->cfq_slice_idle) 1665 if (cic->ttime_mean > cfqd->cfq_slice_idle)
@@ -1733,14 +1750,24 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1733 1750
1734 cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq); 1751 cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq);
1735 1752
1753 cic = crq->io_context;
1754
1736 /* 1755 /*
1737 * we never wait for an async request and we don't allow preemption 1756 * we never wait for an async request and we don't allow preemption
1738 * of an async request. so just return early 1757 * of an async request. so just return early
1739 */ 1758 */
1740 if (!cfq_crq_is_sync(crq)) 1759 if (!cfq_crq_is_sync(crq)) {
1760 /*
1761 * sync process issued an async request, if it's waiting
1762 * then expire it and kick rq handling.
1763 */
1764 if (cic == cfqd->active_cic &&
1765 del_timer(&cfqd->idle_slice_timer)) {
1766 cfq_slice_expired(cfqd, 0);
1767 cfq_start_queueing(cfqd, cfqq);
1768 }
1741 return; 1769 return;
1742 1770 }
1743 cic = crq->io_context;
1744 1771
1745 cfq_update_io_thinktime(cfqd, cic); 1772 cfq_update_io_thinktime(cfqd, cic);
1746 cfq_update_io_seektime(cfqd, cic, crq); 1773 cfq_update_io_seektime(cfqd, cic, crq);
@@ -2158,10 +2185,9 @@ static void cfq_idle_class_timer(unsigned long data)
2158 * race with a non-idle queue, reset timer 2185 * race with a non-idle queue, reset timer
2159 */ 2186 */
2160 end = cfqd->last_end_request + CFQ_IDLE_GRACE; 2187 end = cfqd->last_end_request + CFQ_IDLE_GRACE;
2161 if (!time_after_eq(jiffies, end)) { 2188 if (!time_after_eq(jiffies, end))
2162 cfqd->idle_class_timer.expires = end; 2189 mod_timer(&cfqd->idle_class_timer, end);
2163 add_timer(&cfqd->idle_class_timer); 2190 else
2164 } else
2165 cfq_schedule_dispatch(cfqd); 2191 cfq_schedule_dispatch(cfqd);
2166 2192
2167 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags); 2193 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
@@ -2181,7 +2207,7 @@ static void cfq_exit_queue(elevator_t *e)
2181 2207
2182 cfq_shutdown_timer_wq(cfqd); 2208 cfq_shutdown_timer_wq(cfqd);
2183 2209
2184 write_lock(&cfq_exit_lock); 2210 spin_lock(&cfq_exit_lock);
2185 spin_lock_irq(q->queue_lock); 2211 spin_lock_irq(q->queue_lock);
2186 2212
2187 if (cfqd->active_queue) 2213 if (cfqd->active_queue)
@@ -2204,7 +2230,7 @@ static void cfq_exit_queue(elevator_t *e)
2204 } 2230 }
2205 2231
2206 spin_unlock_irq(q->queue_lock); 2232 spin_unlock_irq(q->queue_lock);
2207 write_unlock(&cfq_exit_lock); 2233 spin_unlock(&cfq_exit_lock);
2208 2234
2209 cfq_shutdown_timer_wq(cfqd); 2235 cfq_shutdown_timer_wq(cfqd);
2210 2236
@@ -2214,14 +2240,14 @@ static void cfq_exit_queue(elevator_t *e)
2214 kfree(cfqd); 2240 kfree(cfqd);
2215} 2241}
2216 2242
2217static int cfq_init_queue(request_queue_t *q, elevator_t *e) 2243static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
2218{ 2244{
2219 struct cfq_data *cfqd; 2245 struct cfq_data *cfqd;
2220 int i; 2246 int i;
2221 2247
2222 cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL); 2248 cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL);
2223 if (!cfqd) 2249 if (!cfqd)
2224 return -ENOMEM; 2250 return NULL;
2225 2251
2226 memset(cfqd, 0, sizeof(*cfqd)); 2252 memset(cfqd, 0, sizeof(*cfqd));
2227 2253
@@ -2251,8 +2277,6 @@ static int cfq_init_queue(request_queue_t *q, elevator_t *e)
2251 for (i = 0; i < CFQ_QHASH_ENTRIES; i++) 2277 for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
2252 INIT_HLIST_HEAD(&cfqd->cfq_hash[i]); 2278 INIT_HLIST_HEAD(&cfqd->cfq_hash[i]);
2253 2279
2254 e->elevator_data = cfqd;
2255
2256 cfqd->queue = q; 2280 cfqd->queue = q;
2257 2281
2258 cfqd->max_queued = q->nr_requests / 4; 2282 cfqd->max_queued = q->nr_requests / 4;
@@ -2279,14 +2303,14 @@ static int cfq_init_queue(request_queue_t *q, elevator_t *e)
2279 cfqd->cfq_slice_async_rq = cfq_slice_async_rq; 2303 cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
2280 cfqd->cfq_slice_idle = cfq_slice_idle; 2304 cfqd->cfq_slice_idle = cfq_slice_idle;
2281 2305
2282 return 0; 2306 return cfqd;
2283out_crqpool: 2307out_crqpool:
2284 kfree(cfqd->cfq_hash); 2308 kfree(cfqd->cfq_hash);
2285out_cfqhash: 2309out_cfqhash:
2286 kfree(cfqd->crq_hash); 2310 kfree(cfqd->crq_hash);
2287out_crqhash: 2311out_crqhash:
2288 kfree(cfqd); 2312 kfree(cfqd);
2289 return -ENOMEM; 2313 return NULL;
2290} 2314}
2291 2315
2292static void cfq_slab_kill(void) 2316static void cfq_slab_kill(void)
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index 06962d8402a3..c94de8e12fbf 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -612,24 +612,24 @@ static void deadline_exit_queue(elevator_t *e)
612 * initialize elevator private data (deadline_data), and alloc a drq for 612 * initialize elevator private data (deadline_data), and alloc a drq for
613 * each request on the free lists 613 * each request on the free lists
614 */ 614 */
615static int deadline_init_queue(request_queue_t *q, elevator_t *e) 615static void *deadline_init_queue(request_queue_t *q, elevator_t *e)
616{ 616{
617 struct deadline_data *dd; 617 struct deadline_data *dd;
618 int i; 618 int i;
619 619
620 if (!drq_pool) 620 if (!drq_pool)
621 return -ENOMEM; 621 return NULL;
622 622
623 dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node); 623 dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
624 if (!dd) 624 if (!dd)
625 return -ENOMEM; 625 return NULL;
626 memset(dd, 0, sizeof(*dd)); 626 memset(dd, 0, sizeof(*dd));
627 627
628 dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES, 628 dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES,
629 GFP_KERNEL, q->node); 629 GFP_KERNEL, q->node);
630 if (!dd->hash) { 630 if (!dd->hash) {
631 kfree(dd); 631 kfree(dd);
632 return -ENOMEM; 632 return NULL;
633 } 633 }
634 634
635 dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, 635 dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
@@ -637,7 +637,7 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
637 if (!dd->drq_pool) { 637 if (!dd->drq_pool) {
638 kfree(dd->hash); 638 kfree(dd->hash);
639 kfree(dd); 639 kfree(dd);
640 return -ENOMEM; 640 return NULL;
641 } 641 }
642 642
643 for (i = 0; i < DL_HASH_ENTRIES; i++) 643 for (i = 0; i < DL_HASH_ENTRIES; i++)
@@ -652,8 +652,7 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
652 dd->writes_starved = writes_starved; 652 dd->writes_starved = writes_starved;
653 dd->front_merges = 1; 653 dd->front_merges = 1;
654 dd->fifo_batch = fifo_batch; 654 dd->fifo_batch = fifo_batch;
655 e->elevator_data = dd; 655 return dd;
656 return 0;
657} 656}
658 657
659static void deadline_put_request(request_queue_t *q, struct request *rq) 658static void deadline_put_request(request_queue_t *q, struct request *rq)
diff --git a/block/elevator.c b/block/elevator.c
index 29825792cbd5..a0afdd317cef 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -121,16 +121,16 @@ static struct elevator_type *elevator_get(const char *name)
121 return e; 121 return e;
122} 122}
123 123
124static int elevator_attach(request_queue_t *q, struct elevator_queue *eq) 124static void *elevator_init_queue(request_queue_t *q, struct elevator_queue *eq)
125{ 125{
126 int ret = 0; 126 return eq->ops->elevator_init_fn(q, eq);
127}
127 128
129static void elevator_attach(request_queue_t *q, struct elevator_queue *eq,
130 void *data)
131{
128 q->elevator = eq; 132 q->elevator = eq;
129 133 eq->elevator_data = data;
130 if (eq->ops->elevator_init_fn)
131 ret = eq->ops->elevator_init_fn(q, eq);
132
133 return ret;
134} 134}
135 135
136static char chosen_elevator[16]; 136static char chosen_elevator[16];
@@ -181,6 +181,7 @@ int elevator_init(request_queue_t *q, char *name)
181 struct elevator_type *e = NULL; 181 struct elevator_type *e = NULL;
182 struct elevator_queue *eq; 182 struct elevator_queue *eq;
183 int ret = 0; 183 int ret = 0;
184 void *data;
184 185
185 INIT_LIST_HEAD(&q->queue_head); 186 INIT_LIST_HEAD(&q->queue_head);
186 q->last_merge = NULL; 187 q->last_merge = NULL;
@@ -202,10 +203,13 @@ int elevator_init(request_queue_t *q, char *name)
202 if (!eq) 203 if (!eq)
203 return -ENOMEM; 204 return -ENOMEM;
204 205
205 ret = elevator_attach(q, eq); 206 data = elevator_init_queue(q, eq);
206 if (ret) 207 if (!data) {
207 kobject_put(&eq->kobj); 208 kobject_put(&eq->kobj);
209 return -ENOMEM;
210 }
208 211
212 elevator_attach(q, eq, data);
209 return ret; 213 return ret;
210} 214}
211 215
@@ -333,6 +337,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
333{ 337{
334 struct list_head *pos; 338 struct list_head *pos;
335 unsigned ordseq; 339 unsigned ordseq;
340 int unplug_it = 1;
336 341
337 blk_add_trace_rq(q, rq, BLK_TA_INSERT); 342 blk_add_trace_rq(q, rq, BLK_TA_INSERT);
338 343
@@ -399,6 +404,11 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
399 } 404 }
400 405
401 list_add_tail(&rq->queuelist, pos); 406 list_add_tail(&rq->queuelist, pos);
407 /*
408 * most requeues happen because of a busy condition, don't
409 * force unplug of the queue for that case.
410 */
411 unplug_it = 0;
402 break; 412 break;
403 413
404 default: 414 default:
@@ -407,7 +417,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
407 BUG(); 417 BUG();
408 } 418 }
409 419
410 if (blk_queue_plugged(q)) { 420 if (unplug_it && blk_queue_plugged(q)) {
411 int nrq = q->rq.count[READ] + q->rq.count[WRITE] 421 int nrq = q->rq.count[READ] + q->rq.count[WRITE]
412 - q->in_flight; 422 - q->in_flight;
413 423
@@ -716,13 +726,16 @@ int elv_register_queue(struct request_queue *q)
716 return error; 726 return error;
717} 727}
718 728
729static void __elv_unregister_queue(elevator_t *e)
730{
731 kobject_uevent(&e->kobj, KOBJ_REMOVE);
732 kobject_del(&e->kobj);
733}
734
719void elv_unregister_queue(struct request_queue *q) 735void elv_unregister_queue(struct request_queue *q)
720{ 736{
721 if (q) { 737 if (q)
722 elevator_t *e = q->elevator; 738 __elv_unregister_queue(q->elevator);
723 kobject_uevent(&e->kobj, KOBJ_REMOVE);
724 kobject_del(&e->kobj);
725 }
726} 739}
727 740
728int elv_register(struct elevator_type *e) 741int elv_register(struct elevator_type *e)
@@ -774,6 +787,7 @@ EXPORT_SYMBOL_GPL(elv_unregister);
774static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) 787static int elevator_switch(request_queue_t *q, struct elevator_type *new_e)
775{ 788{
776 elevator_t *old_elevator, *e; 789 elevator_t *old_elevator, *e;
790 void *data;
777 791
778 /* 792 /*
779 * Allocate new elevator 793 * Allocate new elevator
@@ -782,6 +796,12 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e)
782 if (!e) 796 if (!e)
783 return 0; 797 return 0;
784 798
799 data = elevator_init_queue(q, e);
800 if (!data) {
801 kobject_put(&e->kobj);
802 return 0;
803 }
804
785 /* 805 /*
786 * Turn on BYPASS and drain all requests w/ elevator private data 806 * Turn on BYPASS and drain all requests w/ elevator private data
787 */ 807 */
@@ -800,19 +820,19 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e)
800 elv_drain_elevator(q); 820 elv_drain_elevator(q);
801 } 821 }
802 822
803 spin_unlock_irq(q->queue_lock);
804
805 /* 823 /*
806 * unregister old elevator data 824 * Remember old elevator.
807 */ 825 */
808 elv_unregister_queue(q);
809 old_elevator = q->elevator; 826 old_elevator = q->elevator;
810 827
811 /* 828 /*
812 * attach and start new elevator 829 * attach and start new elevator
813 */ 830 */
814 if (elevator_attach(q, e)) 831 elevator_attach(q, e, data);
815 goto fail; 832
833 spin_unlock_irq(q->queue_lock);
834
835 __elv_unregister_queue(old_elevator);
816 836
817 if (elv_register_queue(q)) 837 if (elv_register_queue(q))
818 goto fail_register; 838 goto fail_register;
@@ -831,7 +851,6 @@ fail_register:
831 */ 851 */
832 elevator_exit(e); 852 elevator_exit(e);
833 e = NULL; 853 e = NULL;
834fail:
835 q->elevator = old_elevator; 854 q->elevator = old_elevator;
836 elv_register_queue(q); 855 elv_register_queue(q);
837 clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); 856 clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 1755c053fd68..7eb36c53f4b7 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1732,8 +1732,21 @@ void blk_run_queue(struct request_queue *q)
1732 1732
1733 spin_lock_irqsave(q->queue_lock, flags); 1733 spin_lock_irqsave(q->queue_lock, flags);
1734 blk_remove_plug(q); 1734 blk_remove_plug(q);
1735 if (!elv_queue_empty(q)) 1735
1736 q->request_fn(q); 1736 /*
1737 * Only recurse once to avoid overrunning the stack, let the unplug
1738 * handling reinvoke the handler shortly if we already got there.
1739 */
1740 if (!elv_queue_empty(q)) {
1741 if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
1742 q->request_fn(q);
1743 clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
1744 } else {
1745 blk_plug_device(q);
1746 kblockd_schedule_work(&q->unplug_work);
1747 }
1748 }
1749
1737 spin_unlock_irqrestore(q->queue_lock, flags); 1750 spin_unlock_irqrestore(q->queue_lock, flags);
1738} 1751}
1739EXPORT_SYMBOL(blk_run_queue); 1752EXPORT_SYMBOL(blk_run_queue);
@@ -3385,7 +3398,7 @@ static int blk_cpu_notify(struct notifier_block *self, unsigned long action,
3385} 3398}
3386 3399
3387 3400
3388static struct notifier_block __devinitdata blk_cpu_notifier = { 3401static struct notifier_block blk_cpu_notifier = {
3389 .notifier_call = blk_cpu_notify, 3402 .notifier_call = blk_cpu_notify,
3390}; 3403};
3391 3404
@@ -3439,7 +3452,12 @@ void end_that_request_last(struct request *req, int uptodate)
3439 if (unlikely(laptop_mode) && blk_fs_request(req)) 3452 if (unlikely(laptop_mode) && blk_fs_request(req))
3440 laptop_io_completion(); 3453 laptop_io_completion();
3441 3454
3442 if (disk && blk_fs_request(req)) { 3455 /*
3456 * Account IO completion. bar_rq isn't accounted as a normal
3457 * IO on queueing nor completion. Accounting the containing
3458 * request is enough.
3459 */
3460 if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
3443 unsigned long duration = jiffies - req->start_time; 3461 unsigned long duration = jiffies - req->start_time;
3444 const int rw = rq_data_dir(req); 3462 const int rw = rq_data_dir(req);
3445 3463
diff --git a/block/noop-iosched.c b/block/noop-iosched.c
index f370e4a7fe6d..56a7c620574f 100644
--- a/block/noop-iosched.c
+++ b/block/noop-iosched.c
@@ -65,16 +65,15 @@ noop_latter_request(request_queue_t *q, struct request *rq)
65 return list_entry(rq->queuelist.next, struct request, queuelist); 65 return list_entry(rq->queuelist.next, struct request, queuelist);
66} 66}
67 67
68static int noop_init_queue(request_queue_t *q, elevator_t *e) 68static void *noop_init_queue(request_queue_t *q, elevator_t *e)
69{ 69{
70 struct noop_data *nd; 70 struct noop_data *nd;
71 71
72 nd = kmalloc(sizeof(*nd), GFP_KERNEL); 72 nd = kmalloc(sizeof(*nd), GFP_KERNEL);
73 if (!nd) 73 if (!nd)
74 return -ENOMEM; 74 return NULL;
75 INIT_LIST_HEAD(&nd->queue); 75 INIT_LIST_HEAD(&nd->queue);
76 e->elevator_data = nd; 76 return nd;
77 return 0;
78} 77}
79 78
80static void noop_exit_queue(elevator_t *e) 79static void noop_exit_queue(elevator_t *e)