diff options
-rw-r--r-- | block/cfq-iosched.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index b0b754a6882b..a55a9bd75bd1 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -154,6 +154,8 @@ struct cfq_queue { | |||
154 | unsigned long rb_key; | 154 | unsigned long rb_key; |
155 | /* prio tree member */ | 155 | /* prio tree member */ |
156 | struct rb_node p_node; | 156 | struct rb_node p_node; |
157 | /* prio tree root we belong to, if any */ | ||
158 | struct rb_root *p_root; | ||
157 | /* sorted list of pending requests */ | 159 | /* sorted list of pending requests */ |
158 | struct rb_root sort_list; | 160 | struct rb_root sort_list; |
159 | /* if fifo isn't expired, next request to serve */ | 161 | /* if fifo isn't expired, next request to serve */ |
@@ -558,10 +560,10 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
558 | } | 560 | } |
559 | 561 | ||
560 | static struct cfq_queue * | 562 | static struct cfq_queue * |
561 | cfq_prio_tree_lookup(struct cfq_data *cfqd, int ioprio, sector_t sector, | 563 | cfq_prio_tree_lookup(struct cfq_data *cfqd, struct rb_root *root, |
562 | struct rb_node **ret_parent, struct rb_node ***rb_link) | 564 | sector_t sector, struct rb_node **ret_parent, |
565 | struct rb_node ***rb_link) | ||
563 | { | 566 | { |
564 | struct rb_root *root = &cfqd->prio_trees[ioprio]; | ||
565 | struct rb_node **p, *parent; | 567 | struct rb_node **p, *parent; |
566 | struct cfq_queue *cfqq = NULL; | 568 | struct cfq_queue *cfqq = NULL; |
567 | 569 | ||
@@ -595,24 +597,27 @@ cfq_prio_tree_lookup(struct cfq_data *cfqd, int ioprio, sector_t sector, | |||
595 | 597 | ||
596 | static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq) | 598 | static void cfq_prio_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq) |
597 | { | 599 | { |
598 | struct rb_root *root = &cfqd->prio_trees[cfqq->ioprio]; | ||
599 | struct rb_node **p, *parent; | 600 | struct rb_node **p, *parent; |
600 | struct cfq_queue *__cfqq; | 601 | struct cfq_queue *__cfqq; |
601 | 602 | ||
602 | if (!RB_EMPTY_NODE(&cfqq->p_node)) | 603 | if (cfqq->p_root) { |
603 | rb_erase_init(&cfqq->p_node, root); | 604 | rb_erase(&cfqq->p_node, cfqq->p_root); |
605 | cfqq->p_root = NULL; | ||
606 | } | ||
604 | 607 | ||
605 | if (cfq_class_idle(cfqq)) | 608 | if (cfq_class_idle(cfqq)) |
606 | return; | 609 | return; |
607 | if (!cfqq->next_rq) | 610 | if (!cfqq->next_rq) |
608 | return; | 611 | return; |
609 | 612 | ||
610 | __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->ioprio, cfqq->next_rq->sector, | 613 | cfqq->p_root = &cfqd->prio_trees[cfqq->org_ioprio]; |
614 | __cfqq = cfq_prio_tree_lookup(cfqd, cfqq->p_root, cfqq->next_rq->sector, | ||
611 | &parent, &p); | 615 | &parent, &p); |
612 | if (!__cfqq) { | 616 | if (!__cfqq) { |
613 | rb_link_node(&cfqq->p_node, parent, p); | 617 | rb_link_node(&cfqq->p_node, parent, p); |
614 | rb_insert_color(&cfqq->p_node, root); | 618 | rb_insert_color(&cfqq->p_node, cfqq->p_root); |
615 | } | 619 | } else |
620 | cfqq->p_root = NULL; | ||
616 | } | 621 | } |
617 | 622 | ||
618 | /* | 623 | /* |
@@ -657,8 +662,10 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) | |||
657 | 662 | ||
658 | if (!RB_EMPTY_NODE(&cfqq->rb_node)) | 663 | if (!RB_EMPTY_NODE(&cfqq->rb_node)) |
659 | cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree); | 664 | cfq_rb_erase(&cfqq->rb_node, &cfqd->service_tree); |
660 | if (!RB_EMPTY_NODE(&cfqq->p_node)) | 665 | if (cfqq->p_root) { |
661 | rb_erase_init(&cfqq->p_node, &cfqd->prio_trees[cfqq->ioprio]); | 666 | rb_erase(&cfqq->p_node, cfqq->p_root); |
667 | cfqq->p_root = NULL; | ||
668 | } | ||
662 | 669 | ||
663 | BUG_ON(!cfqd->busy_queues); | 670 | BUG_ON(!cfqd->busy_queues); |
664 | cfqd->busy_queues--; | 671 | cfqd->busy_queues--; |
@@ -965,7 +972,7 @@ static inline int cfq_rq_close(struct cfq_data *cfqd, struct request *rq) | |||
965 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | 972 | static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, |
966 | struct cfq_queue *cur_cfqq) | 973 | struct cfq_queue *cur_cfqq) |
967 | { | 974 | { |
968 | struct rb_root *root = &cfqd->prio_trees[cur_cfqq->ioprio]; | 975 | struct rb_root *root = &cfqd->prio_trees[cur_cfqq->org_ioprio]; |
969 | struct rb_node *parent, *node; | 976 | struct rb_node *parent, *node; |
970 | struct cfq_queue *__cfqq; | 977 | struct cfq_queue *__cfqq; |
971 | sector_t sector = cfqd->last_position; | 978 | sector_t sector = cfqd->last_position; |
@@ -977,8 +984,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd, | |||
977 | * First, if we find a request starting at the end of the last | 984 | * First, if we find a request starting at the end of the last |
978 | * request, choose it. | 985 | * request, choose it. |
979 | */ | 986 | */ |
980 | __cfqq = cfq_prio_tree_lookup(cfqd, cur_cfqq->ioprio, | 987 | __cfqq = cfq_prio_tree_lookup(cfqd, root, sector, &parent, NULL); |
981 | sector, &parent, NULL); | ||
982 | if (__cfqq) | 988 | if (__cfqq) |
983 | return __cfqq; | 989 | return __cfqq; |
984 | 990 | ||