Commit 3c6bd2f8 authored by Jens Axboe's avatar Jens Axboe Committed by Jens Axboe

cfq-iosched: check whether a queue timed out in accounting

Makes it more fair for the residual slice count.
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent cb887411
...@@ -688,7 +688,7 @@ __cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) ...@@ -688,7 +688,7 @@ __cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
*/ */
static void static void
__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
int preempted) int preempted, int timed_out)
{ {
if (cfq_cfqq_wait_request(cfqq)) if (cfq_cfqq_wait_request(cfqq))
del_timer(&cfqd->idle_slice_timer); del_timer(&cfqd->idle_slice_timer);
...@@ -704,7 +704,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -704,7 +704,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
* store what was left of this slice, if the queue idled out * store what was left of this slice, if the queue idled out
* or was preempted * or was preempted
*/ */
if (!cfq_cfqq_slice_new(cfqq)) if (timed_out && !cfq_cfqq_slice_new(cfqq))
cfqq->slice_resid = cfqq->slice_end - jiffies; cfqq->slice_resid = cfqq->slice_end - jiffies;
cfq_resort_rr_list(cfqq, preempted); cfq_resort_rr_list(cfqq, preempted);
...@@ -720,12 +720,13 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -720,12 +720,13 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
cfqd->dispatch_slice = 0; cfqd->dispatch_slice = 0;
} }
static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted) static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted,
int timed_out)
{ {
struct cfq_queue *cfqq = cfqd->active_queue; struct cfq_queue *cfqq = cfqd->active_queue;
if (cfqq) if (cfqq)
__cfq_slice_expired(cfqd, cfqq, preempted); __cfq_slice_expired(cfqd, cfqq, preempted, timed_out);
} }
/* /*
...@@ -942,7 +943,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) ...@@ -942,7 +943,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
} }
expire: expire:
cfq_slice_expired(cfqd, 0); cfq_slice_expired(cfqd, 0, 0);
new_queue: new_queue:
cfqq = cfq_set_active_queue(cfqd); cfqq = cfq_set_active_queue(cfqd);
keep_queue: keep_queue:
...@@ -992,7 +993,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -992,7 +993,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) || cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
cfq_class_idle(cfqq)) { cfq_class_idle(cfqq)) {
cfqq->slice_end = jiffies + 1; cfqq->slice_end = jiffies + 1;
cfq_slice_expired(cfqd, 0); cfq_slice_expired(cfqd, 0, 0);
} }
return dispatched; return dispatched;
...@@ -1028,7 +1029,7 @@ cfq_forced_dispatch(struct cfq_data *cfqd) ...@@ -1028,7 +1029,7 @@ cfq_forced_dispatch(struct cfq_data *cfqd)
dispatched += cfq_forced_dispatch_cfqqs(&cfqd->cur_rr); dispatched += cfq_forced_dispatch_cfqqs(&cfqd->cur_rr);
dispatched += cfq_forced_dispatch_cfqqs(&cfqd->idle_rr); dispatched += cfq_forced_dispatch_cfqqs(&cfqd->idle_rr);
cfq_slice_expired(cfqd, 0); cfq_slice_expired(cfqd, 0, 0);
BUG_ON(cfqd->busy_queues); BUG_ON(cfqd->busy_queues);
...@@ -1102,7 +1103,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) ...@@ -1102,7 +1103,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
BUG_ON(cfq_cfqq_on_rr(cfqq)); BUG_ON(cfq_cfqq_on_rr(cfqq));
if (unlikely(cfqd->active_queue == cfqq)) if (unlikely(cfqd->active_queue == cfqq))
__cfq_slice_expired(cfqd, cfqq, 0); __cfq_slice_expired(cfqd, cfqq, 0, 0);
/* /*
* it's on the empty list and still hashed * it's on the empty list and still hashed
...@@ -1158,7 +1159,7 @@ static void cfq_free_io_context(struct io_context *ioc) ...@@ -1158,7 +1159,7 @@ static void cfq_free_io_context(struct io_context *ioc)
static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{ {
if (unlikely(cfqq == cfqd->active_queue)) if (unlikely(cfqq == cfqd->active_queue))
__cfq_slice_expired(cfqd, cfqq, 0); __cfq_slice_expired(cfqd, cfqq, 0, 0);
cfq_put_queue(cfqq); cfq_put_queue(cfqq);
} }
...@@ -1607,7 +1608,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, ...@@ -1607,7 +1608,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
*/ */
static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{ {
cfq_slice_expired(cfqd, 1); cfq_slice_expired(cfqd, 1, 1);
/* /*
* Put the new queue at the front of the of the current list, * Put the new queue at the front of the of the current list,
...@@ -1650,7 +1651,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -1650,7 +1651,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
*/ */
if (cic == cfqd->active_cic && if (cic == cfqd->active_cic &&
del_timer(&cfqd->idle_slice_timer)) { del_timer(&cfqd->idle_slice_timer)) {
cfq_slice_expired(cfqd, 0); cfq_slice_expired(cfqd, 0, 0);
blk_start_queueing(cfqd->queue); blk_start_queueing(cfqd->queue);
} }
return; return;
...@@ -1732,7 +1733,7 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) ...@@ -1732,7 +1733,7 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq)
cfq_clear_cfqq_slice_new(cfqq); cfq_clear_cfqq_slice_new(cfqq);
} }
if (cfq_slice_used(cfqq)) if (cfq_slice_used(cfqq))
cfq_slice_expired(cfqd, 0); cfq_slice_expired(cfqd, 0, 1);
else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list)) { else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list)) {
if (!cfq_arm_slice_timer(cfqd)) if (!cfq_arm_slice_timer(cfqd))
cfq_schedule_dispatch(cfqd); cfq_schedule_dispatch(cfqd);
...@@ -1906,10 +1907,13 @@ static void cfq_idle_slice_timer(unsigned long data) ...@@ -1906,10 +1907,13 @@ static void cfq_idle_slice_timer(unsigned long data)
struct cfq_data *cfqd = (struct cfq_data *) data; struct cfq_data *cfqd = (struct cfq_data *) data;
struct cfq_queue *cfqq; struct cfq_queue *cfqq;
unsigned long flags; unsigned long flags;
int timed_out = 1;
spin_lock_irqsave(cfqd->queue->queue_lock, flags); spin_lock_irqsave(cfqd->queue->queue_lock, flags);
if ((cfqq = cfqd->active_queue) != NULL) { if ((cfqq = cfqd->active_queue) != NULL) {
timed_out = 0;
/* /*
* expired * expired
*/ */
...@@ -1932,7 +1936,7 @@ static void cfq_idle_slice_timer(unsigned long data) ...@@ -1932,7 +1936,7 @@ static void cfq_idle_slice_timer(unsigned long data)
} }
} }
expire: expire:
cfq_slice_expired(cfqd, 0); cfq_slice_expired(cfqd, 0, timed_out);
out_kick: out_kick:
cfq_schedule_dispatch(cfqd); cfq_schedule_dispatch(cfqd);
out_cont: out_cont:
...@@ -1978,7 +1982,7 @@ static void cfq_exit_queue(elevator_t *e) ...@@ -1978,7 +1982,7 @@ static void cfq_exit_queue(elevator_t *e)
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
if (cfqd->active_queue) if (cfqd->active_queue)
__cfq_slice_expired(cfqd, cfqd->active_queue, 0); __cfq_slice_expired(cfqd, cfqd->active_queue, 0, 0);
while (!list_empty(&cfqd->cic_list)) { while (!list_empty(&cfqd->cic_list)) {
struct cfq_io_context *cic = list_entry(cfqd->cic_list.next, struct cfq_io_context *cic = list_entry(cfqd->cic_list.next,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment