From fca300e43b592e0f0fd80337e9e3a1e546252200 Mon Sep 17 00:00:00 2001 From: Corrado Zoccolo Date: Thu, 26 Nov 2009 10:02:58 +0100 Subject: [PATCH] --- yaml --- r: 172976 b: refs/heads/master c: 8e550632cccae34e265cb066691945515eaa7fb5 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/block/cfq-iosched.c | 32 ++++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index b88e50111650..c2d667413024 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 76280aff1c7e9ae761cac4b48591c43cd7d69159 +refs/heads/master: 8e550632cccae34e265cb066691945515eaa7fb5 diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 15f7238f527f..a5de31f76d3b 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -172,6 +172,7 @@ struct cfq_data { enum wl_prio_t serving_prio; enum wl_type_t serving_type; unsigned long workload_expires; + bool noidle_tree_requires_idle; /* * Each priority tree is sorted by next_request position. These @@ -1253,9 +1254,9 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) return; /* - * still requests with the driver, don't idle + * still active requests from this queue, don't idle */ - if (rq_in_driver(cfqd)) + if (cfqq->dispatched) return; /* @@ -1478,6 +1479,7 @@ static void choose_service_tree(struct cfq_data *cfqd) slice = max_t(unsigned, slice, CFQ_MIN_TT); cfqd->workload_expires = jiffies + slice; + cfqd->noidle_tree_requires_idle = false; } /* @@ -2597,17 +2599,27 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) cfq_clear_cfqq_slice_new(cfqq); } /* - * If there are no requests waiting in this queue, and - * there are other queues ready to issue requests, AND - * those other queues are issuing requests within our - * mean seek distance, give them a chance to run instead - * of idling. + * Idling is not enabled on: + * - expired queues + * - idle-priority queues + * - async queues + * - queues with still some requests queued + * - when there is a close cooperator */ if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq)) cfq_slice_expired(cfqd, 1); - else if (cfqq_empty && !cfq_close_cooperator(cfqd, cfqq) && - sync && !rq_noidle(rq)) - cfq_arm_slice_timer(cfqd); + else if (sync && cfqq_empty && + !cfq_close_cooperator(cfqd, cfqq)) { + cfqd->noidle_tree_requires_idle |= !rq_noidle(rq); + /* + * Idling is enabled for SYNC_WORKLOAD. + * SYNC_NOIDLE_WORKLOAD idles at the end of the tree + * only if we processed at least one !rq_noidle request + */ + if (cfqd->serving_type == SYNC_WORKLOAD + || cfqd->noidle_tree_requires_idle) + cfq_arm_slice_timer(cfqd); + } } if (!rq_in_driver(cfqd))