| From 18949635e9125e4fff5d92b2645e46c80ebcc9be Mon Sep 17 00:00:00 2001 |
| From: Ming Lei <ming.lei@redhat.com> |
| Date: Thu, 26 Sep 2019 06:23:54 +0800 |
| Subject: [PATCH] blk-mq: move lockdep_assert_held() into elevator_exit |
| |
| commit 284b94be1925dbe035ce5218d8b5c197321262c7 upstream. |
| |
| Commit c48dac137a62 ("block: don't hold q->sysfs_lock in elevator_init_mq") |
| removes q->sysfs_lock from elevator_init_mq(), but forgot to deal with |
| lockdep_assert_held() called in blk_mq_sched_free_requests() which is |
| run in failure path of elevator_init_mq(). |
| |
| blk_mq_sched_free_requests() is called in the following 3 functions: |
| |
| elevator_init_mq() |
| elevator_exit() |
| blk_cleanup_queue() |
| |
| In blk_cleanup_queue(), blk_mq_sched_free_requests() is followed exactly |
| by 'mutex_lock(&q->sysfs_lock)'. |
| |
| So moving the lockdep_assert_held() from blk_mq_sched_free_requests() |
| into elevator_exit() for fixing the report by syzbot. |
| |
| Reported-by: syzbot+da3b7677bb913dc1b737@syzkaller.appspotmail.com |
| Fixed: c48dac137a62 ("block: don't hold q->sysfs_lock in elevator_init_mq") |
| Reviewed-by: Bart Van Assche <bvanassche@acm.org> |
| Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com> |
| Signed-off-by: Ming Lei <ming.lei@redhat.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c |
| index 2766066a15db..3cf555f12700 100644 |
| --- a/block/blk-mq-sched.c |
| +++ b/block/blk-mq-sched.c |
| @@ -554,8 +554,6 @@ void blk_mq_sched_free_requests(struct request_queue *q) |
| struct blk_mq_hw_ctx *hctx; |
| int i; |
| |
| - lockdep_assert_held(&q->sysfs_lock); |
| - |
| queue_for_each_hw_ctx(q, hctx, i) { |
| if (hctx->sched_tags) |
| blk_mq_free_rqs(q->tag_set, hctx->sched_tags, i); |
| diff --git a/block/blk.h b/block/blk.h |
| index 7019757a5ce1..5a470b97204f 100644 |
| --- a/block/blk.h |
| +++ b/block/blk.h |
| @@ -191,6 +191,8 @@ void elv_unregister_queue(struct request_queue *q); |
| static inline void elevator_exit(struct request_queue *q, |
| struct elevator_queue *e) |
| { |
| + lockdep_assert_held(&q->sysfs_lock); |
| + |
| blk_mq_sched_free_requests(q); |
| __elevator_exit(q, e); |
| } |
| -- |
| 2.7.4 |
| |