hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IB4C27
--------------------------------
Commit a7e1ffdd6f5a ("scsi: core: Replace sdev->device_busy with sbitmap") replace the atomic variable sdev->device_busy with an sbitmap for tracking the SCSI device queue depth. Fix the kabi broken in struct scsi_device.
Signed-off-by: Zheng Qixing zhengqixing@huawei.com --- drivers/scsi/scsi.c | 2 +- drivers/scsi/scsi_lib.c | 8 +++---- drivers/scsi/scsi_scan.c | 46 ++++++++++++++++++++++++++++---------- drivers/scsi/scsi_sysfs.c | 2 +- include/scsi/scsi_device.h | 9 +++++--- 5 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index fd6f31a56a97..77cb26bb4df4 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -242,7 +242,7 @@ int scsi_change_queue_depth(struct scsi_device *sdev, int depth) if (sdev->request_queue) blk_set_queue_depth(sdev->request_queue, depth);
- sbitmap_resize(&sdev->budget_map, sdev->queue_depth); + sbitmap_resize(sdev->budget_map, sdev->queue_depth);
return sdev->queue_depth; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e368f2724c2e..a8c115643af3 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -333,7 +333,7 @@ void scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd) if (starget->can_queue > 0) atomic_dec(&starget->target_busy);
- sbitmap_put(&sdev->budget_map, cmd->budget_token); + sbitmap_put(sdev->budget_map, cmd->budget_token); cmd->budget_token = -1; }
@@ -1266,7 +1266,7 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, { int token;
- token = sbitmap_get(&sdev->budget_map); + token = sbitmap_get(sdev->budget_map); if (atomic_read(&sdev->device_blocked)) { if (token < 0) goto out; @@ -1286,7 +1286,7 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, return token; out_dec: if (token >= 0) - sbitmap_put(&sdev->budget_map, token); + sbitmap_put(sdev->budget_map, token); out: return -1; } @@ -1615,7 +1615,7 @@ static void scsi_mq_put_budget(struct request_queue *q, int budget_token) { struct scsi_device *sdev = q->queuedata;
- sbitmap_put(&sdev->budget_map, budget_token); + sbitmap_put(sdev->budget_map, budget_token); }
static int scsi_mq_get_budget(struct request_queue *q) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 89fcb3ab8b9b..1be912544932 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -198,6 +198,38 @@ static void scsi_unlock_floptical(struct scsi_device *sdev, SCSI_TIMEOUT, 3, NULL); }
+static int scsi_alloc_and_init_budget_map(struct scsi_device *sdev, unsigned int depth) +{ + sdev->budget_map = kzalloc(sizeof(*sdev->budget_map), GFP_KERNEL); + if (!sdev->budget_map) + return -ENOMEM; + + /* + * Use .can_queue as budget map's depth because we have to + * support adjusting queue depth from sysfs. Meantime use + * default device queue depth to figure out sbitmap shift + * since we use this queue depth most of times. + */ + if (sbitmap_init_node(sdev->budget_map, + scsi_device_max_queue_depth(sdev), + sbitmap_calculate_shift(depth), + GFP_KERNEL, sdev->request_queue->node, + false, true)) { + kfree(sdev->budget_map); + sdev->budget_map = NULL; + return -ENOMEM; + } + + return 0; +} + +void scsi_free_budget_map(struct scsi_device *sdev) +{ + sbitmap_free(sdev->budget_map); + kfree(sdev->budget_map); + sdev->budget_map = NULL; +} + /** * scsi_alloc_sdev - allocate and setup a scsi_Device * @starget: which target to allocate a &scsi_device for @@ -279,17 +311,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
depth = sdev->host->cmd_per_lun ?: 1;
- /* - * Use .can_queue as budget map's depth because we have to - * support adjusting queue depth from sysfs. Meantime use - * default device queue depth to figure out sbitmap shift - * since we use this queue depth most of times. - */ - if (sbitmap_init_node(&sdev->budget_map, - scsi_device_max_queue_depth(sdev), - sbitmap_calculate_shift(depth), - GFP_KERNEL, sdev->request_queue->node, - false, true)) { + if (scsi_alloc_and_init_budget_map(sdev, depth)) { put_device(&starget->dev); kfree(sdev); goto out; @@ -998,7 +1020,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, scsi_attach_vpd(sdev);
sdev->max_queue_depth = sdev->queue_depth; - WARN_ON_ONCE(sdev->max_queue_depth > sdev->budget_map.depth); + WARN_ON_ONCE(sdev->max_queue_depth > sdev->budget_map->depth); sdev->sdev_bflags = *bflags;
/* diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 80ad038c6f7f..842d7ca99ddb 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -480,7 +480,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) /* NULL queue means the device can't be used */ sdev->request_queue = NULL;
- sbitmap_free(&sdev->budget_map); + scsi_free_budget_map(sdev);
mutex_lock(&sdev->inquiry_mutex); vpd_pg0 = rcu_replace_pointer(sdev->vpd_pg0, vpd_pg0, diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 929311440781..30cdc73175b5 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -108,7 +108,7 @@ struct scsi_device { struct list_head siblings; /* list of all devices on this host */ struct list_head same_target_siblings; /* just the devices sharing same target id */
- struct sbitmap budget_map; + KABI_DEPRECATE(atomic_t, device_busy) atomic_t device_blocked; /* Device returned QUEUE_FULL. */
atomic_t restarts; @@ -241,7 +241,7 @@ struct scsi_device { enum scsi_device_state sdev_state; struct task_struct *quiesced_by;
- KABI_RESERVE(1) + KABI_USE(1, struct sbitmap *budget_map) KABI_RESERVE(2) KABI_RESERVE(3) KABI_RESERVE(4) @@ -460,6 +460,9 @@ extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, unsigned char *sense, struct scsi_sense_hdr *sshdr, int timeout, int retries, u64 flags, req_flags_t rq_flags, int *resid); + +extern void scsi_free_budget_map(struct scsi_device *sdev); + /* Make sure any sense buffer is the correct size. */ #define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \ sshdr, timeout, retries, flags, rq_flags, resid) \ @@ -609,7 +612,7 @@ static inline int scsi_device_supports_vpd(struct scsi_device *sdev)
static inline int scsi_device_busy(struct scsi_device *sdev) { - return sbitmap_weight(&sdev->budget_map); + return sbitmap_weight(sdev->budget_map); }
#define MODULE_ALIAS_SCSI_DEVICE(type) \