Skip to content

Commit edb854a

Browse files
Ming Leimartinkpetersen
authored andcommitted
scsi: core: Reallocate device's budget map on queue depth change
We currently use ->cmd_per_lun as initial queue depth for setting up the budget_map. Martin Wilck reported that it is common for the queue_depth to be subsequently updated in slave_configure() based on detected hardware characteristics. As a result, for some drivers, the static host template settings for cmd_per_lun and can_queue won't actually get used in practice. And if the default values are used to allocate the budget_map, memory may be consumed unnecessarily. Fix the issue by reallocating the budget_map after ->slave_configure() returns. At that time the device queue_depth should accurately reflect what the hardware needs. Link: https://lore.kernel.org/r/20220127153733.409132-1-ming.lei@redhat.com Cc: Bart Van Assche <bvanassche@acm.org> Reported-by: Martin Wilck <martin.wilck@suse.com> Suggested-by: Martin Wilck <martin.wilck@suse.com> Tested-by: Martin Wilck <mwilck@suse.com> Reviewed-by: Martin Wilck <mwilck@suse.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 936bd03 commit edb854a

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

drivers/scsi/scsi_scan.c

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,48 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,
214214
SCSI_TIMEOUT, 3, NULL);
215215
}
216216

217+
static int scsi_realloc_sdev_budget_map(struct scsi_device *sdev,
218+
unsigned int depth)
219+
{
220+
int new_shift = sbitmap_calculate_shift(depth);
221+
bool need_alloc = !sdev->budget_map.map;
222+
bool need_free = false;
223+
int ret;
224+
struct sbitmap sb_backup;
225+
226+
/*
227+
* realloc if new shift is calculated, which is caused by setting
228+
* up one new default queue depth after calling ->slave_configure
229+
*/
230+
if (!need_alloc && new_shift != sdev->budget_map.shift)
231+
need_alloc = need_free = true;
232+
233+
if (!need_alloc)
234+
return 0;
235+
236+
/*
237+
* Request queue has to be frozen for reallocating budget map,
238+
* and here disk isn't added yet, so freezing is pretty fast
239+
*/
240+
if (need_free) {
241+
blk_mq_freeze_queue(sdev->request_queue);
242+
sb_backup = sdev->budget_map;
243+
}
244+
ret = sbitmap_init_node(&sdev->budget_map,
245+
scsi_device_max_queue_depth(sdev),
246+
new_shift, GFP_KERNEL,
247+
sdev->request_queue->node, false, true);
248+
if (need_free) {
249+
if (ret)
250+
sdev->budget_map = sb_backup;
251+
else
252+
sbitmap_free(&sb_backup);
253+
ret = 0;
254+
blk_mq_unfreeze_queue(sdev->request_queue);
255+
}
256+
return ret;
257+
}
258+
217259
/**
218260
* scsi_alloc_sdev - allocate and setup a scsi_Device
219261
* @starget: which target to allocate a &scsi_device for
@@ -306,11 +348,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
306348
* default device queue depth to figure out sbitmap shift
307349
* since we use this queue depth most of times.
308350
*/
309-
if (sbitmap_init_node(&sdev->budget_map,
310-
scsi_device_max_queue_depth(sdev),
311-
sbitmap_calculate_shift(depth),
312-
GFP_KERNEL, sdev->request_queue->node,
313-
false, true)) {
351+
if (scsi_realloc_sdev_budget_map(sdev, depth)) {
314352
put_device(&starget->dev);
315353
kfree(sdev);
316354
goto out;
@@ -1017,6 +1055,13 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
10171055
}
10181056
return SCSI_SCAN_NO_RESPONSE;
10191057
}
1058+
1059+
/*
1060+
* The queue_depth is often changed in ->slave_configure.
1061+
* Set up budget map again since memory consumption of
1062+
* the map depends on actual queue depth.
1063+
*/
1064+
scsi_realloc_sdev_budget_map(sdev, sdev->queue_depth);
10201065
}
10211066

10221067
if (sdev->scsi_level >= SCSI_3)

0 commit comments

Comments
 (0)