Skip to content

Commit

Permalink
cfq-iosched: idling on deep seeky sync queues
Browse files Browse the repository at this point in the history
Seeky sync queues with large depth can gain unfairly big share of disk
 time, at the expense of other seeky queues. This patch ensures that
 idling will be enabled for queues with I/O depth at least 4, and small
 think time. The decision to enable idling is sticky, until an idle
 window times out without seeing a new request.

The reasoning behind the decision is that, if an application is using
large I/O depth, it is already optimized to make full utilization of
the hardware, and therefore we reserve a slice of exclusive use for it.

Reported-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Corrado Zoccolo <czoccolo@gmail.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
  • Loading branch information
Corrado Zoccolo authored and Jens Axboe committed Nov 26, 2009
1 parent e4a2291 commit 76280af
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ enum cfqq_state_flags {
CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */
CFQ_CFQQ_FLAG_sync, /* synchronous queue */
CFQ_CFQQ_FLAG_coop, /* cfqq is shared */
CFQ_CFQQ_FLAG_deep, /* sync cfqq experienced large depth */
};

#define CFQ_CFQQ_FNS(name) \
Expand All @@ -286,6 +287,7 @@ CFQ_CFQQ_FNS(prio_changed);
CFQ_CFQQ_FNS(slice_new);
CFQ_CFQQ_FNS(sync);
CFQ_CFQQ_FNS(coop);
CFQ_CFQQ_FNS(deep);
#undef CFQ_CFQQ_FNS

#define cfq_log_cfqq(cfqd, cfqq, fmt, args...) \
Expand Down Expand Up @@ -2350,8 +2352,12 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,

enable_idle = old_idle = cfq_cfqq_idle_window(cfqq);

if (cfqq->queued[0] + cfqq->queued[1] >= 4)
cfq_mark_cfqq_deep(cfqq);

if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
(sample_valid(cfqq->seek_samples) && CFQQ_SEEKY(cfqq)))
(!cfq_cfqq_deep(cfqq) && sample_valid(cfqq->seek_samples)
&& CFQQ_SEEKY(cfqq)))
enable_idle = 0;
else if (sample_valid(cic->ttime_samples)) {
if (cic->ttime_mean > cfqd->cfq_slice_idle)
Expand Down Expand Up @@ -2849,6 +2855,11 @@ static void cfq_idle_slice_timer(unsigned long data)
*/
if (!RB_EMPTY_ROOT(&cfqq->sort_list))
goto out_kick;

/*
* Queue depth flag is reset only when the idle didn't succeed
*/
cfq_clear_cfqq_deep(cfqq);
}
expire:
cfq_slice_expired(cfqd, timed_out);
Expand Down

0 comments on commit 76280af

Please sign in to comment.