diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-07-03 06:57:48 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-09-11 08:33:30 -0400 |
commit | 5ad531db6e0f3c3c985666e83d3c1c4d53acccf9 (patch) | |
tree | f5bd394c493f425e12fc6991d2b7adf2121ba506 /block/cfq-iosched.c | |
parent | da6c5c720c52cc717124f8f0830b710ea6a092fd (diff) |
cfq-iosched: drain device queue before switching to a sync queue
To lessen the impact of async IO on sync IO, let the device drain of
any async IO in progress when switching to a sync cfqq that has idling
enabled.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r-- | block/cfq-iosched.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index fd7080ed7935..93693bf6083e 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -140,7 +140,7 @@ struct cfq_data { | |||
140 | */ | 140 | */ |
141 | unsigned int busy_rt_queues; | 141 | unsigned int busy_rt_queues; |
142 | 142 | ||
143 | int rq_in_driver; | 143 | int rq_in_driver[2]; |
144 | int sync_flight; | 144 | int sync_flight; |
145 | 145 | ||
146 | /* | 146 | /* |
@@ -239,6 +239,11 @@ static struct cfq_queue *cfq_get_queue(struct cfq_data *, int, | |||
239 | static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *, | 239 | static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *, |
240 | struct io_context *); | 240 | struct io_context *); |
241 | 241 | ||
242 | static inline int rq_in_driver(struct cfq_data *cfqd) | ||
243 | { | ||
244 | return cfqd->rq_in_driver[0] + cfqd->rq_in_driver[1]; | ||
245 | } | ||
246 | |||
242 | static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic, | 247 | static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic, |
243 | int is_sync) | 248 | int is_sync) |
244 | { | 249 | { |
@@ -760,9 +765,9 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) | |||
760 | { | 765 | { |
761 | struct cfq_data *cfqd = q->elevator->elevator_data; | 766 | struct cfq_data *cfqd = q->elevator->elevator_data; |
762 | 767 | ||
763 | cfqd->rq_in_driver++; | 768 | cfqd->rq_in_driver[rq_is_sync(rq)]++; |
764 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d", | 769 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d", |
765 | cfqd->rq_in_driver); | 770 | rq_in_driver(cfqd)); |
766 | 771 | ||
767 | cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); | 772 | cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); |
768 | } | 773 | } |
@@ -770,11 +775,12 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) | |||
770 | static void cfq_deactivate_request(struct request_queue *q, struct request *rq) | 775 | static void cfq_deactivate_request(struct request_queue *q, struct request *rq) |
771 | { | 776 | { |
772 | struct cfq_data *cfqd = q->elevator->elevator_data; | 777 | struct cfq_data *cfqd = q->elevator->elevator_data; |
778 | const int sync = rq_is_sync(rq); | ||
773 | 779 | ||
774 | WARN_ON(!cfqd->rq_in_driver); | 780 | WARN_ON(!cfqd->rq_in_driver[sync]); |
775 | cfqd->rq_in_driver--; | 781 | cfqd->rq_in_driver[sync]--; |
776 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", | 782 | cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", |
777 | cfqd->rq_in_driver); | 783 | rq_in_driver(cfqd)); |
778 | } | 784 | } |
779 | 785 | ||
780 | static void cfq_remove_request(struct request *rq) | 786 | static void cfq_remove_request(struct request *rq) |
@@ -1080,7 +1086,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) | |||
1080 | /* | 1086 | /* |
1081 | * still requests with the driver, don't idle | 1087 | * still requests with the driver, don't idle |
1082 | */ | 1088 | */ |
1083 | if (cfqd->rq_in_driver) | 1089 | if (rq_in_driver(cfqd)) |
1084 | return; | 1090 | return; |
1085 | 1091 | ||
1086 | /* | 1092 | /* |
@@ -1312,6 +1318,12 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1312 | return 0; | 1318 | return 0; |
1313 | 1319 | ||
1314 | /* | 1320 | /* |
1321 | * Drain async requests before we start sync IO | ||
1322 | */ | ||
1323 | if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC]) | ||
1324 | return 0; | ||
1325 | |||
1326 | /* | ||
1315 | * If this is an async queue and we have sync IO in flight, let it wait | 1327 | * If this is an async queue and we have sync IO in flight, let it wait |
1316 | */ | 1328 | */ |
1317 | if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) | 1329 | if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) |
@@ -2130,11 +2142,11 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq) | |||
2130 | */ | 2142 | */ |
2131 | static void cfq_update_hw_tag(struct cfq_data *cfqd) | 2143 | static void cfq_update_hw_tag(struct cfq_data *cfqd) |
2132 | { | 2144 | { |
2133 | if (cfqd->rq_in_driver > cfqd->rq_in_driver_peak) | 2145 | if (rq_in_driver(cfqd) > cfqd->rq_in_driver_peak) |
2134 | cfqd->rq_in_driver_peak = cfqd->rq_in_driver; | 2146 | cfqd->rq_in_driver_peak = rq_in_driver(cfqd); |
2135 | 2147 | ||
2136 | if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN && | 2148 | if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN && |
2137 | cfqd->rq_in_driver <= CFQ_HW_QUEUE_MIN) | 2149 | rq_in_driver(cfqd) <= CFQ_HW_QUEUE_MIN) |
2138 | return; | 2150 | return; |
2139 | 2151 | ||
2140 | if (cfqd->hw_tag_samples++ < 50) | 2152 | if (cfqd->hw_tag_samples++ < 50) |
@@ -2161,9 +2173,9 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
2161 | 2173 | ||
2162 | cfq_update_hw_tag(cfqd); | 2174 | cfq_update_hw_tag(cfqd); |
2163 | 2175 | ||
2164 | WARN_ON(!cfqd->rq_in_driver); | 2176 | WARN_ON(!cfqd->rq_in_driver[sync]); |
2165 | WARN_ON(!cfqq->dispatched); | 2177 | WARN_ON(!cfqq->dispatched); |
2166 | cfqd->rq_in_driver--; | 2178 | cfqd->rq_in_driver[sync]--; |
2167 | cfqq->dispatched--; | 2179 | cfqq->dispatched--; |
2168 | 2180 | ||
2169 | if (cfq_cfqq_sync(cfqq)) | 2181 | if (cfq_cfqq_sync(cfqq)) |
@@ -2197,7 +2209,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) | |||
2197 | cfq_arm_slice_timer(cfqd); | 2209 | cfq_arm_slice_timer(cfqd); |
2198 | } | 2210 | } |
2199 | 2211 | ||
2200 | if (!cfqd->rq_in_driver) | 2212 | if (!rq_in_driver(cfqd)) |
2201 | cfq_schedule_dispatch(cfqd); | 2213 | cfq_schedule_dispatch(cfqd); |
2202 | } | 2214 | } |
2203 | 2215 | ||