diff options
| -rw-r--r-- | block/cfq-iosched.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index bb43a1677626..15152e2da0d2 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -346,14 +346,16 @@ static int cfq_queue_empty(request_queue_t *q) | |||
| 346 | /* | 346 | /* |
| 347 | * Lifted from AS - choose which of crq1 and crq2 that is best served now. | 347 | * Lifted from AS - choose which of crq1 and crq2 that is best served now. |
| 348 | * We choose the request that is closest to the head right now. Distance | 348 | * We choose the request that is closest to the head right now. Distance |
| 349 | * behind the head are penalized and only allowed to a certain extent. | 349 | * behind the head is penalized and only allowed to a certain extent. |
| 350 | */ | 350 | */ |
| 351 | static struct cfq_rq * | 351 | static struct cfq_rq * |
| 352 | cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) | 352 | cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) |
| 353 | { | 353 | { |
| 354 | sector_t last, s1, s2, d1 = 0, d2 = 0; | 354 | sector_t last, s1, s2, d1 = 0, d2 = 0; |
| 355 | int r1_wrap = 0, r2_wrap = 0; /* requests are behind the disk head */ | ||
| 356 | unsigned long back_max; | 355 | unsigned long back_max; |
| 356 | #define CFQ_RQ1_WRAP 0x01 /* request 1 wraps */ | ||
| 357 | #define CFQ_RQ2_WRAP 0x02 /* request 2 wraps */ | ||
| 358 | unsigned wrap = 0; /* bit mask: requests behind the disk head? */ | ||
| 357 | 359 | ||
| 358 | if (crq1 == NULL || crq1 == crq2) | 360 | if (crq1 == NULL || crq1 == crq2) |
| 359 | return crq2; | 361 | return crq2; |
| @@ -385,35 +387,47 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) | |||
| 385 | else if (s1 + back_max >= last) | 387 | else if (s1 + back_max >= last) |
| 386 | d1 = (last - s1) * cfqd->cfq_back_penalty; | 388 | d1 = (last - s1) * cfqd->cfq_back_penalty; |
| 387 | else | 389 | else |
| 388 | r1_wrap = 1; | 390 | wrap |= CFQ_RQ1_WRAP; |
| 389 | 391 | ||
| 390 | if (s2 >= last) | 392 | if (s2 >= last) |
| 391 | d2 = s2 - last; | 393 | d2 = s2 - last; |
| 392 | else if (s2 + back_max >= last) | 394 | else if (s2 + back_max >= last) |
| 393 | d2 = (last - s2) * cfqd->cfq_back_penalty; | 395 | d2 = (last - s2) * cfqd->cfq_back_penalty; |
| 394 | else | 396 | else |
| 395 | r2_wrap = 1; | 397 | wrap |= CFQ_RQ2_WRAP; |
| 396 | 398 | ||
| 397 | /* Found required data */ | 399 | /* Found required data */ |
| 398 | if (!r1_wrap && r2_wrap) | 400 | |
| 399 | return crq1; | 401 | /* |
| 400 | else if (!r2_wrap && r1_wrap) | 402 | * By doing switch() on the bit mask "wrap" we avoid having to |
| 401 | return crq2; | 403 | * check two variables for all permutations: --> faster! |
| 402 | else if (r1_wrap && r2_wrap) { | 404 | */ |
| 403 | /* both behind the head */ | 405 | switch (wrap) { |
| 404 | if (s1 <= s2) | 406 | case 0: /* common case for CFQ: crq1 and crq2 not wrapped */ |
| 407 | if (d1 < d2) | ||
| 405 | return crq1; | 408 | return crq1; |
| 406 | else | 409 | else if (d2 < d1) |
| 407 | return crq2; | 410 | return crq2; |
| 408 | } | 411 | else { |
| 412 | if (s1 >= s2) | ||
| 413 | return crq1; | ||
| 414 | else | ||
| 415 | return crq2; | ||
| 416 | } | ||
| 409 | 417 | ||
| 410 | /* Both requests in front of the head */ | 418 | case CFQ_RQ2_WRAP: |
| 411 | if (d1 < d2) | ||
| 412 | return crq1; | 419 | return crq1; |
| 413 | else if (d2 < d1) | 420 | case CFQ_RQ1_WRAP: |
| 414 | return crq2; | 421 | return crq2; |
| 415 | else { | 422 | case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both crqs wrapped */ |
| 416 | if (s1 >= s2) | 423 | default: |
| 424 | /* | ||
| 425 | * Since both rqs are wrapped, | ||
| 426 | * start with the one that's further behind head | ||
| 427 | * (--> only *one* back seek required), | ||
| 428 | * since back seek takes more time than forward. | ||
| 429 | */ | ||
| 430 | if (s1 <= s2) | ||
| 417 | return crq1; | 431 | return crq1; |
| 418 | else | 432 | else |
| 419 | return crq2; | 433 | return crq2; |
