aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/cfq-iosched.c50
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 */
351static struct cfq_rq * 351static struct cfq_rq *
352cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) 352cfq_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;