aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-01-18 20:06:33 -0500
committerJens Axboe <axboe@carl.home.kernel.dk>2007-02-11 17:14:45 -0500
commit3c6bd2f879d2c12ce369fe5f75e608ac7bacf01a (patch)
treeb4fe059420762d542c14acc29ca0638c514410d9
parentcb8874119e9a3ec38c45942808c91cfbc014f402 (diff)
cfq-iosched: check whether a queue timed out in accounting
Makes it more fair for the residual slice count. Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/cfq-iosched.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 03b1e474b2bf..bf571b2b7d76 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -688,7 +688,7 @@ __cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
688 */ 688 */
689static void 689static void
690__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, 690__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
691 int preempted) 691 int preempted, int timed_out)
692{ 692{
693 if (cfq_cfqq_wait_request(cfqq)) 693 if (cfq_cfqq_wait_request(cfqq))
694 del_timer(&cfqd->idle_slice_timer); 694 del_timer(&cfqd->idle_slice_timer);
@@ -704,7 +704,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
704 * store what was left of this slice, if the queue idled out 704 * store what was left of this slice, if the queue idled out
705 * or was preempted 705 * or was preempted
706 */ 706 */
707 if (!cfq_cfqq_slice_new(cfqq)) 707 if (timed_out && !cfq_cfqq_slice_new(cfqq))
708 cfqq->slice_resid = cfqq->slice_end - jiffies; 708 cfqq->slice_resid = cfqq->slice_end - jiffies;
709 709
710 cfq_resort_rr_list(cfqq, preempted); 710 cfq_resort_rr_list(cfqq, preempted);
@@ -720,12 +720,13 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
720 cfqd->dispatch_slice = 0; 720 cfqd->dispatch_slice = 0;
721} 721}
722 722
723static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted) 723static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted,
724 int timed_out)
724{ 725{
725 struct cfq_queue *cfqq = cfqd->active_queue; 726 struct cfq_queue *cfqq = cfqd->active_queue;
726 727
727 if (cfqq) 728 if (cfqq)
728 __cfq_slice_expired(cfqd, cfqq, preempted); 729 __cfq_slice_expired(cfqd, cfqq, preempted, timed_out);
729} 730}
730 731
731/* 732/*
@@ -942,7 +943,7 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
942 } 943 }
943 944
944expire: 945expire:
945 cfq_slice_expired(cfqd, 0); 946 cfq_slice_expired(cfqd, 0, 0);
946new_queue: 947new_queue:
947 cfqq = cfq_set_active_queue(cfqd); 948 cfqq = cfq_set_active_queue(cfqd);
948keep_queue: 949keep_queue:
@@ -992,7 +993,7 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
992 cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) || 993 cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
993 cfq_class_idle(cfqq)) { 994 cfq_class_idle(cfqq)) {
994 cfqq->slice_end = jiffies + 1; 995 cfqq->slice_end = jiffies + 1;
995 cfq_slice_expired(cfqd, 0); 996 cfq_slice_expired(cfqd, 0, 0);
996 } 997 }
997 998
998 return dispatched; 999 return dispatched;
@@ -1028,7 +1029,7 @@ cfq_forced_dispatch(struct cfq_data *cfqd)
1028 dispatched += cfq_forced_dispatch_cfqqs(&cfqd->cur_rr); 1029 dispatched += cfq_forced_dispatch_cfqqs(&cfqd->cur_rr);
1029 dispatched += cfq_forced_dispatch_cfqqs(&cfqd->idle_rr); 1030 dispatched += cfq_forced_dispatch_cfqqs(&cfqd->idle_rr);
1030 1031
1031 cfq_slice_expired(cfqd, 0); 1032 cfq_slice_expired(cfqd, 0, 0);
1032 1033
1033 BUG_ON(cfqd->busy_queues); 1034 BUG_ON(cfqd->busy_queues);
1034 1035
@@ -1102,7 +1103,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq)
1102 BUG_ON(cfq_cfqq_on_rr(cfqq)); 1103 BUG_ON(cfq_cfqq_on_rr(cfqq));
1103 1104
1104 if (unlikely(cfqd->active_queue == cfqq)) 1105 if (unlikely(cfqd->active_queue == cfqq))
1105 __cfq_slice_expired(cfqd, cfqq, 0); 1106 __cfq_slice_expired(cfqd, cfqq, 0, 0);
1106 1107
1107 /* 1108 /*
1108 * it's on the empty list and still hashed 1109 * it's on the empty list and still hashed
@@ -1158,7 +1159,7 @@ static void cfq_free_io_context(struct io_context *ioc)
1158static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) 1159static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1159{ 1160{
1160 if (unlikely(cfqq == cfqd->active_queue)) 1161 if (unlikely(cfqq == cfqd->active_queue))
1161 __cfq_slice_expired(cfqd, cfqq, 0); 1162 __cfq_slice_expired(cfqd, cfqq, 0, 0);
1162 1163
1163 cfq_put_queue(cfqq); 1164 cfq_put_queue(cfqq);
1164} 1165}
@@ -1607,7 +1608,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
1607 */ 1608 */
1608static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) 1609static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1609{ 1610{
1610 cfq_slice_expired(cfqd, 1); 1611 cfq_slice_expired(cfqd, 1, 1);
1611 1612
1612 /* 1613 /*
1613 * Put the new queue at the front of the of the current list, 1614 * 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 */ 1651 */
1651 if (cic == cfqd->active_cic && 1652 if (cic == cfqd->active_cic &&
1652 del_timer(&cfqd->idle_slice_timer)) { 1653 del_timer(&cfqd->idle_slice_timer)) {
1653 cfq_slice_expired(cfqd, 0); 1654 cfq_slice_expired(cfqd, 0, 0);
1654 blk_start_queueing(cfqd->queue); 1655 blk_start_queueing(cfqd->queue);
1655 } 1656 }
1656 return; 1657 return;
@@ -1732,7 +1733,7 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq)
1732 cfq_clear_cfqq_slice_new(cfqq); 1733 cfq_clear_cfqq_slice_new(cfqq);
1733 } 1734 }
1734 if (cfq_slice_used(cfqq)) 1735 if (cfq_slice_used(cfqq))
1735 cfq_slice_expired(cfqd, 0); 1736 cfq_slice_expired(cfqd, 0, 1);
1736 else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list)) { 1737 else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list)) {
1737 if (!cfq_arm_slice_timer(cfqd)) 1738 if (!cfq_arm_slice_timer(cfqd))
1738 cfq_schedule_dispatch(cfqd); 1739 cfq_schedule_dispatch(cfqd);
@@ -1906,10 +1907,13 @@ static void cfq_idle_slice_timer(unsigned long data)
1906 struct cfq_data *cfqd = (struct cfq_data *) data; 1907 struct cfq_data *cfqd = (struct cfq_data *) data;
1907 struct cfq_queue *cfqq; 1908 struct cfq_queue *cfqq;
1908 unsigned long flags; 1909 unsigned long flags;
1910 int timed_out = 1;
1909 1911
1910 spin_lock_irqsave(cfqd->queue->queue_lock, flags); 1912 spin_lock_irqsave(cfqd->queue->queue_lock, flags);
1911 1913
1912 if ((cfqq = cfqd->active_queue) != NULL) { 1914 if ((cfqq = cfqd->active_queue) != NULL) {
1915 timed_out = 0;
1916
1913 /* 1917 /*
1914 * expired 1918 * expired
1915 */ 1919 */
@@ -1932,7 +1936,7 @@ static void cfq_idle_slice_timer(unsigned long data)
1932 } 1936 }
1933 } 1937 }
1934expire: 1938expire:
1935 cfq_slice_expired(cfqd, 0); 1939 cfq_slice_expired(cfqd, 0, timed_out);
1936out_kick: 1940out_kick:
1937 cfq_schedule_dispatch(cfqd); 1941 cfq_schedule_dispatch(cfqd);
1938out_cont: 1942out_cont:
@@ -1978,7 +1982,7 @@ static void cfq_exit_queue(elevator_t *e)
1978 spin_lock_irq(q->queue_lock); 1982 spin_lock_irq(q->queue_lock);
1979 1983
1980 if (cfqd->active_queue) 1984 if (cfqd->active_queue)
1981 __cfq_slice_expired(cfqd, cfqd->active_queue, 0); 1985 __cfq_slice_expired(cfqd, cfqd->active_queue, 0, 0);
1982 1986
1983 while (!list_empty(&cfqd->cic_list)) { 1987 while (!list_empty(&cfqd->cic_list)) {
1984 struct cfq_io_context *cic = list_entry(cfqd->cic_list.next, 1988 struct cfq_io_context *cic = list_entry(cfqd->cic_list.next,