diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2007-04-23 02:33:33 -0400 |
---|---|---|
committer | Jens Axboe <axboe@nelson.home.kernel.dk> | 2007-04-30 03:01:23 -0400 |
commit | 3ed9a2965c47636bc0ebafab31a39f1c105492ca (patch) | |
tree | 952c5f93f93b88c747f6e1fb15b87a973e7c5b8b | |
parent | 1be92f2fc7b563db3a8909d2d1c6a6520aeca323 (diff) |
cfq-iosched: improve sync vs async workloads
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | block/cfq-iosched.c | 31 |
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 | */ |
912 | static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) | 913 | static 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 | ||