aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 14:06:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 14:06:41 -0400
commit6a5d263866d699ebf6843105497afc86ee53de5b (patch)
tree439195e272631908cdc2e3e44abaf7e1c3447157 /block
parentaeeae86859f4319de0a4946b44771d9926eeed54 (diff)
parentffcd7dca3ab78f9f425971756e5e90024157f6be (diff)
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: loop: mutex already unlocked in loop_clr_fd() cfq-iosched: don't let idling interfere with plugging block: remove unused REQ_UNPLUG cfq-iosched: kill two unused cfqq flags cfq-iosched: change dispatch logic to deal with single requests at the time mflash: initial support cciss: change to discover first memory BAR cciss: kernel scan thread for MSA2012 cciss: fix residual count for block pc requests block: fix inconsistency in I/O stat accounting code block: elevator quiescing helpers
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c15
-rw-r--r--block/blk-merge.c29
-rw-r--r--block/blk-sysfs.c4
-rw-r--r--block/blk.h14
-rw-r--r--block/cfq-iosched.c202
-rw-r--r--block/elevator.c42
6 files changed, 169 insertions, 137 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 25572802dac2..43fdedc524ee 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -64,12 +64,11 @@ static struct workqueue_struct *kblockd_workqueue;
64 64
65static void drive_stat_acct(struct request *rq, int new_io) 65static void drive_stat_acct(struct request *rq, int new_io)
66{ 66{
67 struct gendisk *disk = rq->rq_disk;
68 struct hd_struct *part; 67 struct hd_struct *part;
69 int rw = rq_data_dir(rq); 68 int rw = rq_data_dir(rq);
70 int cpu; 69 int cpu;
71 70
72 if (!blk_fs_request(rq) || !disk || !blk_do_io_stat(disk->queue)) 71 if (!blk_fs_request(rq) || !blk_do_io_stat(rq))
73 return; 72 return;
74 73
75 cpu = part_stat_lock(); 74 cpu = part_stat_lock();
@@ -1124,8 +1123,6 @@ void init_request_from_bio(struct request *req, struct bio *bio)
1124 1123
1125 if (bio_sync(bio)) 1124 if (bio_sync(bio))
1126 req->cmd_flags |= REQ_RW_SYNC; 1125 req->cmd_flags |= REQ_RW_SYNC;
1127 if (bio_unplug(bio))
1128 req->cmd_flags |= REQ_UNPLUG;
1129 if (bio_rw_meta(bio)) 1126 if (bio_rw_meta(bio))
1130 req->cmd_flags |= REQ_RW_META; 1127 req->cmd_flags |= REQ_RW_META;
1131 if (bio_noidle(bio)) 1128 if (bio_noidle(bio))
@@ -1675,9 +1672,7 @@ EXPORT_SYMBOL(blkdev_dequeue_request);
1675 1672
1676static void blk_account_io_completion(struct request *req, unsigned int bytes) 1673static void blk_account_io_completion(struct request *req, unsigned int bytes)
1677{ 1674{
1678 struct gendisk *disk = req->rq_disk; 1675 if (!blk_do_io_stat(req))
1679
1680 if (!disk || !blk_do_io_stat(disk->queue))
1681 return; 1676 return;
1682 1677
1683 if (blk_fs_request(req)) { 1678 if (blk_fs_request(req)) {
@@ -1694,9 +1689,7 @@ static void blk_account_io_completion(struct request *req, unsigned int bytes)
1694 1689
1695static void blk_account_io_done(struct request *req) 1690static void blk_account_io_done(struct request *req)
1696{ 1691{
1697 struct gendisk *disk = req->rq_disk; 1692 if (!blk_do_io_stat(req))
1698
1699 if (!disk || !blk_do_io_stat(disk->queue))
1700 return; 1693 return;
1701 1694
1702 /* 1695 /*
@@ -1711,7 +1704,7 @@ static void blk_account_io_done(struct request *req)
1711 int cpu; 1704 int cpu;
1712 1705
1713 cpu = part_stat_lock(); 1706 cpu = part_stat_lock();
1714 part = disk_map_sector_rcu(disk, req->sector); 1707 part = disk_map_sector_rcu(req->rq_disk, req->sector);
1715 1708
1716 part_stat_inc(cpu, part, ios[rw]); 1709 part_stat_inc(cpu, part, ios[rw]);
1717 part_stat_add(cpu, part, ticks[rw], duration); 1710 part_stat_add(cpu, part, ticks[rw], duration);
diff --git a/block/blk-merge.c b/block/blk-merge.c
index e39cb24b7679..63760ca3da0f 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -338,6 +338,22 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
338 return 1; 338 return 1;
339} 339}
340 340
341static void blk_account_io_merge(struct request *req)
342{
343 if (blk_do_io_stat(req)) {
344 struct hd_struct *part;
345 int cpu;
346
347 cpu = part_stat_lock();
348 part = disk_map_sector_rcu(req->rq_disk, req->sector);
349
350 part_round_stats(cpu, part);
351 part_dec_in_flight(part);
352
353 part_stat_unlock();
354 }
355}
356
341/* 357/*
342 * Has to be called with the request spinlock acquired 358 * Has to be called with the request spinlock acquired
343 */ 359 */
@@ -386,18 +402,7 @@ static int attempt_merge(struct request_queue *q, struct request *req,
386 402
387 elv_merge_requests(q, req, next); 403 elv_merge_requests(q, req, next);
388 404
389 if (req->rq_disk) { 405 blk_account_io_merge(req);
390 struct hd_struct *part;
391 int cpu;
392
393 cpu = part_stat_lock();
394 part = disk_map_sector_rcu(req->rq_disk, req->sector);
395
396 part_round_stats(cpu, part);
397 part_dec_in_flight(part);
398
399 part_stat_unlock();
400 }
401 406
402 req->ioprio = ioprio_best(req->ioprio, next->ioprio); 407 req->ioprio = ioprio_best(req->ioprio, next->ioprio);
403 if (blk_rq_cpu_valid(next)) 408 if (blk_rq_cpu_valid(next))
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 3ff9bba3379a..73f36beff5cd 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -209,10 +209,14 @@ static ssize_t queue_iostats_store(struct request_queue *q, const char *page,
209 ssize_t ret = queue_var_store(&stats, page, count); 209 ssize_t ret = queue_var_store(&stats, page, count);
210 210
211 spin_lock_irq(q->queue_lock); 211 spin_lock_irq(q->queue_lock);
212 elv_quisce_start(q);
213
212 if (stats) 214 if (stats)
213 queue_flag_set(QUEUE_FLAG_IO_STAT, q); 215 queue_flag_set(QUEUE_FLAG_IO_STAT, q);
214 else 216 else
215 queue_flag_clear(QUEUE_FLAG_IO_STAT, q); 217 queue_flag_clear(QUEUE_FLAG_IO_STAT, q);
218
219 elv_quisce_end(q);
216 spin_unlock_irq(q->queue_lock); 220 spin_unlock_irq(q->queue_lock);
217 221
218 return ret; 222 return ret;
diff --git a/block/blk.h b/block/blk.h
index 3ee94358b43d..24fcaeeaf620 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -70,6 +70,10 @@ void blk_queue_congestion_threshold(struct request_queue *q);
70 70
71int blk_dev_init(void); 71int blk_dev_init(void);
72 72
73void elv_quisce_start(struct request_queue *q);
74void elv_quisce_end(struct request_queue *q);
75
76
73/* 77/*
74 * Return the threshold (number of used requests) at which the queue is 78 * Return the threshold (number of used requests) at which the queue is
75 * considered to be congested. It include a little hysteresis to keep the 79 * considered to be congested. It include a little hysteresis to keep the
@@ -108,12 +112,14 @@ static inline int blk_cpu_to_group(int cpu)
108#endif 112#endif
109} 113}
110 114
111static inline int blk_do_io_stat(struct request_queue *q) 115static inline int blk_do_io_stat(struct request *rq)
112{ 116{
113 if (q) 117 struct gendisk *disk = rq->rq_disk;
114 return blk_queue_io_stat(q);
115 118
116 return 0; 119 if (!disk || !disk->queue)
120 return 0;
121
122 return blk_queue_io_stat(disk->queue) && (rq->cmd_flags & REQ_ELVPRIV);
117} 123}
118 124
119#endif 125#endif
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 9e809345f71a..a4809de6fea6 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -160,6 +160,7 @@ struct cfq_queue {
160 160
161 unsigned long slice_end; 161 unsigned long slice_end;
162 long slice_resid; 162 long slice_resid;
163 unsigned int slice_dispatch;
163 164
164 /* pending metadata requests */ 165 /* pending metadata requests */
165 int meta_pending; 166 int meta_pending;
@@ -176,13 +177,12 @@ struct cfq_queue {
176enum cfqq_state_flags { 177enum cfqq_state_flags {
177 CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */ 178 CFQ_CFQQ_FLAG_on_rr = 0, /* on round-robin busy list */
178 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 */
179 CFQ_CFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ 181 CFQ_CFQQ_FLAG_must_alloc, /* must be allowed rq alloc */
180 CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */ 182 CFQ_CFQQ_FLAG_must_alloc_slice, /* per-slice must_alloc flag */
181 CFQ_CFQQ_FLAG_must_dispatch, /* must dispatch, even if expired */
182 CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ 183 CFQ_CFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */
183 CFQ_CFQQ_FLAG_idle_window, /* slice idling enabled */ 184 CFQ_CFQQ_FLAG_idle_window, /* slice idling enabled */
184 CFQ_CFQQ_FLAG_prio_changed, /* task priority has changed */ 185 CFQ_CFQQ_FLAG_prio_changed, /* task priority has changed */
185 CFQ_CFQQ_FLAG_queue_new, /* queue never been serviced */
186 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ 186 CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */
187 CFQ_CFQQ_FLAG_sync, /* synchronous queue */ 187 CFQ_CFQQ_FLAG_sync, /* synchronous queue */
188}; 188};
@@ -203,13 +203,12 @@ static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq) \
203 203
204CFQ_CFQQ_FNS(on_rr); 204CFQ_CFQQ_FNS(on_rr);
205CFQ_CFQQ_FNS(wait_request); 205CFQ_CFQQ_FNS(wait_request);
206CFQ_CFQQ_FNS(must_dispatch);
206CFQ_CFQQ_FNS(must_alloc); 207CFQ_CFQQ_FNS(must_alloc);
207CFQ_CFQQ_FNS(must_alloc_slice); 208CFQ_CFQQ_FNS(must_alloc_slice);
208CFQ_CFQQ_FNS(must_dispatch);
209CFQ_CFQQ_FNS(fifo_expire); 209CFQ_CFQQ_FNS(fifo_expire);
210CFQ_CFQQ_FNS(idle_window); 210CFQ_CFQQ_FNS(idle_window);
211CFQ_CFQQ_FNS(prio_changed); 211CFQ_CFQQ_FNS(prio_changed);
212CFQ_CFQQ_FNS(queue_new);
213CFQ_CFQQ_FNS(slice_new); 212CFQ_CFQQ_FNS(slice_new);
214CFQ_CFQQ_FNS(sync); 213CFQ_CFQQ_FNS(sync);
215#undef CFQ_CFQQ_FNS 214#undef CFQ_CFQQ_FNS
@@ -774,10 +773,15 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
774 if (cfqq) { 773 if (cfqq) {
775 cfq_log_cfqq(cfqd, cfqq, "set_active"); 774 cfq_log_cfqq(cfqd, cfqq, "set_active");
776 cfqq->slice_end = 0; 775 cfqq->slice_end = 0;
776 cfqq->slice_dispatch = 0;
777
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);
780 cfq_clear_cfqq_queue_new(cfqq); 783
784 del_timer(&cfqd->idle_slice_timer);
781 } 785 }
782 786
783 cfqd->active_queue = cfqq; 787 cfqd->active_queue = cfqq;
@@ -795,7 +799,6 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
795 if (cfq_cfqq_wait_request(cfqq)) 799 if (cfq_cfqq_wait_request(cfqq))
796 del_timer(&cfqd->idle_slice_timer); 800 del_timer(&cfqd->idle_slice_timer);
797 801
798 cfq_clear_cfqq_must_dispatch(cfqq);
799 cfq_clear_cfqq_wait_request(cfqq); 802 cfq_clear_cfqq_wait_request(cfqq);
800 803
801 /* 804 /*
@@ -924,7 +927,6 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
924 (sample_valid(cic->ttime_samples) && cic->ttime_mean > 2)) 927 (sample_valid(cic->ttime_samples) && cic->ttime_mean > 2))
925 return; 928 return;
926 929
927 cfq_mark_cfqq_must_dispatch(cfqq);
928 cfq_mark_cfqq_wait_request(cfqq); 930 cfq_mark_cfqq_wait_request(cfqq);
929 931
930 /* 932 /*
@@ -1010,7 +1012,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
1010 /* 1012 /*
1011 * 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.
1012 */ 1014 */
1013 if (cfq_slice_used(cfqq)) 1015 if (cfq_slice_used(cfqq) && !cfq_cfqq_must_dispatch(cfqq))
1014 goto expire; 1016 goto expire;
1015 1017
1016 /* 1018 /*
@@ -1053,66 +1055,6 @@ keep_queue:
1053 return cfqq; 1055 return cfqq;
1054} 1056}
1055 1057
1056/*
1057 * Dispatch some requests from cfqq, moving them to the request queue
1058 * dispatch list.
1059 */
1060static int
1061__cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1062 int max_dispatch)
1063{
1064 int dispatched = 0;
1065
1066 BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
1067
1068 do {
1069 struct request *rq;
1070
1071 /*
1072 * follow expired path, else get first next available
1073 */
1074 rq = cfq_check_fifo(cfqq);
1075 if (rq == NULL)
1076 rq = cfqq->next_rq;
1077
1078 /*
1079 * finally, insert request into driver dispatch list
1080 */
1081 cfq_dispatch_insert(cfqd->queue, rq);
1082
1083 dispatched++;
1084
1085 if (!cfqd->active_cic) {
1086 atomic_inc(&RQ_CIC(rq)->ioc->refcount);
1087 cfqd->active_cic = RQ_CIC(rq);
1088 }
1089
1090 if (RB_EMPTY_ROOT(&cfqq->sort_list))
1091 break;
1092
1093 /*
1094 * If there is a non-empty RT cfqq waiting for current
1095 * cfqq's timeslice to complete, pre-empt this cfqq
1096 */
1097 if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues)
1098 break;
1099
1100 } while (dispatched < max_dispatch);
1101
1102 /*
1103 * expire an async queue immediately if it has used up its slice. idle
1104 * queue always expire after 1 dispatch round.
1105 */
1106 if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
1107 dispatched >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
1108 cfq_class_idle(cfqq))) {
1109 cfqq->slice_end = jiffies + 1;
1110 cfq_slice_expired(cfqd, 0);
1111 }
1112
1113 return dispatched;
1114}
1115
1116static int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq) 1058static int __cfq_forced_dispatch_cfqq(struct cfq_queue *cfqq)
1117{ 1059{
1118 int dispatched = 0; 1060 int dispatched = 0;
@@ -1146,11 +1088,45 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
1146 return dispatched; 1088 return dispatched;
1147} 1089}
1148 1090
1091/*
1092 * Dispatch a request from cfqq, moving them to the request queue
1093 * dispatch list.
1094 */
1095static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1096{
1097 struct request *rq;
1098
1099 BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
1100
1101 /*
1102 * follow expired path, else get first next available
1103 */
1104 rq = cfq_check_fifo(cfqq);
1105 if (!rq)
1106 rq = cfqq->next_rq;
1107
1108 /*
1109 * insert request into driver dispatch list
1110 */
1111 cfq_dispatch_insert(cfqd->queue, rq);
1112
1113 if (!cfqd->active_cic) {
1114 struct cfq_io_context *cic = RQ_CIC(rq);
1115
1116 atomic_inc(&cic->ioc->refcount);
1117 cfqd->active_cic = cic;
1118 }
1119}
1120
1121/*
1122 * Find the cfqq that we need to service and move a request from that to the
1123 * dispatch list
1124 */
1149static int cfq_dispatch_requests(struct request_queue *q, int force) 1125static int cfq_dispatch_requests(struct request_queue *q, int force)
1150{ 1126{
1151 struct cfq_data *cfqd = q->elevator->elevator_data; 1127 struct cfq_data *cfqd = q->elevator->elevator_data;
1152 struct cfq_queue *cfqq; 1128 struct cfq_queue *cfqq;
1153 int dispatched; 1129 unsigned int max_dispatch;
1154 1130
1155 if (!cfqd->busy_queues) 1131 if (!cfqd->busy_queues)
1156 return 0; 1132 return 0;
@@ -1158,29 +1134,63 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
1158 if (unlikely(force)) 1134 if (unlikely(force))
1159 return cfq_forced_dispatch(cfqd); 1135 return cfq_forced_dispatch(cfqd);
1160 1136
1161 dispatched = 0; 1137 cfqq = cfq_select_queue(cfqd);
1162 while ((cfqq = cfq_select_queue(cfqd)) != NULL) { 1138 if (!cfqq)
1163 int max_dispatch; 1139 return 0;
1140
1141 /*
1142 * If this is an async queue and we have sync IO in flight, let it wait
1143 */
1144 if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
1145 return 0;
1146
1147 max_dispatch = cfqd->cfq_quantum;
1148 if (cfq_class_idle(cfqq))
1149 max_dispatch = 1;
1164 1150
1165 max_dispatch = cfqd->cfq_quantum; 1151 /*
1152 * Does this cfqq already have too much IO in flight?
1153 */
1154 if (cfqq->dispatched >= max_dispatch) {
1155 /*
1156 * idle queue must always only have a single IO in flight
1157 */
1166 if (cfq_class_idle(cfqq)) 1158 if (cfq_class_idle(cfqq))
1167 max_dispatch = 1; 1159 return 0;
1168 1160
1169 if (cfqq->dispatched >= max_dispatch && cfqd->busy_queues > 1) 1161 /*
1170 break; 1162 * We have other queues, don't allow more IO from this one
1163 */
1164 if (cfqd->busy_queues > 1)
1165 return 0;
1171 1166
1172 if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) 1167 /*
1173 break; 1168 * we are the only queue, allow up to 4 times of 'quantum'
1169 */
1170 if (cfqq->dispatched >= 4 * max_dispatch)
1171 return 0;
1172 }
1174 1173
1175 cfq_clear_cfqq_must_dispatch(cfqq); 1174 /*
1176 cfq_clear_cfqq_wait_request(cfqq); 1175 * Dispatch a request from this cfqq
1177 del_timer(&cfqd->idle_slice_timer); 1176 */
1177 cfq_dispatch_request(cfqd, cfqq);
1178 cfqq->slice_dispatch++;
1179 cfq_clear_cfqq_must_dispatch(cfqq);
1178 1180
1179 dispatched += __cfq_dispatch_requests(cfqd, cfqq, max_dispatch); 1181 /*
1182 * expire an async queue immediately if it has used up its slice. idle
1183 * queue always expire after 1 dispatch round.
1184 */
1185 if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) &&
1186 cfqq->slice_dispatch >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
1187 cfq_class_idle(cfqq))) {
1188 cfqq->slice_end = jiffies + 1;
1189 cfq_slice_expired(cfqd, 0);
1180 } 1190 }
1181 1191
1182 cfq_log(cfqd, "dispatched=%d", dispatched); 1192 cfq_log(cfqd, "dispatched a request");
1183 return dispatched; 1193 return 1;
1184} 1194}
1185 1195
1186/* 1196/*
@@ -1506,7 +1516,6 @@ retry:
1506 cfqq->cfqd = cfqd; 1516 cfqq->cfqd = cfqd;
1507 1517
1508 cfq_mark_cfqq_prio_changed(cfqq); 1518 cfq_mark_cfqq_prio_changed(cfqq);
1509 cfq_mark_cfqq_queue_new(cfqq);
1510 1519
1511 cfq_init_prio_data(cfqq, ioc); 1520 cfq_init_prio_data(cfqq, ioc);
1512 1521
@@ -1893,15 +1902,13 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1893 1902
1894 if (cfqq == cfqd->active_queue) { 1903 if (cfqq == cfqd->active_queue) {
1895 /* 1904 /*
1896 * if we are waiting for a request for this queue, let it rip 1905 * Remember that we saw a request from this process, but
1897 * immediately and flag that we must not expire this queue 1906 * don't start queuing just yet. Otherwise we risk seeing lots
1898 * just now 1907 * of tiny requests, because we disrupt the normal plugging
1908 * and merging.
1899 */ 1909 */
1900 if (cfq_cfqq_wait_request(cfqq)) { 1910 if (cfq_cfqq_wait_request(cfqq))
1901 cfq_mark_cfqq_must_dispatch(cfqq); 1911 cfq_mark_cfqq_must_dispatch(cfqq);
1902 del_timer(&cfqd->idle_slice_timer);
1903 blk_start_queueing(cfqd->queue);
1904 }
1905 } else if (cfq_should_preempt(cfqd, cfqq, rq)) { 1912 } else if (cfq_should_preempt(cfqd, cfqq, rq)) {
1906 /* 1913 /*
1907 * not the active queue - expire current slice if it is 1914 * not the active queue - expire current slice if it is
@@ -1910,7 +1917,6 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1910 * this new queue is RT and the current one is BE 1917 * this new queue is RT and the current one is BE
1911 */ 1918 */
1912 cfq_preempt_queue(cfqd, cfqq); 1919 cfq_preempt_queue(cfqd, cfqq);
1913 cfq_mark_cfqq_must_dispatch(cfqq);
1914 blk_start_queueing(cfqd->queue); 1920 blk_start_queueing(cfqd->queue);
1915 } 1921 }
1916} 1922}
@@ -2172,6 +2178,12 @@ static void cfq_idle_slice_timer(unsigned long data)
2172 timed_out = 0; 2178 timed_out = 0;
2173 2179
2174 /* 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 /*
2175 * expired 2187 * expired
2176 */ 2188 */
2177 if (cfq_slice_used(cfqq)) 2189 if (cfq_slice_used(cfqq))
@@ -2187,10 +2199,8 @@ static void cfq_idle_slice_timer(unsigned long data)
2187 /* 2199 /*
2188 * not expired and it has a request pending, let it dispatch 2200 * not expired and it has a request pending, let it dispatch
2189 */ 2201 */
2190 if (!RB_EMPTY_ROOT(&cfqq->sort_list)) { 2202 if (!RB_EMPTY_ROOT(&cfqq->sort_list))
2191 cfq_mark_cfqq_must_dispatch(cfqq);
2192 goto out_kick; 2203 goto out_kick;
2193 }
2194 } 2204 }
2195expire: 2205expire:
2196 cfq_slice_expired(cfqd, timed_out); 2206 cfq_slice_expired(cfqd, timed_out);
diff --git a/block/elevator.c b/block/elevator.c
index ca6788a0195a..fb81bcc14a8c 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -573,7 +573,7 @@ void elv_requeue_request(struct request_queue *q, struct request *rq)
573 elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); 573 elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
574} 574}
575 575
576static void elv_drain_elevator(struct request_queue *q) 576void elv_drain_elevator(struct request_queue *q)
577{ 577{
578 static int printed; 578 static int printed;
579 while (q->elevator->ops->elevator_dispatch_fn(q, 1)) 579 while (q->elevator->ops->elevator_dispatch_fn(q, 1))
@@ -587,6 +587,31 @@ static void elv_drain_elevator(struct request_queue *q)
587 } 587 }
588} 588}
589 589
590/*
591 * Call with queue lock held, interrupts disabled
592 */
593void elv_quisce_start(struct request_queue *q)
594{
595 queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
596
597 /*
598 * make sure we don't have any requests in flight
599 */
600 elv_drain_elevator(q);
601 while (q->rq.elvpriv) {
602 blk_start_queueing(q);
603 spin_unlock_irq(q->queue_lock);
604 msleep(10);
605 spin_lock_irq(q->queue_lock);
606 elv_drain_elevator(q);
607 }
608}
609
610void elv_quisce_end(struct request_queue *q)
611{
612 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
613}
614
590void elv_insert(struct request_queue *q, struct request *rq, int where) 615void elv_insert(struct request_queue *q, struct request *rq, int where)
591{ 616{
592 struct list_head *pos; 617 struct list_head *pos;
@@ -1101,18 +1126,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
1101 * Turn on BYPASS and drain all requests w/ elevator private data 1126 * Turn on BYPASS and drain all requests w/ elevator private data
1102 */ 1127 */
1103 spin_lock_irq(q->queue_lock); 1128 spin_lock_irq(q->queue_lock);
1104 1129 elv_quisce_start(q);
1105 queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
1106
1107 elv_drain_elevator(q);
1108
1109 while (q->rq.elvpriv) {
1110 blk_start_queueing(q);
1111 spin_unlock_irq(q->queue_lock);
1112 msleep(10);
1113 spin_lock_irq(q->queue_lock);
1114 elv_drain_elevator(q);
1115 }
1116 1130
1117 /* 1131 /*
1118 * Remember old elevator. 1132 * Remember old elevator.
@@ -1136,7 +1150,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
1136 */ 1150 */
1137 elevator_exit(old_elevator); 1151 elevator_exit(old_elevator);
1138 spin_lock_irq(q->queue_lock); 1152 spin_lock_irq(q->queue_lock);
1139 queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); 1153 elv_quisce_end(q);
1140 spin_unlock_irq(q->queue_lock); 1154 spin_unlock_irq(q->queue_lock);
1141 1155
1142 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); 1156 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);