diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2019-08-07 13:21:11 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-08-08 09:31:50 -0400 |
commit | fd03177c33b287c6541f4048f1d67b7b45a1abc9 (patch) | |
tree | 1e95e71d6ba6bd86620b9d1267b89e463ed4df2c /block | |
parent | 3f758e844aa9800eb660d60ee10226fa802594d4 (diff) |
block, bfq: handle NULL return value by bfq_init_rq()
As reported in [1], the call bfq_init_rq(rq) may return NULL in case
of OOM (in particular, if rq->elv.icq is NULL because memory
allocation failed in failed in ioc_create_icq()).
This commit handles this circumstance.
[1] https://lkml.org/lkml/2019/7/22/824
Cc: Hsin-Yi Wang <hsinyi@google.com>
Cc: Nicolas Boichat <drinkcat@chromium.org>
Cc: Doug Anderson <dianders@chromium.org>
Reported-by: Guenter Roeck <linux@roeck-us.net>
Reported-by: Hsin-Yi Wang <hsinyi@google.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/bfq-iosched.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 5f477501bb3d..b33be928d164 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c | |||
@@ -2251,9 +2251,14 @@ static void bfq_request_merged(struct request_queue *q, struct request *req, | |||
2251 | blk_rq_pos(container_of(rb_prev(&req->rb_node), | 2251 | blk_rq_pos(container_of(rb_prev(&req->rb_node), |
2252 | struct request, rb_node))) { | 2252 | struct request, rb_node))) { |
2253 | struct bfq_queue *bfqq = bfq_init_rq(req); | 2253 | struct bfq_queue *bfqq = bfq_init_rq(req); |
2254 | struct bfq_data *bfqd = bfqq->bfqd; | 2254 | struct bfq_data *bfqd; |
2255 | struct request *prev, *next_rq; | 2255 | struct request *prev, *next_rq; |
2256 | 2256 | ||
2257 | if (!bfqq) | ||
2258 | return; | ||
2259 | |||
2260 | bfqd = bfqq->bfqd; | ||
2261 | |||
2257 | /* Reposition request in its sort_list */ | 2262 | /* Reposition request in its sort_list */ |
2258 | elv_rb_del(&bfqq->sort_list, req); | 2263 | elv_rb_del(&bfqq->sort_list, req); |
2259 | elv_rb_add(&bfqq->sort_list, req); | 2264 | elv_rb_add(&bfqq->sort_list, req); |
@@ -2300,6 +2305,9 @@ static void bfq_requests_merged(struct request_queue *q, struct request *rq, | |||
2300 | struct bfq_queue *bfqq = bfq_init_rq(rq), | 2305 | struct bfq_queue *bfqq = bfq_init_rq(rq), |
2301 | *next_bfqq = bfq_init_rq(next); | 2306 | *next_bfqq = bfq_init_rq(next); |
2302 | 2307 | ||
2308 | if (!bfqq) | ||
2309 | return; | ||
2310 | |||
2303 | /* | 2311 | /* |
2304 | * If next and rq belong to the same bfq_queue and next is older | 2312 | * If next and rq belong to the same bfq_queue and next is older |
2305 | * than rq, then reposition rq in the fifo (by substituting next | 2313 | * than rq, then reposition rq in the fifo (by substituting next |
@@ -5454,12 +5462,12 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, | |||
5454 | 5462 | ||
5455 | spin_lock_irq(&bfqd->lock); | 5463 | spin_lock_irq(&bfqd->lock); |
5456 | bfqq = bfq_init_rq(rq); | 5464 | bfqq = bfq_init_rq(rq); |
5457 | if (at_head || blk_rq_is_passthrough(rq)) { | 5465 | if (!bfqq || at_head || blk_rq_is_passthrough(rq)) { |
5458 | if (at_head) | 5466 | if (at_head) |
5459 | list_add(&rq->queuelist, &bfqd->dispatch); | 5467 | list_add(&rq->queuelist, &bfqd->dispatch); |
5460 | else | 5468 | else |
5461 | list_add_tail(&rq->queuelist, &bfqd->dispatch); | 5469 | list_add_tail(&rq->queuelist, &bfqd->dispatch); |
5462 | } else { /* bfqq is assumed to be non null here */ | 5470 | } else { |
5463 | idle_timer_disabled = __bfq_insert_request(bfqd, rq); | 5471 | idle_timer_disabled = __bfq_insert_request(bfqd, rq); |
5464 | /* | 5472 | /* |
5465 | * Update bfqq, because, if a queue merge has occurred | 5473 | * Update bfqq, because, if a queue merge has occurred |