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, |
