aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index f90519430be6..73a58628f54a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -160,6 +160,7 @@ enum wl_prio_t {
160 BE_WORKLOAD = 0, 160 BE_WORKLOAD = 0,
161 RT_WORKLOAD = 1, 161 RT_WORKLOAD = 1,
162 IDLE_WORKLOAD = 2, 162 IDLE_WORKLOAD = 2,
163 CFQ_PRIO_NR,
163}; 164};
164 165
165/* 166/*
@@ -184,10 +185,19 @@ struct cfq_group {
184 /* number of cfqq currently on this group */ 185 /* number of cfqq currently on this group */
185 int nr_cfqq; 186 int nr_cfqq;
186 187
187 /* Per group busy queus average. Useful for workload slice calc. */
188 unsigned int busy_queues_avg[2];
189 /* 188 /*
190 * rr lists of queues with requests, onle rr for each priority class. 189 * Per group busy queus average. Useful for workload slice calc. We
190 * create the array for each prio class but at run time it is used
191 * only for RT and BE class and slot for IDLE class remains unused.
192 * This is primarily done to avoid confusion and a gcc warning.
193 */
194 unsigned int busy_queues_avg[CFQ_PRIO_NR];
195 /*
196 * rr lists of queues with requests. We maintain service trees for
197 * RT and BE classes. These trees are subdivided in subclasses
198 * of SYNC, SYNC_NOIDLE and ASYNC based on workload type. For IDLE
199 * class there is no subclassification and all the cfq queues go on
200 * a single tree service_tree_idle.
191 * Counts are embedded in the cfq_rb_root 201 * Counts are embedded in the cfq_rb_root
192 */ 202 */
193 struct cfq_rb_root service_trees[2][3]; 203 struct cfq_rb_root service_trees[2][3];
@@ -221,7 +231,6 @@ struct cfq_data {
221 enum wl_type_t serving_type; 231 enum wl_type_t serving_type;
222 unsigned long workload_expires; 232 unsigned long workload_expires;
223 struct cfq_group *serving_group; 233 struct cfq_group *serving_group;
224 bool noidle_tree_requires_idle;
225 234
226 /* 235 /*
227 * Each priority tree is sorted by next_request position. These 236 * Each priority tree is sorted by next_request position. These
@@ -977,8 +986,8 @@ static inline struct cfq_group *cfqg_of_blkg(struct blkio_group *blkg)
977 return NULL; 986 return NULL;
978} 987}
979 988
980void 989void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg,
981cfq_update_blkio_group_weight(struct blkio_group *blkg, unsigned int weight) 990 unsigned int weight)
982{ 991{
983 cfqg_of_blkg(blkg)->weight = weight; 992 cfqg_of_blkg(blkg)->weight = weight;
984} 993}
@@ -2180,7 +2189,6 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
2180 slice = max_t(unsigned, slice, CFQ_MIN_TT); 2189 slice = max_t(unsigned, slice, CFQ_MIN_TT);
2181 cfq_log(cfqd, "workload slice:%d", slice); 2190 cfq_log(cfqd, "workload slice:%d", slice);
2182 cfqd->workload_expires = jiffies + slice; 2191 cfqd->workload_expires = jiffies + slice;
2183 cfqd->noidle_tree_requires_idle = false;
2184} 2192}
2185 2193
2186static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd) 2194static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd)
@@ -3188,7 +3196,9 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
3188 if (cfqq->queued[0] + cfqq->queued[1] >= 4) 3196 if (cfqq->queued[0] + cfqq->queued[1] >= 4)
3189 cfq_mark_cfqq_deep(cfqq); 3197 cfq_mark_cfqq_deep(cfqq);
3190 3198
3191 if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || 3199 if (cfqq->next_rq && (cfqq->next_rq->cmd_flags & REQ_NOIDLE))
3200 enable_idle = 0;
3201 else if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
3192 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq))) 3202 (!cfq_cfqq_deep(cfqq) && CFQQ_SEEKY(cfqq)))
3193 enable_idle = 0; 3203 enable_idle = 0;
3194 else if (sample_valid(cic->ttime_samples)) { 3204 else if (sample_valid(cic->ttime_samples)) {
@@ -3509,17 +3519,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
3509 cfq_slice_expired(cfqd, 1); 3519 cfq_slice_expired(cfqd, 1);
3510 else if (sync && cfqq_empty && 3520 else if (sync && cfqq_empty &&
3511 !cfq_close_cooperator(cfqd, cfqq)) { 3521 !cfq_close_cooperator(cfqd, cfqq)) {
3512 cfqd->noidle_tree_requires_idle |= 3522 cfq_arm_slice_timer(cfqd);
3513 !(rq->cmd_flags & REQ_NOIDLE);
3514 /*
3515 * Idling is enabled for SYNC_WORKLOAD.
3516 * SYNC_NOIDLE_WORKLOAD idles at the end of the tree
3517 * only if we processed at least one !REQ_NOIDLE request
3518 */
3519 if (cfqd->serving_type == SYNC_WORKLOAD
3520 || cfqd->noidle_tree_requires_idle
3521 || cfqq->cfqg->nr_cfqq == 1)
3522 cfq_arm_slice_timer(cfqd);
3523 } 3523 }
3524 } 3524 }
3525 3525
@@ -4105,6 +4105,7 @@ static struct blkio_policy_type blkio_policy_cfq = {
4105 .blkio_unlink_group_fn = cfq_unlink_blkio_group, 4105 .blkio_unlink_group_fn = cfq_unlink_blkio_group,
4106 .blkio_update_group_weight_fn = cfq_update_blkio_group_weight, 4106 .blkio_update_group_weight_fn = cfq_update_blkio_group_weight,
4107 }, 4107 },
4108 .plid = BLKIO_POLICY_PROP,
4108}; 4109};
4109#else 4110#else
4110static struct blkio_policy_type blkio_policy_cfq; 4111static struct blkio_policy_type blkio_policy_cfq;