Commit 48e025e6 authored by Corrado Zoccolo's avatar Corrado Zoccolo Committed by Jens Axboe

cfq-iosched: fix possible problem with jiffies wraparound

The RR service tree is indexed by a key that is relative to current jiffies.
This can cause problems on jiffies wraparound.

The patch fixes it using time_before comparison, and changing
the add_front path to use a relative number, too.
Signed-off-by: default avatarCorrado Zoccolo <czoccolo@gmail.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 30996f40
...@@ -512,8 +512,11 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -512,8 +512,11 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies; rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies;
rb_key += cfqq->slice_resid; rb_key += cfqq->slice_resid;
cfqq->slice_resid = 0; cfqq->slice_resid = 0;
} else } else {
rb_key = 0; rb_key = -HZ;
__cfqq = cfq_rb_first(&cfqd->service_tree);
rb_key += __cfqq ? __cfqq->rb_key : jiffies;
}
if (!RB_EMPTY_NODE(&cfqq->rb_node)) { if (!RB_EMPTY_NODE(&cfqq->rb_node)) {
/* /*
...@@ -547,7 +550,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, ...@@ -547,7 +550,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
n = &(*p)->rb_left; n = &(*p)->rb_left;
else if (cfq_class_idle(cfqq) > cfq_class_idle(__cfqq)) else if (cfq_class_idle(cfqq) > cfq_class_idle(__cfqq))
n = &(*p)->rb_right; n = &(*p)->rb_right;
else if (rb_key < __cfqq->rb_key) else if (time_before(rb_key, __cfqq->rb_key))
n = &(*p)->rb_left; n = &(*p)->rb_left;
else else
n = &(*p)->rb_right; n = &(*p)->rb_right;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment