aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-04-23 02:33:33 -0400
committerJens Axboe <axboe@nelson.home.kernel.dk>2007-04-30 03:01:23 -0400
commit3ed9a2965c47636bc0ebafab31a39f1c105492ca (patch)
tree952c5f93f93b88c747f6e1fb15b87a973e7c5b8b
parent1be92f2fc7b563db3a8909d2d1c6a6520aeca323 (diff)
cfq-iosched: improve sync vs async workloads
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/cfq-iosched.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index df82755ac40b..a8237be97a28 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -96,6 +96,7 @@ struct cfq_data {
96 struct hlist_head *cfq_hash; 96 struct hlist_head *cfq_hash;
97 97
98 int rq_in_driver; 98 int rq_in_driver;
99 int sync_flight;
99 int hw_tag; 100 int hw_tag;
100 101
101 /* 102 /*
@@ -911,11 +912,15 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
911 */ 912 */
912static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) 913static void cfq_dispatch_insert(request_queue_t *q, struct request *rq)
913{ 914{
915 struct cfq_data *cfqd = q->elevator->elevator_data;
914 struct cfq_queue *cfqq = RQ_CFQQ(rq); 916 struct cfq_queue *cfqq = RQ_CFQQ(rq);
915 917
916 cfq_remove_request(rq); 918 cfq_remove_request(rq);
917 cfqq->dispatched++; 919 cfqq->dispatched++;
918 elv_dispatch_sort(q, rq); 920 elv_dispatch_sort(q, rq);
921
922 if (cfq_cfqq_sync(cfqq))
923 cfqd->sync_flight++;
919} 924}
920 925
921/* 926/*
@@ -1100,27 +1105,24 @@ static int cfq_dispatch_requests(request_queue_t *q, int force)
1100 while ((cfqq = cfq_select_queue(cfqd)) != NULL) { 1105 while ((cfqq = cfq_select_queue(cfqd)) != NULL) {
1101 int max_dispatch; 1106 int max_dispatch;
1102 1107
1103 if (cfqd->busy_queues > 1) { 1108 max_dispatch = cfqd->cfq_quantum;
1104 /* 1109 if (cfq_class_idle(cfqq))
1105 * So we have dispatched before in this round, if the 1110 max_dispatch = 1;
1106 * next queue has idling enabled (must be sync), don't 1111
1107 * allow it service until the previous have completed. 1112 if (cfqq->dispatched >= max_dispatch) {
1108 */ 1113 if (cfqd->busy_queues > 1)
1109 if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq) &&
1110 dispatched)
1111 break; 1114 break;
1112 if (cfqq->dispatched >= cfqd->cfq_quantum) 1115 if (cfqq->dispatched >= 4 * max_dispatch)
1113 break; 1116 break;
1114 } 1117 }
1115 1118
1119 if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
1120 break;
1121
1116 cfq_clear_cfqq_must_dispatch(cfqq); 1122 cfq_clear_cfqq_must_dispatch(cfqq);
1117 cfq_clear_cfqq_wait_request(cfqq); 1123 cfq_clear_cfqq_wait_request(cfqq);
1118 del_timer(&cfqd->idle_slice_timer); 1124 del_timer(&cfqd->idle_slice_timer);
1119 1125
1120 max_dispatch = cfqd->cfq_quantum;
1121 if (cfq_class_idle(cfqq))
1122 max_dispatch = 1;
1123
1124 dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); 1126 dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
1125 } 1127 }
1126 1128
@@ -1767,6 +1769,9 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq)
1767 cfqd->rq_in_driver--; 1769 cfqd->rq_in_driver--;
1768 cfqq->dispatched--; 1770 cfqq->dispatched--;
1769 1771
1772 if (cfq_cfqq_sync(cfqq))
1773 cfqd->sync_flight--;
1774
1770 if (!cfq_class_idle(cfqq)) 1775 if (!cfq_class_idle(cfqq))
1771 cfqd->last_end_request = now; 1776 cfqd->last_end_request = now;
1772 1777