diff options
-rw-r--r-- | block/cfq-iosched.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 11efcf196e74..a4809de6fea6 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -177,6 +177,7 @@ struct cfq_queue { | |||
177 | enum cfqq_state_flags { | 177 | enum cfqq_state_flags { |
178 | CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */ | 178 | CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */ |
179 | CFQ_CFQQ_FLAG_wait_request, /* waiting for a request */ | 179 | CFQ_CFQQ_FLAG_wait_request, /* waiting for a request */ |
180 | CFQ_CFQQ_FLAG_must_dispatch, /* must be allowed a dispatch */ | ||
180 | CFQ_CFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ | 181 | CFQ_CFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ |
181 | CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */ | 182 | CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */ |
182 | CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ | 183 | CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ |
@@ -202,6 +203,7 @@ static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq) \ | |||
202 | 203 | ||
203 | CFQ_CFQQ_FNS(on_rr); | 204 | CFQ_CFQQ_FNS(on_rr); |
204 | CFQ_CFQQ_FNS(wait_request); | 205 | CFQ_CFQQ_FNS(wait_request); |
206 | CFQ_CFQQ_FNS(must_dispatch); | ||
205 | CFQ_CFQQ_FNS(must_alloc); | 207 | CFQ_CFQQ_FNS(must_alloc); |
206 | CFQ_CFQQ_FNS(must_alloc_slice); | 208 | CFQ_CFQQ_FNS(must_alloc_slice); |
207 | CFQ_CFQQ_FNS(fifo_expire); | 209 | CFQ_CFQQ_FNS(fifo_expire); |
@@ -774,6 +776,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd, | |||
774 | cfqq->slice_dispatch = 0; | 776 | cfqq->slice_dispatch = 0; |
775 | 777 | ||
776 | cfq_clear_cfqq_wait_request(cfqq); | 778 | cfq_clear_cfqq_wait_request(cfqq); |
779 | cfq_clear_cfqq_must_dispatch(cfqq); | ||
777 | cfq_clear_cfqq_must_alloc_slice(cfqq); | 780 | cfq_clear_cfqq_must_alloc_slice(cfqq); |
778 | cfq_clear_cfqq_fifo_expire(cfqq); | 781 | cfq_clear_cfqq_fifo_expire(cfqq); |
779 | cfq_mark_cfqq_slice_new(cfqq); | 782 | cfq_mark_cfqq_slice_new(cfqq); |
@@ -1009,7 +1012,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) | |||
1009 | /* | 1012 | /* |
1010 | * The active queue has run out of time, expire it and select new. | 1013 | * The active queue has run out of time, expire it and select new. |
1011 | */ | 1014 | */ |
1012 | if (cfq_slice_used(cfqq)) | 1015 | if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq)) |
1013 | goto expire; | 1016 | goto expire; |
1014 | 1017 | ||
1015 | /* | 1018 | /* |
@@ -1173,6 +1176,7 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1173 | */ | 1176 | */ |
1174 | cfq_dispatch_request(cfqd, cfqq); | 1177 | cfq_dispatch_request(cfqd, cfqq); |
1175 | cfqq->slice_dispatch++; | 1178 | cfqq->slice_dispatch++; |
1179 | cfq_clear_cfqq_must_dispatch(cfqq); | ||
1176 | 1180 | ||
1177 | /* | 1181 | /* |
1178 | * expire an async queue immediately if it has used up its slice. idle | 1182 | * expire an async queue immediately if it has used up its slice. idle |
@@ -1898,14 +1902,13 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
1898 | 1902 | ||
1899 | if (cfqq == cfqd->active_queue) { | 1903 | if (cfqq == cfqd->active_queue) { |
1900 | /* | 1904 | /* |
1901 | * if we are waiting for a request for this queue, let it rip | 1905 | * Remember that we saw a request from this process, but |
1902 | * immediately and flag that we must not expire this queue | 1906 | * don't start queuing just yet. Otherwise we risk seeing lots |
1903 | * just now | 1907 | * of tiny requests, because we disrupt the normal plugging |
1908 | * and merging. | ||
1904 | */ | 1909 | */ |
1905 | if (cfq_cfqq_wait_request(cfqq)) { | 1910 | if (cfq_cfqq_wait_request(cfqq)) |
1906 | del_timer(&cfqd->idle_slice_timer); | 1911 | cfq_mark_cfqq_must_dispatch(cfqq); |
1907 | blk_start_queueing(cfqd->queue); | ||
1908 | } | ||
1909 | } else if (cfq_should_preempt(cfqd, cfqq, rq)) { | 1912 | } else if (cfq_should_preempt(cfqd, cfqq, rq)) { |
1910 | /* | 1913 | /* |
1911 | * not the active queue - expire current slice if it is | 1914 | * not the active queue - expire current slice if it is |
@@ -2175,6 +2178,12 @@ static void cfq_idle_slice_timer(unsigned long data) | |||
2175 | timed_out = 0; | 2178 | timed_out = 0; |
2176 | 2179 | ||
2177 | /* | 2180 | /* |
2181 | * We saw a request before the queue expired, let it through | ||
2182 | */ | ||
2183 | if (cfq_cfqq_must_dispatch(cfqq)) | ||
2184 | goto out_kick; | ||
2185 | |||
2186 | /* | ||
2178 | * expired | 2187 | * expired |
2179 | */ | 2188 | */ |
2180 | if (cfq_slice_used(cfqq)) | 2189 | if (cfq_slice_used(cfqq)) |