Skip to content

Commit

Permalink
block/cfq: cache rightmost rb_node
Browse files Browse the repository at this point in the history
commit f0f1a45f95e85a8ac28c4d62bf2a84db0799efab upstream.

For the same reasons we already cache the leftmost pointer, apply the same
optimization for rb_last() calls.  Users must explicitly do this as
rb_root_cached only deals with the smallest node.

[[email protected]: brain fart 8890q#1]
  Link: http://lkml.kernel.org/r/[email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Davidlohr Bueso <[email protected]>
Cc: Jens Axboe <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Harsh Shandilya <[email protected]>
Signed-off-by: Oktapra Amtono <[email protected]>
  • Loading branch information
Davidlohr Bueso authored and HarryPottreDev committed Nov 8, 2024
1 parent f7e8364 commit ed5eb39
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,13 @@ struct cfq_ttime {
*/
struct cfq_rb_root {
struct rb_root_cached rb;
struct rb_node *rb_rightmost;
unsigned count;
u64 min_vdisktime;
struct cfq_ttime ttime;
};
#define CFQ_RB_ROOT (struct cfq_rb_root) { .rb = RB_ROOT_CACHED, \
.rb_rightmost = NULL, \
.ttime = {.last_end_request = ktime_get_ns(),},}

/*
Expand Down Expand Up @@ -1187,6 +1189,9 @@ static struct cfq_group *cfq_rb_first_group(struct cfq_rb_root *root)

static void cfq_rb_erase(struct rb_node *n, struct cfq_rb_root *root)
{
if (root->rb_rightmost == n)
root->rb_rightmost = rb_prev(n);

rb_erase_cached(n, &root->rb);
RB_CLEAR_NODE(n);

Expand Down Expand Up @@ -1243,20 +1248,24 @@ __cfq_group_service_tree_add(struct cfq_rb_root *st, struct cfq_group *cfqg)
struct rb_node *parent = NULL;
struct cfq_group *__cfqg;
s64 key = cfqg_key(st, cfqg);
bool leftmost = true;
bool leftmost = true, rightmost = true;

while (*node != NULL) {
parent = *node;
__cfqg = rb_entry_cfqg(parent);

if (key < cfqg_key(st, __cfqg))
if (key < cfqg_key(st, __cfqg)) {
node = &parent->rb_left;
else {
rightmost = false;
} else {
node = &parent->rb_right;
leftmost = false;
}
}

if (rightmost)
st->rb_rightmost = &cfqg->rb_node;

rb_link_node(&cfqg->rb_node, parent, node);
rb_insert_color_cached(&cfqg->rb_node, &st->rb, leftmost);
}
Expand Down Expand Up @@ -1351,7 +1360,7 @@ cfq_group_notify_queue_add(struct cfq_data *cfqd, struct cfq_group *cfqg)
* so that groups get lesser vtime based on their weights, so that
* if group does not loose all if it was not continuously backlogged.
*/
n = rb_last(&st->rb.rb_root);
n = st->rb_rightmost;
if (n) {
__cfqg = rb_entry_cfqg(n);
cfqg->vdisktime = __cfqg->vdisktime + CFQ_IDLE_DELAY;
Expand Down Expand Up @@ -2205,7 +2214,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
st = st_for(cfqq->cfqg, cfqq_class(cfqq), cfqq_type(cfqq));
if (cfq_class_idle(cfqq)) {
rb_key = CFQ_IDLE_DELAY;
parent = rb_last(&st->rb.rb_root);
parent = st->rb_rightmost;
if (parent && parent != &cfqq->rb_node) {
__cfqq = rb_entry(parent, struct cfq_queue, rb_node);
rb_key += __cfqq->rb_key;
Expand Down

0 comments on commit ed5eb39

Please sign in to comment.