|
@@ -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) \
|
|
@@ -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...) \
|
|
@@ -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)
|
|
@@ -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);
|