diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/cfq-iosched.c | 121 |
1 files changed, 67 insertions, 54 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 690ebd96dc42..5c3cee93329a 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -1247,67 +1247,21 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd) | |||
1247 | return dispatched; | 1247 | return dispatched; |
1248 | } | 1248 | } |
1249 | 1249 | ||
1250 | /* | 1250 | static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
1251 | * Dispatch a request from cfqq, moving them to the request queue | ||
1252 | * dispatch list. | ||
1253 | */ | ||
1254 | static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq) | ||
1255 | { | 1251 | { |
1256 | struct request *rq; | ||
1257 | |||
1258 | BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); | ||
1259 | |||
1260 | /* | ||
1261 | * follow expired path, else get first next available | ||
1262 | */ | ||
1263 | rq = cfq_check_fifo(cfqq); | ||
1264 | if (!rq) | ||
1265 | rq = cfqq->next_rq; | ||
1266 | |||
1267 | /* | ||
1268 | * insert request into driver dispatch list | ||
1269 | */ | ||
1270 | cfq_dispatch_insert(cfqd->queue, rq); | ||
1271 | |||
1272 | if (!cfqd->active_cic) { | ||
1273 | struct cfq_io_context *cic = RQ_CIC(rq); | ||
1274 | |||
1275 | atomic_long_inc(&cic->ioc->refcount); | ||
1276 | cfqd->active_cic = cic; | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | /* | ||
1281 | * Find the cfqq that we need to service and move a request from that to the | ||
1282 | * dispatch list | ||
1283 | */ | ||
1284 | static int cfq_dispatch_requests(struct request_queue *q, int force) | ||
1285 | { | ||
1286 | struct cfq_data *cfqd = q->elevator->elevator_data; | ||
1287 | struct cfq_queue *cfqq; | ||
1288 | unsigned int max_dispatch; | 1252 | unsigned int max_dispatch; |
1289 | 1253 | ||
1290 | if (!cfqd->busy_queues) | ||
1291 | return 0; | ||
1292 | |||
1293 | if (unlikely(force)) | ||
1294 | return cfq_forced_dispatch(cfqd); | ||
1295 | |||
1296 | cfqq = cfq_select_queue(cfqd); | ||
1297 | if (!cfqq) | ||
1298 | return 0; | ||
1299 | |||
1300 | /* | 1254 | /* |
1301 | * Drain async requests before we start sync IO | 1255 | * Drain async requests before we start sync IO |
1302 | */ | 1256 | */ |
1303 | if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC]) | 1257 | if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC]) |
1304 | return 0; | 1258 | return false; |
1305 | 1259 | ||
1306 | /* | 1260 | /* |
1307 | * If this is an async queue and we have sync IO in flight, let it wait | 1261 | * If this is an async queue and we have sync IO in flight, let it wait |
1308 | */ | 1262 | */ |
1309 | if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) | 1263 | if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq)) |
1310 | return 0; | 1264 | return false; |
1311 | 1265 | ||
1312 | max_dispatch = cfqd->cfq_quantum; | 1266 | max_dispatch = cfqd->cfq_quantum; |
1313 | if (cfq_class_idle(cfqq)) | 1267 | if (cfq_class_idle(cfqq)) |
@@ -1321,13 +1275,13 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1321 | * idle queue must always only have a single IO in flight | 1275 | * idle queue must always only have a single IO in flight |
1322 | */ | 1276 | */ |
1323 | if (cfq_class_idle(cfqq)) | 1277 | if (cfq_class_idle(cfqq)) |
1324 | return 0; | 1278 | return false; |
1325 | 1279 | ||
1326 | /* | 1280 | /* |
1327 | * We have other queues, don't allow more IO from this one | 1281 | * We have other queues, don't allow more IO from this one |
1328 | */ | 1282 | */ |
1329 | if (cfqd->busy_queues > 1) | 1283 | if (cfqd->busy_queues > 1) |
1330 | return 0; | 1284 | return false; |
1331 | 1285 | ||
1332 | /* | 1286 | /* |
1333 | * Sole queue user, allow bigger slice | 1287 | * Sole queue user, allow bigger slice |
@@ -1351,13 +1305,72 @@ static int cfq_dispatch_requests(struct request_queue *q, int force) | |||
1351 | max_dispatch = depth; | 1305 | max_dispatch = depth; |
1352 | } | 1306 | } |
1353 | 1307 | ||
1354 | if (cfqq->dispatched >= max_dispatch) | 1308 | /* |
1309 | * If we're below the current max, allow a dispatch | ||
1310 | */ | ||
1311 | return cfqq->dispatched < max_dispatch; | ||
1312 | } | ||
1313 | |||
1314 | /* | ||
1315 | * Dispatch a request from cfqq, moving them to the request queue | ||
1316 | * dispatch list. | ||
1317 | */ | ||
1318 | static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq) | ||
1319 | { | ||
1320 | struct request *rq; | ||
1321 | |||
1322 | BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); | ||
1323 | |||
1324 | if (!cfq_may_dispatch(cfqd, cfqq)) | ||
1325 | return false; | ||
1326 | |||
1327 | /* | ||
1328 | * follow expired path, else get first next available | ||
1329 | */ | ||
1330 | rq = cfq_check_fifo(cfqq); | ||
1331 | if (!rq) | ||
1332 | rq = cfqq->next_rq; | ||
1333 | |||
1334 | /* | ||
1335 | * insert request into driver dispatch list | ||
1336 | */ | ||
1337 | cfq_dispatch_insert(cfqd->queue, rq); | ||
1338 | |||
1339 | if (!cfqd->active_cic) { | ||
1340 | struct cfq_io_context *cic = RQ_CIC(rq); | ||
1341 | |||
1342 | atomic_long_inc(&cic->ioc->refcount); | ||
1343 | cfqd->active_cic = cic; | ||
1344 | } | ||
1345 | |||
1346 | return true; | ||
1347 | } | ||
1348 | |||
1349 | /* | ||
1350 | * Find the cfqq that we need to service and move a request from that to the | ||
1351 | * dispatch list | ||
1352 | */ | ||
1353 | static int cfq_dispatch_requests(struct request_queue *q, int force) | ||
1354 | { | ||
1355 | struct cfq_data *cfqd = q->elevator->elevator_data; | ||
1356 | struct cfq_queue *cfqq; | ||
1357 | |||
1358 | if (!cfqd->busy_queues) | ||
1359 | return 0; | ||
1360 | |||
1361 | if (unlikely(force)) | ||
1362 | return cfq_forced_dispatch(cfqd); | ||
1363 | |||
1364 | cfqq = cfq_select_queue(cfqd); | ||
1365 | if (!cfqq) | ||
1355 | return 0; | 1366 | return 0; |
1356 | 1367 | ||
1357 | /* | 1368 | /* |
1358 | * Dispatch a request from this cfqq | 1369 | * Dispatch a request from this cfqq, if it is allowed |
1359 | */ | 1370 | */ |
1360 | cfq_dispatch_request(cfqd, cfqq); | 1371 | if (!cfq_dispatch_request(cfqd, cfqq)) |
1372 | return 0; | ||
1373 | |||
1361 | cfqq->slice_dispatch++; | 1374 | cfqq->slice_dispatch++; |
1362 | cfq_clear_cfqq_must_dispatch(cfqq); | 1375 | cfq_clear_cfqq_must_dispatch(cfqq); |
1363 | 1376 | ||