diff options
Diffstat (limited to 'block/cfq-iosched.c')
| -rw-r--r-- | block/cfq-iosched.c | 124 |
1 files changed, 43 insertions, 81 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index e2f80463ed0d..023f4e69a337 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -42,16 +42,13 @@ static const int cfq_hist_divisor = 4; | |||
| 42 | */ | 42 | */ |
| 43 | #define CFQ_MIN_TT (2) | 43 | #define CFQ_MIN_TT (2) |
| 44 | 44 | ||
| 45 | /* | ||
| 46 | * Allow merged cfqqs to perform this amount of seeky I/O before | ||
| 47 | * deciding to break the queues up again. | ||
| 48 | */ | ||
| 49 | #define CFQQ_COOP_TOUT (HZ) | ||
| 50 | |||
| 51 | #define CFQ_SLICE_SCALE (5) | 45 | #define CFQ_SLICE_SCALE (5) |
| 52 | #define CFQ_HW_QUEUE_MIN (5) | 46 | #define CFQ_HW_QUEUE_MIN (5) |
| 53 | #define CFQ_SERVICE_SHIFT 12 | 47 | #define CFQ_SERVICE_SHIFT 12 |
| 54 | 48 | ||
| 49 | #define CFQQ_SEEK_THR 8 * 1024 | ||
| 50 | #define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR) | ||
| 51 | |||
| 55 | #define RQ_CIC(rq) \ | 52 | #define RQ_CIC(rq) \ |
| 56 | ((struct cfq_io_context *) (rq)->elevator_private) | 53 | ((struct cfq_io_context *) (rq)->elevator_private) |
| 57 | #define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) | 54 | #define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) |
| @@ -137,7 +134,6 @@ struct cfq_queue { | |||
| 137 | u64 seek_total; | 134 | u64 seek_total; |
| 138 | sector_t seek_mean; | 135 | sector_t seek_mean; |
| 139 | sector_t last_request_pos; | 136 | sector_t last_request_pos; |
| 140 | unsigned long seeky_start; | ||
| 141 | 137 | ||
| 142 | pid_t pid; | 138 | pid_t pid; |
| 143 | 139 | ||
| @@ -208,8 +204,6 @@ struct cfq_data { | |||
| 208 | /* Root service tree for cfq_groups */ | 204 | /* Root service tree for cfq_groups */ |
| 209 | struct cfq_rb_root grp_service_tree; | 205 | struct cfq_rb_root grp_service_tree; |
| 210 | struct cfq_group root_group; | 206 | struct cfq_group root_group; |
| 211 | /* Number of active cfq groups on group service tree */ | ||
| 212 | int nr_groups; | ||
| 213 | 207 | ||
| 214 | /* | 208 | /* |
| 215 | * The priority currently being served | 209 | * The priority currently being served |
| @@ -294,8 +288,7 @@ static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd); | |||
| 294 | 288 | ||
| 295 | static struct cfq_rb_root *service_tree_for(struct cfq_group *cfqg, | 289 | static struct cfq_rb_root *service_tree_for(struct cfq_group *cfqg, |
| 296 | enum wl_prio_t prio, | 290 | enum wl_prio_t prio, |
| 297 | enum wl_type_t type, | 291 | enum wl_type_t type) |
| 298 | struct cfq_data *cfqd) | ||
| 299 | { | 292 | { |
| 300 | if (!cfqg) | 293 | if (!cfqg) |
| 301 | return NULL; | 294 | return NULL; |
| @@ -317,6 +310,7 @@ enum cfqq_state_flags { | |||
| 317 | CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ | 310 | CFQ_CFQQ_FLAG_slice_new, /* no requests dispatched in slice */ |
| 318 | CFQ_CFQQ_FLAG_sync, /* synchronous queue */ | 311 | CFQ_CFQQ_FLAG_sync, /* synchronous queue */ |
| 319 | CFQ_CFQQ_FLAG_coop, /* cfqq is shared */ | 312 | CFQ_CFQQ_FLAG_coop, /* cfqq is shared */ |
| 313 | CFQ_CFQQ_FLAG_split_coop, /* shared cfqq will be splitted */ | ||
| 320 | CFQ_CFQQ_FLAG_deep, /* sync cfqq experienced large depth */ | 314 | CFQ_CFQQ_FLAG_deep, /* sync cfqq experienced large depth */ |
| 321 | CFQ_CFQQ_FLAG_wait_busy, /* Waiting for next request */ | 315 | CFQ_CFQQ_FLAG_wait_busy, /* Waiting for next request */ |
| 322 | }; | 316 | }; |
| @@ -345,6 +339,7 @@ CFQ_CFQQ_FNS(prio_changed); | |||
| 345 | CFQ_CFQQ_FNS(slice_new); | 339 | CFQ_CFQQ_FNS(slice_new); |
| 346 | CFQ_CFQQ_FNS(sync); | 340 | CFQ_CFQQ_FNS(sync); |
| 347 | CFQ_CFQQ_FNS(coop); | 341 | CFQ_CFQQ_FNS(coop); |
| 342 | CFQ_CFQQ_FNS(split_coop); | ||
| 348 | CFQ_CFQQ_FNS(deep); | 343 | CFQ_CFQQ_FNS(deep); |
| 349 | CFQ_CFQQ_FNS(wait_busy); | 344 | CFQ_CFQQ_FNS(wait_busy); |
| 350 | #undef CFQ_CFQQ_FNS | 345 | #undef CFQ_CFQQ_FNS |
| @@ -842,7 +837,6 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg) | |||
| 842 | 837 | ||
| 843 | __cfq_group_service_tree_add(st, cfqg); | 838 | __cfq_group_service_tree_add(st, cfqg); |
| 844 | cfqg->on_st = true; | 839 | cfqg->on_st = true; |
| 845 | cfqd->nr_groups++; | ||
| 846 | st->total_weight += cfqg->weight; | 840 | st->total_weight += cfqg->weight; |
| 847 | } | 841 | } |
| 848 | 842 | ||
| @@ -863,7 +857,6 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg) | |||
| 863 | 857 | ||
| 864 | cfq_log_cfqg(cfqd, cfqg, "del_from_rr group"); | 858 | cfq_log_cfqg(cfqd, cfqg, "del_from_rr group"); |
| 865 | cfqg->on_st = false; | 859 | cfqg->on_st = false; |
| 866 | cfqd->nr_groups--; | ||
| 867 | st->total_weight -= cfqg->weight; | 860 | st->total_weight -= cfqg->weight; |
| 868 | if (!RB_EMPTY_NODE(&cfqg->rb_node)) | 861 | if (!RB_EMPTY_NODE(&cfqg->rb_node)) |
| 869 | cfq_rb_erase(&cfqg->rb_node, st); | 862 | cfq_rb_erase(&cfqg->rb_node, st); |
| @@ -1150,7 +1143,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 1150 | #endif | 1143 | #endif |
| 1151 | 1144 | ||
| 1152 | service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), | 1145 | service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq), |
| 1153 | cfqq_type(cfqq), cfqd); | 1146 | cfqq_type(cfqq)); |
| 1154 | if (cfq_class_idle(cfqq)) { | 1147 | if (cfq_class_idle(cfqq)) { |
| 1155 | rb_key = CFQ_IDLE_DELAY; | 1148 | rb_key = CFQ_IDLE_DELAY; |
| 1156 | parent = rb_last(&service_tree->rb); | 1149 | parent = rb_last(&service_tree->rb); |
| @@ -1513,9 +1506,6 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq, | |||
| 1513 | struct cfq_io_context *cic; | 1506 | struct cfq_io_context *cic; |
| 1514 | struct cfq_queue *cfqq; | 1507 | struct cfq_queue *cfqq; |
| 1515 | 1508 | ||
| 1516 | /* Deny merge if bio and rq don't belong to same cfq group */ | ||
| 1517 | if ((RQ_CFQQ(rq))->cfqg != cfq_get_cfqg(cfqd, 0)) | ||
| 1518 | return false; | ||
| 1519 | /* | 1509 | /* |
| 1520 | * Disallow merge of a sync bio into an async request. | 1510 | * Disallow merge of a sync bio into an async request. |
| 1521 | */ | 1511 | */ |
| @@ -1574,6 +1564,15 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 1574 | cfq_clear_cfqq_wait_busy(cfqq); | 1564 | cfq_clear_cfqq_wait_busy(cfqq); |
| 1575 | 1565 | ||
| 1576 | /* | 1566 | /* |
| 1567 | * If this cfqq is shared between multiple processes, check to | ||
| 1568 | * make sure that those processes are still issuing I/Os within | ||
| 1569 | * the mean seek distance. If not, it may be time to break the | ||
| 1570 | * queues apart again. | ||
| 1571 | */ | ||
| 1572 | if (cfq_cfqq_coop(cfqq) && CFQQ_SEEKY(cfqq)) | ||
| 1573 | cfq_mark_cfqq_split_coop(cfqq); | ||
| 1574 | |||
| 1575 | /* | ||
| 1577 | * store what was left of this slice, if the queue idled/timed out | 1576 | * store what was left of this slice, if the queue idled/timed out |
| 1578 | */ | 1577 | */ |
| 1579 | if (timed_out && !cfq_cfqq_slice_new(cfqq)) { | 1578 | if (timed_out && !cfq_cfqq_slice_new(cfqq)) { |
| @@ -1616,7 +1615,7 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd) | |||
| 1616 | { | 1615 | { |
| 1617 | struct cfq_rb_root *service_tree = | 1616 | struct cfq_rb_root *service_tree = |
| 1618 | service_tree_for(cfqd->serving_group, cfqd->serving_prio, | 1617 | service_tree_for(cfqd->serving_group, cfqd->serving_prio, |
| 1619 | cfqd->serving_type, cfqd); | 1618 | cfqd->serving_type); |
| 1620 | 1619 | ||
| 1621 | if (!cfqd->rq_queued) | 1620 | if (!cfqd->rq_queued) |
| 1622 | return NULL; | 1621 | return NULL; |
| @@ -1671,17 +1670,18 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd, | |||
| 1671 | return cfqd->last_position - blk_rq_pos(rq); | 1670 | return cfqd->last_position - blk_rq_pos(rq); |
| 1672 | } | 1671 | } |
| 1673 | 1672 | ||
| 1674 | #define CFQQ_SEEK_THR 8 * 1024 | ||
| 1675 | #define CFQQ_SEEKY(cfqq) ((cfqq)->seek_mean > CFQQ_SEEK_THR) | ||
| 1676 | |||
| 1677 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 1673 | static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
| 1678 | struct request *rq) | 1674 | struct request *rq, bool for_preempt) |
| 1679 | { | 1675 | { |
| 1680 | sector_t sdist = cfqq->seek_mean; | 1676 | sector_t sdist = cfqq->seek_mean; |
| 1681 | 1677 | ||
| 1682 | if (!sample_valid(cfqq->seek_samples)) | 1678 | if (!sample_valid(cfqq->seek_samples)) |
| 1683 | sdist = CFQQ_SEEK_THR; | 1679 | sdist = CFQQ_SEEK_THR; |
| 1684 | 1680 | ||
| 1681 | /* if seek_mean is big, using it as close criteria is meaningless */ | ||
| 1682 | if (sdist > CFQQ_SEEK_THR && !for_preempt) | ||
| 1683 | sdist = CFQQ_SEEK_THR; | ||
| 1684 | |||
| 1685 | return cfq_dist_from_last(cfqd, rq) <= sdist; | 1685 | return cfq_dist_from_last(cfqd, rq) <= sdist; |
| 1686 | } | 1686 | } |
| 1687 | 1687 | ||
| @@ -1709,7 +1709,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | |||
| 1709 | * will contain the closest sector. | 1709 | * will contain the closest sector. |
| 1710 | */ | 1710 | */ |
| 1711 | __cfqq = rb_entry(parent, struct cfq_queue, p_node); | 1711 | __cfqq = rb_entry(parent, struct cfq_queue, p_node); |
| 1712 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) | 1712 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) |
| 1713 | return __cfqq; | 1713 | return __cfqq; |
| 1714 | 1714 | ||
| 1715 | if (blk_rq_pos(__cfqq->next_rq) < sector) | 1715 | if (blk_rq_pos(__cfqq->next_rq) < sector) |
| @@ -1720,7 +1720,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | |||
| 1720 | return NULL; | 1720 | return NULL; |
| 1721 | 1721 | ||
| 1722 | __cfqq = rb_entry(node, struct cfq_queue, p_node); | 1722 | __cfqq = rb_entry(node, struct cfq_queue, p_node); |
| 1723 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq)) | 1723 | if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false)) |
| 1724 | return __cfqq; | 1724 | return __cfqq; |
| 1725 | 1725 | ||
| 1726 | return NULL; | 1726 | return NULL; |
| @@ -1807,7 +1807,7 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
| 1807 | * Otherwise, we do only if they are the last ones | 1807 | * Otherwise, we do only if they are the last ones |
| 1808 | * in their service tree. | 1808 | * in their service tree. |
| 1809 | */ | 1809 | */ |
| 1810 | return service_tree->count == 1; | 1810 | return service_tree->count == 1 && cfq_cfqq_sync(cfqq); |
| 1811 | } | 1811 | } |
| 1812 | 1812 | ||
| 1813 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) | 1813 | static void cfq_arm_slice_timer(struct cfq_data *cfqd) |
| @@ -1963,8 +1963,7 @@ static void cfq_setup_merge(struct cfq_queue *cfqq, struct cfq_queue *new_cfqq) | |||
| 1963 | } | 1963 | } |
| 1964 | 1964 | ||
| 1965 | static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, | 1965 | static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, |
| 1966 | struct cfq_group *cfqg, enum wl_prio_t prio, | 1966 | struct cfq_group *cfqg, enum wl_prio_t prio) |
| 1967 | bool prio_changed) | ||
| 1968 | { | 1967 | { |
| 1969 | struct cfq_queue *queue; | 1968 | struct cfq_queue *queue; |
| 1970 | int i; | 1969 | int i; |
| @@ -1972,24 +1971,9 @@ static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, | |||
| 1972 | unsigned long lowest_key = 0; | 1971 | unsigned long lowest_key = 0; |
| 1973 | enum wl_type_t cur_best = SYNC_NOIDLE_WORKLOAD; | 1972 | enum wl_type_t cur_best = SYNC_NOIDLE_WORKLOAD; |
| 1974 | 1973 | ||
| 1975 | if (prio_changed) { | 1974 | for (i = 0; i <= SYNC_WORKLOAD; ++i) { |
| 1976 | /* | 1975 | /* select the one with lowest rb_key */ |
| 1977 | * When priorities switched, we prefer starting | 1976 | queue = cfq_rb_first(service_tree_for(cfqg, prio, i)); |
| 1978 | * from SYNC_NOIDLE (first choice), or just SYNC | ||
| 1979 | * over ASYNC | ||
| 1980 | */ | ||
| 1981 | if (service_tree_for(cfqg, prio, cur_best, cfqd)->count) | ||
| 1982 | return cur_best; | ||
| 1983 | cur_best = SYNC_WORKLOAD; | ||
| 1984 | if (service_tree_for(cfqg, prio, cur_best, cfqd)->count) | ||
| 1985 | return cur_best; | ||
| 1986 | |||
| 1987 | return ASYNC_WORKLOAD; | ||
| 1988 | } | ||
| 1989 | |||
| 1990 | for (i = 0; i < 3; ++i) { | ||
| 1991 | /* otherwise, select the one with lowest rb_key */ | ||
| 1992 | queue = cfq_rb_first(service_tree_for(cfqg, prio, i, cfqd)); | ||
| 1993 | if (queue && | 1977 | if (queue && |
| 1994 | (!key_valid || time_before(queue->rb_key, lowest_key))) { | 1978 | (!key_valid || time_before(queue->rb_key, lowest_key))) { |
| 1995 | lowest_key = queue->rb_key; | 1979 | lowest_key = queue->rb_key; |
| @@ -2003,8 +1987,6 @@ static enum wl_type_t cfq_choose_wl(struct cfq_data *cfqd, | |||
| 2003 | 1987 | ||
| 2004 | static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) | 1988 | static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) |
| 2005 | { | 1989 | { |
| 2006 | enum wl_prio_t previous_prio = cfqd->serving_prio; | ||
| 2007 | bool prio_changed; | ||
| 2008 | unsigned slice; | 1990 | unsigned slice; |
| 2009 | unsigned count; | 1991 | unsigned count; |
| 2010 | struct cfq_rb_root *st; | 1992 | struct cfq_rb_root *st; |
| @@ -2032,24 +2014,19 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) | |||
| 2032 | * (SYNC, SYNC_NOIDLE, ASYNC), and to compute a workload | 2014 | * (SYNC, SYNC_NOIDLE, ASYNC), and to compute a workload |
| 2033 | * expiration time | 2015 | * expiration time |
| 2034 | */ | 2016 | */ |
| 2035 | prio_changed = (cfqd->serving_prio != previous_prio); | 2017 | st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type); |
| 2036 | st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type, | ||
| 2037 | cfqd); | ||
| 2038 | count = st->count; | 2018 | count = st->count; |
| 2039 | 2019 | ||
| 2040 | /* | 2020 | /* |
| 2041 | * If priority didn't change, check workload expiration, | 2021 | * check workload expiration, and that we still have other queues ready |
| 2042 | * and that we still have other queues ready | ||
| 2043 | */ | 2022 | */ |
| 2044 | if (!prio_changed && count && | 2023 | if (count && !time_after(jiffies, cfqd->workload_expires)) |
| 2045 | !time_after(jiffies, cfqd->workload_expires)) | ||
| 2046 | return; | 2024 | return; |
| 2047 | 2025 | ||
| 2048 | /* otherwise select new workload type */ | 2026 | /* otherwise select new workload type */ |
| 2049 | cfqd->serving_type = | 2027 | cfqd->serving_type = |
| 2050 | cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio, prio_changed); | 2028 | cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio); |
| 2051 | st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type, | 2029 | st = service_tree_for(cfqg, cfqd->serving_prio, cfqd->serving_type); |
| 2052 | cfqd); | ||
| 2053 | count = st->count; | 2030 | count = st->count; |
| 2054 | 2031 | ||
| 2055 | /* | 2032 | /* |
| @@ -3027,19 +3004,6 @@ cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 3027 | total = cfqq->seek_total + (cfqq->seek_samples/2); | 3004 | total = cfqq->seek_total + (cfqq->seek_samples/2); |
| 3028 | do_div(total, cfqq->seek_samples); | 3005 | do_div(total, cfqq->seek_samples); |
| 3029 | cfqq->seek_mean = (sector_t)total; | 3006 | cfqq->seek_mean = (sector_t)total; |
| 3030 | |||
| 3031 | /* | ||
| 3032 | * If this cfqq is shared between multiple processes, check to | ||
| 3033 | * make sure that those processes are still issuing I/Os within | ||
| 3034 | * the mean seek distance. If not, it may be time to break the | ||
| 3035 | * queues apart again. | ||
| 3036 | */ | ||
| 3037 | if (cfq_cfqq_coop(cfqq)) { | ||
| 3038 | if (CFQQ_SEEKY(cfqq) && !cfqq->seeky_start) | ||
| 3039 | cfqq->seeky_start = jiffies; | ||
| 3040 | else if (!CFQQ_SEEKY(cfqq)) | ||
| 3041 | cfqq->seeky_start = 0; | ||
| 3042 | } | ||
| 3043 | } | 3007 | } |
| 3044 | 3008 | ||
| 3045 | /* | 3009 | /* |
| @@ -3104,6 +3068,12 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
| 3104 | return true; | 3068 | return true; |
| 3105 | 3069 | ||
| 3106 | /* | 3070 | /* |
| 3071 | * Don't allow a non-RT request to preempt an ongoing RT cfqq timeslice. | ||
| 3072 | */ | ||
| 3073 | if (cfq_class_rt(cfqq) && !cfq_class_rt(new_cfqq)) | ||
| 3074 | return false; | ||
| 3075 | |||
| 3076 | /* | ||
| 3107 | * if the new request is sync, but the currently running queue is | 3077 | * if the new request is sync, but the currently running queue is |
| 3108 | * not, let the sync request have priority. | 3078 | * not, let the sync request have priority. |
| 3109 | */ | 3079 | */ |
| @@ -3143,7 +3113,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, | |||
| 3143 | * if this request is as-good as one we would expect from the | 3113 | * if this request is as-good as one we would expect from the |
| 3144 | * current cfqq, let it preempt | 3114 | * current cfqq, let it preempt |
| 3145 | */ | 3115 | */ |
| 3146 | if (cfq_rq_close(cfqd, cfqq, rq)) | 3116 | if (cfq_rq_close(cfqd, cfqq, rq, true)) |
| 3147 | return true; | 3117 | return true; |
| 3148 | 3118 | ||
| 3149 | return false; | 3119 | return false; |
| @@ -3474,14 +3444,6 @@ cfq_merge_cfqqs(struct cfq_data *cfqd, struct cfq_io_context *cic, | |||
| 3474 | return cic_to_cfqq(cic, 1); | 3444 | return cic_to_cfqq(cic, 1); |
| 3475 | } | 3445 | } |
| 3476 | 3446 | ||
| 3477 | static int should_split_cfqq(struct cfq_queue *cfqq) | ||
| 3478 | { | ||
| 3479 | if (cfqq->seeky_start && | ||
| 3480 | time_after(jiffies, cfqq->seeky_start + CFQQ_COOP_TOUT)) | ||
| 3481 | return 1; | ||
| 3482 | return 0; | ||
| 3483 | } | ||
| 3484 | |||
| 3485 | /* | 3447 | /* |
| 3486 | * Returns NULL if a new cfqq should be allocated, or the old cfqq if this | 3448 | * Returns NULL if a new cfqq should be allocated, or the old cfqq if this |
| 3487 | * was the last process referring to said cfqq. | 3449 | * was the last process referring to said cfqq. |
| @@ -3490,9 +3452,9 @@ static struct cfq_queue * | |||
| 3490 | split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq) | 3452 | split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq) |
| 3491 | { | 3453 | { |
| 3492 | if (cfqq_process_refs(cfqq) == 1) { | 3454 | if (cfqq_process_refs(cfqq) == 1) { |
| 3493 | cfqq->seeky_start = 0; | ||
| 3494 | cfqq->pid = current->pid; | 3455 | cfqq->pid = current->pid; |
| 3495 | cfq_clear_cfqq_coop(cfqq); | 3456 | cfq_clear_cfqq_coop(cfqq); |
| 3457 | cfq_clear_cfqq_split_coop(cfqq); | ||
| 3496 | return cfqq; | 3458 | return cfqq; |
| 3497 | } | 3459 | } |
| 3498 | 3460 | ||
| @@ -3531,7 +3493,7 @@ new_queue: | |||
| 3531 | /* | 3493 | /* |
| 3532 | * If the queue was seeky for too long, break it apart. | 3494 | * If the queue was seeky for too long, break it apart. |
| 3533 | */ | 3495 | */ |
| 3534 | if (cfq_cfqq_coop(cfqq) && should_split_cfqq(cfqq)) { | 3496 | if (cfq_cfqq_coop(cfqq) && cfq_cfqq_split_coop(cfqq)) { |
| 3535 | cfq_log_cfqq(cfqd, cfqq, "breaking apart cfqq"); | 3497 | cfq_log_cfqq(cfqd, cfqq, "breaking apart cfqq"); |
| 3536 | cfqq = split_cfqq(cic, cfqq); | 3498 | cfqq = split_cfqq(cic, cfqq); |
| 3537 | if (!cfqq) | 3499 | if (!cfqq) |
