Commit 15e44355 authored by Zheng Qixing's avatar Zheng Qixing
Browse files

sbitmap: fix kabi broken in struct scsi_device

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IB4C27



--------------------------------

Commit cade2a2a1673 ("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.

Fixes: cade2a2a1673 ("scsi: core: Replace sdev->device_busy with sbitmap")
Signed-off-by: default avatarZheng Qixing <zhengqixing@huawei.com>
parent 2e6a3773
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+4 −4
Original line number Diff line number Diff line
@@ -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)
+34 −12
Original line number Diff line number Diff line
@@ -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;

	/*
+1 −1
Original line number Diff line number Diff line
@@ -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,
+6 −3
Original line number Diff line number Diff line
@@ -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) \