| From foo@baz Mon Apr 9 17:09:24 CEST 2018 |
| From: Ming Lei <ming.lei@redhat.com> |
| Date: Sat, 6 Jan 2018 16:27:40 +0800 |
| Subject: blk-mq: fix race between updating nr_hw_queues and switching io sched |
| |
| From: Ming Lei <ming.lei@redhat.com> |
| |
| |
| [ Upstream commit fb350e0ad99359768e1e80b4784692031ec340e4 ] |
| |
| In both elevator_switch_mq() and blk_mq_update_nr_hw_queues(), sched tags |
| can be allocated, and q->nr_hw_queue is used, and race is inevitable, for |
| example: blk_mq_init_sched() may trigger use-after-free on hctx, which is |
| freed in blk_mq_realloc_hw_ctxs() when nr_hw_queues is decreased. |
| |
| This patch fixes the race be holding q->sysfs_lock. |
| |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Reported-by: Yi Zhang <yi.zhang@redhat.com> |
| Tested-by: Yi Zhang <yi.zhang@redhat.com> |
| Signed-off-by: Ming Lei <ming.lei@redhat.com> |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| block/blk-mq.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/block/blk-mq.c |
| +++ b/block/blk-mq.c |
| @@ -1907,6 +1907,9 @@ static void blk_mq_realloc_hw_ctxs(struc |
| struct blk_mq_hw_ctx **hctxs = q->queue_hw_ctx; |
| |
| blk_mq_sysfs_unregister(q); |
| + |
| + /* protect against switching io scheduler */ |
| + mutex_lock(&q->sysfs_lock); |
| for (i = 0; i < set->nr_hw_queues; i++) { |
| int node; |
| |
| @@ -1956,6 +1959,7 @@ static void blk_mq_realloc_hw_ctxs(struc |
| } |
| } |
| q->nr_hw_queues = i; |
| + mutex_unlock(&q->sysfs_lock); |
| blk_mq_sysfs_register(q); |
| } |
| |