[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190807141754.3567-2-paolo.valente@linaro.org>
Date: Wed, 7 Aug 2019 16:17:53 +0200
From: Paolo Valente <paolo.valente@...aro.org>
To: Jens Axboe <axboe@...nel.dk>
Cc: linux-block@...r.kernel.org, linux-kernel@...r.kernel.org,
ulf.hansson@...aro.org, linus.walleij@...aro.org,
bfq-iosched@...glegroups.com, oleksandr@...alenko.name,
pavel@...x.de, Paolo Valente <paolo.valente@...aro.org>,
Douglas Anderson <dianders@...omium.org>
Subject: [PATCH BUGFIX 1/2] block, bfq: reset last_completed_rq_bfqq if the pointed queue is freed
Since commit 13a857a4c4e8 ("block, bfq: detect wakers and
unconditionally inject their I/O"), BFQ stores, in a per-device
pointer last_completed_rq_bfqq, the last bfq_queue that had an I/O
request completed. If some bfq_queue receives new I/O right after the
last request of last_completed_rq_bfqq has been completed, then
last_completed_rq_bfqq may be a waker bfq_queue.
But if the bfq_queue last_completed_rq_bfqq points to is freed, then
last_completed_rq_bfqq becomes a dangling reference. This commit
resets last_completed_rq_bfqq if the pointed bfq_queue is freed.
Fixes: 13a857a4c4e8 ("block, bfq: detect wakers and unconditionally inject their I/O")
Reported-by: Douglas Anderson <dianders@...omium.org>
Tested-by: Douglas Anderson <dianders@...omium.org>
Signed-off-by: Paolo Valente <paolo.valente@...aro.org>
---
block/bfq-iosched.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 586fcfe227ea..b2009650afc2 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -1924,12 +1924,13 @@ static void bfq_add_request(struct request *rq)
* confirmed no later than during the next
* I/O-plugging interval for bfqq.
*/
- if (!bfq_bfqq_has_short_ttime(bfqq) &&
+ if (bfqd->last_completed_rq_bfqq &&
+ !bfq_bfqq_has_short_ttime(bfqq) &&
ktime_get_ns() - bfqd->last_completion <
200 * NSEC_PER_USEC) {
if (bfqd->last_completed_rq_bfqq != bfqq &&
- bfqd->last_completed_rq_bfqq !=
- bfqq->waker_bfqq) {
+ bfqd->last_completed_rq_bfqq !=
+ bfqq->waker_bfqq) {
/*
* First synchronization detected with
* a candidate waker queue, or with a
@@ -4808,6 +4809,9 @@ void bfq_put_queue(struct bfq_queue *bfqq)
bfqq->bfqd->burst_size--;
}
+ if (bfqq->bfqd && bfqq->bfqd->last_completed_rq_bfqq == bfqq)
+ bfqq->bfqd->last_completed_rq_bfqq = NULL;
+
kmem_cache_free(bfq_pool, bfqq);
#ifdef CONFIG_BFQ_GROUP_IOSCHED
bfqg_and_blkg_put(bfqg);
--
2.20.1
Powered by blists - more mailing lists