diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2007-01-18 20:06:33 -0500 |
---|---|---|
committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2007-02-11 17:14:45 -0500 |
commit | 3c6bd2f879d2c12ce369fe5f75e608ac7bacf01a (patch) | |
tree | b4fe059420762d542c14acc29ca0638c514410d9 | |
parent | cb8874119e9a3ec38c45942808c91cfbc014f402 (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.c | 32 |
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 | */ |
689 | static void | 689 | static 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 | ||
723 | static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted) | 723 | static 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 | ||
944 | expire: | 945 | expire: |
945 | cfq_slice_expired(cfqd, 0); | 946 | cfq_slice_expired(cfqd, 0, 0); |
946 | new_queue: | 947 | new_queue: |
947 | cfqq = cfq_set_active_queue(cfqd); | 948 | cfqq = cfq_set_active_queue(cfqd); |
948 | keep_queue: | 949 | keep_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) | |||
1158 | static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 1159 | static 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 | */ |
1608 | static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 1609 | static 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 | } |
1934 | expire: | 1938 | expire: |
1935 | cfq_slice_expired(cfqd, 0); | 1939 | cfq_slice_expired(cfqd, 0, timed_out); |
1936 | out_kick: | 1940 | out_kick: |
1937 | cfq_schedule_dispatch(cfqd); | 1941 | cfq_schedule_dispatch(cfqd); |
1938 | out_cont: | 1942 | out_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, |