aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c300
1 files changed, 250 insertions, 50 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index a4809de6fea6..a55a9bd75bd1 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -56,9 +56,6 @@ static DEFINE_SPINLOCK(ioc_gone_lock);
56#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) 56#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
57#define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT) 57#define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
58 58
59#define ASYNC (0)
60#define SYNC (1)
61
62#define sample_valid(samples) ((samples) > 80) 59#define sample_valid(samples) ((samples) > 80)
63 60
64/* 61/*
@@ -83,6 +80,14 @@ struct cfq_data {
83 * rr list of queues with requests and the count of them 80 * rr list of queues with requests and the count of them
84 */ 81 */
85 struct cfq_rb_root service_tree; 82 struct cfq_rb_root service_tree;
83
84 /*
85 * Each priority tree is sorted by next_request position. These
86 * trees are used when determining if two or more queues are
87 * interleaving requests (see cfq_close_cooperator).
88 */
89 struct rb_root prio_trees[CFQ_PRIO_LISTS];
90
86 unsigned int busy_queues; 91 unsigned int busy_queues;
87 /* 92 /*
88 * Used to track any pending rt requests so we can pre-empt current 93 * Used to track any pending rt requests so we can pre-empt current
@@ -147,6 +152,10 @@ struct cfq_queue {
147 struct rb_node rb_node; 152 struct rb_node rb_node;
148 /* service_tree key */ 153 /* service_tree key */
149 unsigned long rb_key; 154 unsigned long rb_key;
155 /* prio tree member */
156 struct rb_node p_node;
157 /* prio tree root we belong to, if any */
158 struct rb_root *p_root;
150 /* sorted list of pending requests */ 159 /* sorted list of pending requests */
151 struct rb_root sort_list; 160 struct rb_root sort_list;
152 /* if fifo isn't expired, next request to serve */ 161 /* if fifo isn't expired, next request to serve */
@@ -185,6 +194,7 @@ enum cfqq_state_flags {
185 CFQ_CFQQ_FLAG_prio_changed, /* task priority has changed */ 194 CFQ_CFQQ_FLAG_prio_changed, /* task priority has changed */
186 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ 195 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */
187 CFQ_CFQQ_FLAG_sync, /* synchronous queue */ 196 CFQ_CFQQ_FLAG_sync, /* synchronous queue */
197 CFQ_CFQQ_FLAG_coop, /* has done a coop jump of the queue */
188}; 198};
189 199
190#define CFQ_CFQQ_FNS(name) \ 200#define CFQ_CFQQ_FNS(name) \
@@ -211,6 +221,7 @@ CFQ_CFQQ_FNS(idle_window);
211CFQ_CFQQ_FNS(prio_changed); 221CFQ_CFQQ_FNS(prio_changed);
212CFQ_CFQQ_FNS(slice_new); 222CFQ_CFQQ_FNS(slice_new);
213CFQ_CFQQ_FNS(sync); 223CFQ_CFQQ_FNS(sync);
224CFQ_CFQQ_FNS(coop);
214#undef CFQ_CFQQ_FNS 225#undef CFQ_CFQQ_FNS
215 226
216#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \ 227#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \
@@ -419,13 +430,17 @@ static struct cfq_queue *cfq_rb_first(struct cfq_rb_root *root)
419 return NULL; 430 return NULL;
420} 431}
421 432
433static void rb_erase_init(struct rb_node *n, struct rb_root *root)
434{
435 rb_erase(n, root);
436 RB_CLEAR_NODE(n);
437}
438
422static void cfq_rb_erase(struct rb_node *n, struct cfq_rb_root *root) 439static void cfq_rb_erase(struct rb_node *n, struct cfq_rb_root *root)
423{ 440{
424 if (root->left == n) 441 if (root->left == n)
425 root->left = NULL; 442 root->left = NULL;
426 443 rb_erase_init(n, &root->rb);
427 rb_erase(n, &root->rb);
428 RB_CLEAR_NODE(n);
429} 444}
430 445
431/* 446/*
@@ -470,8 +485,8 @@ static unsigned long cfq_slice_offset(struct cfq_data *cfqd,
470 * requests waiting to be processed. It is sorted in the order that 485 * requests waiting to be processed. It is sorted in the order that
471 * we will service the queues. 486 * we will service the queues.
472 */ 487 */
473static void cfq_service_tree_add(struct cfq_data *cfqd, 488static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
474 struct cfq_queue *cfqq, int add_front) 489 int add_front)
475{ 490{
476 struct rb_node **p, *parent; 491 struct rb_node **p, *parent;
477 struct cfq_queue *__cfqq; 492 struct cfq_queue *__cfqq;
@@ -544,6 +559,67 @@ static void cfq_service_tree_add(struct cfq_data *cfqd,
544 rb_insert_color(&cfqq->rb_node, &cfqd->service_tree.rb); 559 rb_insert_color(&cfqq->rb_node, &cfqd->service_tree.rb);
545} 560}
546 561
562static struct cfq_queue *
563cfq_prio_tree_lookup(struct cfq_data *cfqd, struct rb_root *root,
564 sector_t sector, struct rb_node **ret_parent,
565 struct rb_node ***rb_link)
566{
567 struct rb_node **p, *parent;
568 struct cfq_queue *cfqq = NULL;
569
570 parent = NULL;
571 p = &root->rb_node;
572 while (*p) {
573 struct rb_node **n;
574
575 parent = *p;
576 cfqq = rb_entry(parent, struct cfq_queue, p_node);
577
578 /*
579 * Sort strictly based on sector. Smallest to the left,
580 * largest to the right.
581 */
582 if (sector > cfqq->next_rq->sector)
583 n = &(*p)->rb_right;
584 else if (sector < cfqq->next_rq->sector)
585 n = &(*p)->rb_left;
586 else
587 break;
588 p = n;
589 cfqq = NULL;
590 }
591
592 *ret_parent = parent;
593 if (rb_link)
594 *rb_link = p;
595 return cfqq;
596}
597
598static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq)
599{
600 struct rb_node **p, *parent;
601 struct cfq_queue *__cfqq;
602
603 if (cfqq->p_root) {
604 rb_erase(&cfqq->p_node, cfqq->p_root);
605 cfqq->p_root = NULL;
606 }
607
608 if (cfq_class_idle(cfqq))
609 return;
610 if (!cfqq->next_rq)
611 return;
612
613 cfqq->p_root = &cfqd->prio_trees[cfqq->org_ioprio];
614 __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->p_root, cfqq->next_rq->sector,
615 &parent, &p);
616 if (!__cfqq) {
617 rb_link_node(&cfqq->p_node, parent, p);
618 rb_insert_color(&cfqq->p_node, cfqq->p_root);
619 } else
620 cfqq->p_root = NULL;
621}
622
547/* 623/*
548 * Update cfqq's position in the service tree. 624 * Update cfqq's position in the service tree.
549 */ 625 */
@@ -552,8 +628,10 @@ static void cfq_resort_rr_list(struct cfq_data *cfqd, struct cfq_queue *cfqq)
552 /* 628 /*
553 * Resorting requires the cfqq to be on the RR list already. 629 * Resorting requires the cfqq to be on the RR list already.
554 */ 630 */
555 if (cfq_cfqq_on_rr(cfqq)) 631 if (cfq_cfqq_on_rr(cfqq)) {
556 cfq_service_tree_add(cfqd, cfqq, 0); 632 cfq_service_tree_add(cfqd, cfqq, 0);
633 cfq_prio_tree_add(cfqd, cfqq);
634 }
557} 635}
558 636
559/* 637/*
@@ -584,6 +662,10 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
584 662
585 if (!RB_EMPTY_NODE(&cfqq->rb_node)) 663 if (!RB_EMPTY_NODE(&cfqq->rb_node))
586 cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree); 664 cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree);
665 if (cfqq->p_root) {
666 rb_erase(&cfqq->p_node, cfqq->p_root);
667 cfqq->p_root = NULL;
668 }
587 669
588 BUG_ON(!cfqd->busy_queues); 670 BUG_ON(!cfqd->busy_queues);
589 cfqd->busy_queues--; 671 cfqd->busy_queues--;
@@ -613,7 +695,7 @@ static void cfq_add_rq_rb(struct request *rq)
613{ 695{
614 struct cfq_queue *cfqq = RQ_CFQQ(rq); 696 struct cfq_queue *cfqq = RQ_CFQQ(rq);
615 struct cfq_data *cfqd = cfqq->cfqd; 697 struct cfq_data *cfqd = cfqq->cfqd;
616 struct request *__alias; 698 struct request *__alias, *prev;
617 699
618 cfqq->queued[rq_is_sync(rq)]++; 700 cfqq->queued[rq_is_sync(rq)]++;
619 701
@@ -630,7 +712,15 @@ static void cfq_add_rq_rb(struct request *rq)
630 /* 712 /*
631 * check if this request is a better next-serve candidate 713 * check if this request is a better next-serve candidate
632 */ 714 */
715 prev = cfqq->next_rq;
633 cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); 716 cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq);
717
718 /*
719 * adjust priority tree position, if ->next_rq changes
720 */
721 if (prev != cfqq->next_rq)
722 cfq_prio_tree_add(cfqd, cfqq);
723
634 BUG_ON(!cfqq->next_rq); 724 BUG_ON(!cfqq->next_rq);
635} 725}
636 726
@@ -843,11 +933,15 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
843/* 933/*
844 * Get and set a new active queue for service. 934 * Get and set a new active queue for service.
845 */ 935 */
846static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd) 936static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd,
937 struct cfq_queue *cfqq)
847{ 938{
848 struct cfq_queue *cfqq; 939 if (!cfqq) {
940 cfqq = cfq_get_next_queue(cfqd);
941 if (cfqq)
942 cfq_clear_cfqq_coop(cfqq);
943 }
849 944
850 cfqq = cfq_get_next_queue(cfqd);
851 __cfq_set_active_queue(cfqd, cfqq); 945 __cfq_set_active_queue(cfqd, cfqq);
852 return cfqq; 946 return cfqq;
853} 947}
@@ -861,28 +955,100 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,
861 return cfqd->last_position - rq->sector; 955 return cfqd->last_position - rq->sector;
862} 956}
863 957
958#define CIC_SEEK_THR 8 * 1024
959#define CIC_SEEKY(cic) ((cic)->seek_mean > CIC_SEEK_THR)
960
864static inline int cfq_rq_close(struct cfq_data *cfqd, struct request *rq) 961static inline int cfq_rq_close(struct cfq_data *cfqd, struct request *rq)
865{ 962{
866 struct cfq_io_context *cic = cfqd->active_cic; 963 struct cfq_io_context *cic = cfqd->active_cic;
964 sector_t sdist = cic->seek_mean;
867 965
868 if (!sample_valid(cic->seek_samples)) 966 if (!sample_valid(cic->seek_samples))
869 return 0; 967 sdist = CIC_SEEK_THR;
968
969 return cfq_dist_from_last(cfqd, rq) <= sdist;
970}
971
972static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
973 struct cfq_queue *cur_cfqq)
974{
975 struct rb_root *root = &cfqd->prio_trees[cur_cfqq->org_ioprio];
976 struct rb_node *parent, *node;
977 struct cfq_queue *__cfqq;
978 sector_t sector = cfqd->last_position;
979
980 if (RB_EMPTY_ROOT(root))
981 return NULL;
982
983 /*
984 * First, if we find a request starting at the end of the last
985 * request, choose it.
986 */
987 __cfqq = cfq_prio_tree_lookup(cfqd, root, sector, &parent, NULL);
988 if (__cfqq)
989 return __cfqq;
990
991 /*
992 * If the exact sector wasn't found, the parent of the NULL leaf
993 * will contain the closest sector.
994 */
995 __cfqq = rb_entry(parent, struct cfq_queue, p_node);
996 if (cfq_rq_close(cfqd, __cfqq->next_rq))
997 return __cfqq;
998
999 if (__cfqq->next_rq->sector < sector)
1000 node = rb_next(&__cfqq->p_node);
1001 else
1002 node = rb_prev(&__cfqq->p_node);
1003 if (!node)
1004 return NULL;
870 1005
871 return cfq_dist_from_last(cfqd, rq) <= cic->seek_mean; 1006 __cfqq = rb_entry(node, struct cfq_queue, p_node);
1007 if (cfq_rq_close(cfqd, __cfqq->next_rq))
1008 return __cfqq;
1009
1010 return NULL;
872} 1011}
873 1012
874static int cfq_close_cooperator(struct cfq_data *cfq_data, 1013/*
875 struct cfq_queue *cfqq) 1014 * cfqd - obvious
1015 * cur_cfqq - passed in so that we don't decide that the current queue is
1016 * closely cooperating with itself.
1017 *
1018 * So, basically we're assuming that that cur_cfqq has dispatched at least
1019 * one request, and that cfqd->last_position reflects a position on the disk
1020 * associated with the I/O issued by cur_cfqq. I'm not sure this is a valid
1021 * assumption.
1022 */
1023static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
1024 struct cfq_queue *cur_cfqq,
1025 int probe)
876{ 1026{
1027 struct cfq_queue *cfqq;
1028
1029 /*
1030 * A valid cfq_io_context is necessary to compare requests against
1031 * the seek_mean of the current cfqq.
1032 */
1033 if (!cfqd->active_cic)
1034 return NULL;
1035
877 /* 1036 /*
878 * We should notice if some of the queues are cooperating, eg 1037 * We should notice if some of the queues are cooperating, eg
879 * working closely on the same area of the disk. In that case, 1038 * working closely on the same area of the disk. In that case,
880 * we can group them together and don't waste time idling. 1039 * we can group them together and don't waste time idling.
881 */ 1040 */
882 return 0; 1041 cfqq = cfqq_close(cfqd, cur_cfqq);
883} 1042 if (!cfqq)
1043 return NULL;
884 1044
885#define CIC_SEEKY(cic) ((cic)->seek_mean > (8 * 1024)) 1045 if (cfq_cfqq_coop(cfqq))
1046 return NULL;
1047
1048 if (!probe)
1049 cfq_mark_cfqq_coop(cfqq);
1050 return cfqq;
1051}
886 1052
887static void cfq_arm_slice_timer(struct cfq_data *cfqd) 1053static void cfq_arm_slice_timer(struct cfq_data *cfqd)
888{ 1054{
@@ -920,13 +1086,6 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
920 if (!cic || !atomic_read(&cic->ioc->nr_tasks)) 1086 if (!cic || !atomic_read(&cic->ioc->nr_tasks))
921 return; 1087 return;
922 1088
923 /*
924 * See if this prio level has a good candidate
925 */
926 if (cfq_close_cooperator(cfqd, cfqq) &&
927 (sample_valid(cic->ttime_samples) && cic->ttime_mean > 2))
928 return;
929
930 cfq_mark_cfqq_wait_request(cfqq); 1089 cfq_mark_cfqq_wait_request(cfqq);
931 1090
932 /* 1091 /*
@@ -939,7 +1098,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
939 sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT)); 1098 sl = min(sl, msecs_to_jiffies(CFQ_MIN_TT));
940 1099
941 mod_timer(&cfqd->idle_slice_timer, jiffies + sl); 1100 mod_timer(&cfqd->idle_slice_timer, jiffies + sl);
942 cfq_log(cfqd, "arm_idle: %lu", sl); 1101 cfq_log_cfqq(cfqd, cfqq, "arm_idle: %lu", sl);
943} 1102}
944 1103
945/* 1104/*
@@ -1003,7 +1162,7 @@ cfq_prio_to_maxrq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1003 */ 1162 */
1004static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) 1163static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
1005{ 1164{
1006 struct cfq_queue *cfqq; 1165 struct cfq_queue *cfqq, *new_cfqq = NULL;
1007 1166
1008 cfqq = cfqd->active_queue; 1167 cfqq = cfqd->active_queue;
1009 if (!cfqq) 1168 if (!cfqq)
@@ -1037,6 +1196,16 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
1037 goto keep_queue; 1196 goto keep_queue;
1038 1197
1039 /* 1198 /*
1199 * If another queue has a request waiting within our mean seek
1200 * distance, let it run. The expire code will check for close
1201 * cooperators and put the close queue at the front of the service
1202 * tree.
1203 */
1204 new_cfqq = cfq_close_cooperator(cfqd, cfqq, 0);
1205 if (new_cfqq)
1206 goto expire;
1207
1208 /*
1040 * No requests pending. If the active queue still has requests in 1209 * No requests pending. If the active queue still has requests in
1041 * flight or is idling for a new request, allow either of these 1210 * flight or is idling for a new request, allow either of these
1042 * conditions to happen (or time out) before selecting a new queue. 1211 * conditions to happen (or time out) before selecting a new queue.
@@ -1050,7 +1219,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
1050expire: 1219expire:
1051 cfq_slice_expired(cfqd, 0); 1220 cfq_slice_expired(cfqd, 0);
1052new_queue: 1221new_queue:
1053 cfqq = cfq_set_active_queue(cfqd); 1222 cfqq = cfq_set_active_queue(cfqd, new_cfqq);
1054keep_queue: 1223keep_queue:
1055 return cfqq; 1224 return cfqq;
1056} 1225}
@@ -1333,14 +1502,14 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
1333 if (ioc->ioc_data == cic) 1502 if (ioc->ioc_data == cic)
1334 rcu_assign_pointer(ioc->ioc_data, NULL); 1503 rcu_assign_pointer(ioc->ioc_data, NULL);
1335 1504
1336 if (cic->cfqq[ASYNC]) { 1505 if (cic->cfqq[BLK_RW_ASYNC]) {
1337 cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]); 1506 cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]);
1338 cic->cfqq[ASYNC] = NULL; 1507 cic->cfqq[BLK_RW_ASYNC] = NULL;
1339 } 1508 }
1340 1509
1341 if (cic->cfqq[SYNC]) { 1510 if (cic->cfqq[BLK_RW_SYNC]) {
1342 cfq_exit_cfqq(cfqd, cic->cfqq[SYNC]); 1511 cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_SYNC]);
1343 cic->cfqq[SYNC] = NULL; 1512 cic->cfqq[BLK_RW_SYNC] = NULL;
1344 } 1513 }
1345} 1514}
1346 1515
@@ -1449,17 +1618,18 @@ static void changed_ioprio(struct io_context *ioc, struct cfq_io_context *cic)
1449 1618
1450 spin_lock_irqsave(cfqd->queue->queue_lock, flags); 1619 spin_lock_irqsave(cfqd->queue->queue_lock, flags);
1451 1620
1452 cfqq = cic->cfqq[ASYNC]; 1621 cfqq = cic->cfqq[BLK_RW_ASYNC];
1453 if (cfqq) { 1622 if (cfqq) {
1454 struct cfq_queue *new_cfqq; 1623 struct cfq_queue *new_cfqq;
1455 new_cfqq = cfq_get_queue(cfqd, ASYNC, cic->ioc, GFP_ATOMIC); 1624 new_cfqq = cfq_get_queue(cfqd, BLK_RW_ASYNC, cic->ioc,
1625 GFP_ATOMIC);
1456 if (new_cfqq) { 1626 if (new_cfqq) {
1457 cic->cfqq[ASYNC] = new_cfqq; 1627 cic->cfqq[BLK_RW_ASYNC] = new_cfqq;
1458 cfq_put_queue(cfqq); 1628 cfq_put_queue(cfqq);
1459 } 1629 }
1460 } 1630 }
1461 1631
1462 cfqq = cic->cfqq[SYNC]; 1632 cfqq = cic->cfqq[BLK_RW_SYNC];
1463 if (cfqq) 1633 if (cfqq)
1464 cfq_mark_cfqq_prio_changed(cfqq); 1634 cfq_mark_cfqq_prio_changed(cfqq);
1465 1635
@@ -1510,6 +1680,7 @@ retry:
1510 } 1680 }
1511 1681
1512 RB_CLEAR_NODE(&cfqq->rb_node); 1682 RB_CLEAR_NODE(&cfqq->rb_node);
1683 RB_CLEAR_NODE(&cfqq->p_node);
1513 INIT_LIST_HEAD(&cfqq->fifo); 1684 INIT_LIST_HEAD(&cfqq->fifo);
1514 1685
1515 atomic_set(&cfqq->ref, 0); 1686 atomic_set(&cfqq->ref, 0);
@@ -1745,7 +1916,9 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic,
1745 sector_t sdist; 1916 sector_t sdist;
1746 u64 total; 1917 u64 total;
1747 1918
1748 if (cic->last_request_pos < rq->sector) 1919 if (!cic->last_request_pos)
1920 sdist = 0;
1921 else if (cic->last_request_pos < rq->sector)
1749 sdist = rq->sector - cic->last_request_pos; 1922 sdist = rq->sector - cic->last_request_pos;
1750 else 1923 else
1751 sdist = cic->last_request_pos - rq->sector; 1924 sdist = cic->last_request_pos - rq->sector;
@@ -1905,10 +2078,20 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1905 * Remember that we saw a request from this process, but 2078 * Remember that we saw a request from this process, but
1906 * don't start queuing just yet. Otherwise we risk seeing lots 2079 * don't start queuing just yet. Otherwise we risk seeing lots
1907 * of tiny requests, because we disrupt the normal plugging 2080 * of tiny requests, because we disrupt the normal plugging
1908 * and merging. 2081 * and merging. If the request is already larger than a single
2082 * page, let it rip immediately. For that case we assume that
2083 * merging is already done. Ditto for a busy system that
2084 * has other work pending, don't risk delaying until the
2085 * idle timer unplug to continue working.
1909 */ 2086 */
1910 if (cfq_cfqq_wait_request(cfqq)) 2087 if (cfq_cfqq_wait_request(cfqq)) {
2088 if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE ||
2089 cfqd->busy_queues > 1) {
2090 del_timer(&cfqd->idle_slice_timer);
2091 blk_start_queueing(cfqd->queue);
2092 }
1911 cfq_mark_cfqq_must_dispatch(cfqq); 2093 cfq_mark_cfqq_must_dispatch(cfqq);
2094 }
1912 } else if (cfq_should_preempt(cfqd, cfqq, rq)) { 2095 } else if (cfq_should_preempt(cfqd, cfqq, rq)) {
1913 /* 2096 /*
1914 * not the active queue - expire current slice if it is 2097 * not the active queue - expire current slice if it is
@@ -1992,16 +2175,24 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
1992 * or if we want to idle in case it has no pending requests. 2175 * or if we want to idle in case it has no pending requests.
1993 */ 2176 */
1994 if (cfqd->active_queue == cfqq) { 2177 if (cfqd->active_queue == cfqq) {
2178 const bool cfqq_empty = RB_EMPTY_ROOT(&cfqq->sort_list);
2179
1995 if (cfq_cfqq_slice_new(cfqq)) { 2180 if (cfq_cfqq_slice_new(cfqq)) {
1996 cfq_set_prio_slice(cfqd, cfqq); 2181 cfq_set_prio_slice(cfqd, cfqq);
1997 cfq_clear_cfqq_slice_new(cfqq); 2182 cfq_clear_cfqq_slice_new(cfqq);
1998 } 2183 }
2184 /*
2185 * If there are no requests waiting in this queue, and
2186 * there are other queues ready to issue requests, AND
2187 * those other queues are issuing requests within our
2188 * mean seek distance, give them a chance to run instead
2189 * of idling.
2190 */
1999 if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq)) 2191 if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
2000 cfq_slice_expired(cfqd, 1); 2192 cfq_slice_expired(cfqd, 1);
2001 else if (sync && !rq_noidle(rq) && 2193 else if (cfqq_empty && !cfq_close_cooperator(cfqd, cfqq, 1) &&
2002 RB_EMPTY_ROOT(&cfqq->sort_list)) { 2194 sync && !rq_noidle(rq))
2003 cfq_arm_slice_timer(cfqd); 2195 cfq_arm_slice_timer(cfqd);
2004 }
2005 } 2196 }
2006 2197
2007 if (!cfqd->rq_in_driver) 2198 if (!cfqd->rq_in_driver)
@@ -2062,7 +2253,7 @@ static int cfq_may_queue(struct request_queue *q, int rw)
2062 if (!cic) 2253 if (!cic)
2063 return ELV_MQUEUE_MAY; 2254 return ELV_MQUEUE_MAY;
2064 2255
2065 cfqq = cic_to_cfqq(cic, rw & REQ_RW_SYNC); 2256 cfqq = cic_to_cfqq(cic, rw_is_sync(rw));
2066 if (cfqq) { 2257 if (cfqq) {
2067 cfq_init_prio_data(cfqq, cic->ioc); 2258 cfq_init_prio_data(cfqq, cic->ioc);
2068 cfq_prio_boost(cfqq); 2259 cfq_prio_boost(cfqq);
@@ -2152,11 +2343,10 @@ static void cfq_kick_queue(struct work_struct *work)
2152 struct cfq_data *cfqd = 2343 struct cfq_data *cfqd =
2153 container_of(work, struct cfq_data, unplug_work); 2344 container_of(work, struct cfq_data, unplug_work);
2154 struct request_queue *q = cfqd->queue; 2345 struct request_queue *q = cfqd->queue;
2155 unsigned long flags;
2156 2346
2157 spin_lock_irqsave(q->queue_lock, flags); 2347 spin_lock_irq(q->queue_lock);
2158 blk_start_queueing(q); 2348 blk_start_queueing(q);
2159 spin_unlock_irqrestore(q->queue_lock, flags); 2349 spin_unlock_irq(q->queue_lock);
2160} 2350}
2161 2351
2162/* 2352/*
@@ -2263,12 +2453,22 @@ static void cfq_exit_queue(struct elevator_queue *e)
2263static void *cfq_init_queue(struct request_queue *q) 2453static void *cfq_init_queue(struct request_queue *q)
2264{ 2454{
2265 struct cfq_data *cfqd; 2455 struct cfq_data *cfqd;
2456 int i;
2266 2457
2267 cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node); 2458 cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
2268 if (!cfqd) 2459 if (!cfqd)
2269 return NULL; 2460 return NULL;
2270 2461
2271 cfqd->service_tree = CFQ_RB_ROOT; 2462 cfqd->service_tree = CFQ_RB_ROOT;
2463
2464 /*
2465 * Not strictly needed (since RB_ROOT just clears the node and we
2466 * zeroed cfqd on alloc), but better be safe in case someone decides
2467 * to add magic to the rb code
2468 */
2469 for (i = 0; i < CFQ_PRIO_LISTS; i++)
2470 cfqd->prio_trees[i] = RB_ROOT;
2471
2272 INIT_LIST_HEAD(&cfqd->cic_list); 2472 INIT_LIST_HEAD(&cfqd->cic_list);
2273 2473
2274 cfqd->queue = q; 2474 cfqd->queue = q;