[PATCH] cfq-iosched: Detect hardware queueing

If the hardware is doing real queueing, decide that it's worthless to
idle the hardware. It does reasonable simultaneous io in that case
anyways, and the idling hurts some work loads.

Signed-off-by: Jens Axboe <axboe@suse.de>

+13 -2
+13 -2
block/cfq-iosched.c
··· 133 mempool_t *crq_pool; 134 135 int rq_in_driver; 136 137 /* 138 * schedule slice state info ··· 665 struct cfq_data *cfqd = q->elevator->elevator_data; 666 667 cfqd->rq_in_driver++; 668 } 669 670 static void cfq_deactivate_request(request_queue_t *q, struct request *rq) ··· 1475 * set ->slice_left to allow preemption for a new process 1476 */ 1477 cfqq->slice_left = 2 * cfqd->cfq_slice_idle; 1478 - cfq_mark_cfqq_idle_window(cfqq); 1479 cfq_mark_cfqq_prio_changed(cfqq); 1480 cfq_init_prio_data(cfqq); 1481 } ··· 1667 { 1668 int enable_idle = cfq_cfqq_idle_window(cfqq); 1669 1670 - if (!cic->ioc->task || !cfqd->cfq_slice_idle) 1671 enable_idle = 0; 1672 else if (sample_valid(cic->ttime_samples)) { 1673 if (cic->ttime_mean > cfqd->cfq_slice_idle)
··· 133 mempool_t *crq_pool; 134 135 int rq_in_driver; 136 + int hw_tag; 137 138 /* 139 * schedule slice state info ··· 664 struct cfq_data *cfqd = q->elevator->elevator_data; 665 666 cfqd->rq_in_driver++; 667 + 668 + /* 669 + * If the depth is larger 1, it really could be queueing. But lets 670 + * make the mark a little higher - idling could still be good for 671 + * low queueing, and a low queueing number could also just indicate 672 + * a SCSI mid layer like behaviour where limit+1 is often seen. 673 + */ 674 + if (!cfqd->hw_tag && cfqd->rq_in_driver > 4) 675 + cfqd->hw_tag = 1; 676 } 677 678 static void cfq_deactivate_request(request_queue_t *q, struct request *rq) ··· 1465 * set ->slice_left to allow preemption for a new process 1466 */ 1467 cfqq->slice_left = 2 * cfqd->cfq_slice_idle; 1468 + if (!cfqd->hw_tag) 1469 + cfq_mark_cfqq_idle_window(cfqq); 1470 cfq_mark_cfqq_prio_changed(cfqq); 1471 cfq_init_prio_data(cfqq); 1472 } ··· 1656 { 1657 int enable_idle = cfq_cfqq_idle_window(cfqq); 1658 1659 + if (!cic->ioc->task || !cfqd->cfq_slice_idle || cfqd->hw_tag) 1660 enable_idle = 0; 1661 else if (sample_valid(cic->ttime_samples)) { 1662 if (cic->ttime_mean > cfqd->cfq_slice_idle)