Merge "block, bfq: fix use-after-free in bfq_idle_slice_timer_body"

This commit is contained in:
qctecmdr 2020-06-11 21:35:30 -07:00 • committed by Gerrit - the friendly Code Review server
commit 0b5c25955b

View file

@ -6210,20 +6210,28 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
return bfqq;
}
static void bfq_idle_slice_timer_body(struct bfq_queue *bfqq)
static void
bfq_idle_slice_timer_body(struct bfq_data *bfqd, struct bfq_queue *bfqq)
{
struct bfq_data *bfqd = bfqq->bfqd;
enum bfqq_expiration reason;
unsigned long flags;
spin_lock_irqsave(&bfqd->lock, flags);
bfq_clear_bfqq_wait_request(bfqq);
/*
* Considering that bfqq may be in race, we should firstly check
* whether bfqq is in service before doing something on it. If
* the bfqq in race is not in service, it has already been expired
* through __bfq_bfqq_expire func and its wait_request flags has
* been cleared in __bfq_bfqd_reset_in_service func.
*/
if (bfqq != bfqd->in_service_queue) {
spin_unlock_irqrestore(&bfqd->lock, flags);
return;
}
bfq_clear_bfqq_wait_request(bfqq);
if (bfq_bfqq_budget_timeout(bfqq))
/*
* Also here the queue can be safely expired
@ -6268,7 +6276,7 @@ static enum hrtimer_restart bfq_idle_slice_timer(struct hrtimer *timer)
* early.
*/
if (bfqq)
bfq_idle_slice_timer_body(bfqq);
bfq_idle_slice_timer_body(bfqd, bfqq);
return HRTIMER_NORESTART;
}