| From f9e6b879caf196de7417a15a0dc882edd5d7321a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 16 Mar 2022 17:44:30 +0800 |
| Subject: scsi: core: Fix sbitmap depth in scsi_realloc_sdev_budget_map() |
| |
| From: John Garry <john.garry@huawei.com> |
| |
| [ Upstream commit eaba83b5b8506bbc9ee7ca2f10aeab3fff3719e7 ] |
| |
| In commit edb854a3680b ("scsi: core: Reallocate device's budget map on |
| queue depth change"), the sbitmap for the device budget map may be |
| reallocated after the slave device depth is configured. |
| |
| When the sbitmap is reallocated we use the result from |
| scsi_device_max_queue_depth() for the sbitmap size, but don't resize to |
| match the actual device queue depth. |
| |
| Fix by resizing the sbitmap after reallocating the budget sbitmap. We do |
| this instead of init'ing the sbitmap to the device queue depth as the user |
| may want to change the queue depth later via sysfs or other. |
| |
| Link: https://lore.kernel.org/r/1647423870-143867-1-git-send-email-john.garry@huawei.com |
| Fixes: edb854a3680b ("scsi: core: Reallocate device's budget map on queue depth change") |
| Tested-by: Damien Le Moal <damien.lemoal@opensource.wdc.com> |
| Reviewed-by: Ming Lei <ming.lei@redhat.com> |
| Reviewed-by: Bart Van Assche <bvanassche@acm.org> |
| Signed-off-by: John Garry <john.garry@huawei.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/scsi_scan.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c |
| index d0ce723299bf..6bc0f5f511e1 100644 |
| --- a/drivers/scsi/scsi_scan.c |
| +++ b/drivers/scsi/scsi_scan.c |
| @@ -223,6 +223,8 @@ static int scsi_realloc_sdev_budget_map(struct scsi_device *sdev, |
| int ret; |
| struct sbitmap sb_backup; |
| |
| + depth = min_t(unsigned int, depth, scsi_device_max_queue_depth(sdev)); |
| + |
| /* |
| * realloc if new shift is calculated, which is caused by setting |
| * up one new default queue depth after calling ->slave_configure |
| @@ -245,6 +247,9 @@ static int scsi_realloc_sdev_budget_map(struct scsi_device *sdev, |
| scsi_device_max_queue_depth(sdev), |
| new_shift, GFP_KERNEL, |
| sdev->request_queue->node, false, true); |
| + if (!ret) |
| + sbitmap_resize(&sdev->budget_map, depth); |
| + |
| if (need_free) { |
| if (ret) |
| sdev->budget_map = sb_backup; |
| -- |
| 2.35.1 |
| |