Linux SCSI subsystem development
 help / color / mirror / Atom feed
* [PATCH v5 0/8] scsi_debug: Enable lock context analysis
@ 2026-10-08 22:42 Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 1/8] scsi: scsi_debug: Fix a locking bug in resp_write_same() Bart Van Assche
                   ` (7 more replies)
  0 siblings, 8 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Hi Martin,

This patch series enables compiler-based lock context analysis for the
scsi_debug driver. Conditional locking is eliminated across command response
and error injection functions so that static analysis can verify lock
acquisitions and releases. Internal locking helper functions are annotated
with __acquires(),__releases(), __acquires_shared() and __releases_shared()
attributes. An error-path lock leak in resp_write_same() is fixed. Finally,
lock context analysis is enabled in drivers/scsi/Makefile.

Please consider this patch series for the next merge window.

Thanks,

Bart.

Changes compared to v4:
- Add a Reviewed-by tag from Christoph Hellwig to patch 6/8.
- Drop __context_unsafe() from sdeb_read_lock(), sdeb_read_unlock(),
  sdeb_write_lock(), and sdeb_write_unlock() in patch 7/8. Preserve the
  original if (sdebug_no_rwlock) conditional structure and annotate with
  __acquire_shared(), __release_shared(), __acquire(), and __release().
- Drop __context_unsafe() from sdeb_data_lock(), sdeb_data_unlock(),
  sdeb_data_sector_lock(), and sdeb_data_sector_unlock() in patch 7/8,
  and add explicit context capability transitions on the read paths.
- Retain __context_unsafe() exclusively for
  sdeb_meta_{read,write}_{,un}lock() to prevent undefined pointer
  arithmetic when sip is NULL under fake_rw.
- Update the commit description of patch 7/8 to reflect these changes.

Changes compared to v3:
- Add a new patch to split resp_atomic_write() and eliminate conditional
  locking in atomic write handling.
- Pass the LBP state boolean down into __resp_write_same(),
  __corrupt_lbas(), and __resp_write_dt0() to avoid repeated calls to
  scsi_debug_lbp().
- Drop unused function arguments from __resp_read_dt0_dix() and
  __resp_write_dt0_dix().
- Correct the return value descriptions in the header comments of
  __resp_read_dt0_dix() and __resp_write_dt0_dix().

Changes compared to v2:
- Move DIX/DIF verification into a helper function (__resp_read_dt0_dix())
  to reduce indentation.
- Remove unnecessary "else" branches after "return".
- Set the SCSI status code only if do_device_access() fails instead of
  unconditionally setting it to DID_ERROR << 16 beforehand.

Changes compared to v1:
- Fix an issue where the error code was clobbered in resp_write_same() and
  __resp_write_same() when fetch_to_dev_buffer() fails (John Garry and
  sashiko-bot).
- Fix return value handling in resp_read_dt0() and resp_write_dt0():
  previously a positive byte count returned by do_device_access() was
  incorrectly treated as a SCSI status code and returned to the caller.
  Now, pass the SCSI status via an output pointer and only trigger an error
  return on negative return values (sashiko-bot).
- Improve lock context annotations:
  * Annotate existing rwlock_t members (&sip->macc_data_lck,
    &sip->macc_sector_lck, &sip->macc_meta_lck) directly with __acquires /
    __releases instead of defining and embedding dummy context lock structs
    in struct sdeb_store_info.
  * Drop the unwarranted __context_unsafe() annotation from
    sdeb_data_read_lock().
  * Update the commit descriptions to match the code changes.

Bart Van Assche (8):
  scsi: scsi_debug: Fix a locking bug in resp_write_same()
  scsi: scsi_debug: Split resp_write_same()
  scsi: scsi_debug: Split corrupt_lbas()
  scsi: scsi_debug: Split resp_read_dt0()
  scsi: scsi_debug: Split resp_write_dt0()
  scsi: scsi_debug: Split resp_atomic_write()
  scsi: scsi_debug: Improve lock context annotations
  scsi: core: Enable lock context analysis for the scsi_debug driver

 drivers/scsi/Makefile     |   1 +
 drivers/scsi/scsi_debug.c | 426 +++++++++++++++++++++++---------------
 2 files changed, 264 insertions(+), 163 deletions(-)


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5 1/8] scsi: scsi_debug: Fix a locking bug in resp_write_same()
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same() Bart Van Assche
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

If fetch_to_dev_buffer() fails in resp_write_same(), the function jumps
to 'out' without releasing the data write lock acquired earlier via
sdeb_data_write_lock(). Jump to 'unlock' instead so that
sdeb_data_write_unlock() is called on the error path. This bug has been
discovered by building the scsi_debug driver with Clang and modified
lock context annotations. The modified lock context annotations are
available in patch "scsi: scsi_debug: Improve lock context annotations".

Fixes: 84f3a3c01d70 ("scsi: scsi_debug: Atomic write support")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.garry@linux.dev>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index e679df1993aa..44b4587b53c6 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -5455,7 +5455,7 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
 
 	if (-1 == ret) {
 		ret = DID_ERROR << 16;
-		goto out;
+		goto unlock;
 	} else if (sdebug_verbose && !ndob && (ret < lb_size))
 		sdev_printk(KERN_INFO, scp->device,
 			    "%s: %s: lb size=%u, IO sent=%d bytes\n",
@@ -5472,8 +5472,9 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
 	/* If ZBC zone then bump its write pointer */
 	if (sdebug_dev_is_zoned(devip))
 		zbc_inc_wp(devip, lba, num);
-	sdeb_data_write_unlock(sip);
 	ret = 0;
+unlock:
+	sdeb_data_write_unlock(sip);
 out:
 	if (meta_data_locked)
 		sdeb_meta_write_unlock(sip);

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same()
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 1/8] scsi: scsi_debug: Fix a locking bug in resp_write_same() Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-08 22:52   ` sashiko-bot
  2026-10-08 22:42 ` [PATCH v5 3/8] scsi: scsi_debug: Split corrupt_lbas() Bart Van Assche
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Since the Clang thread-safety analyzer does not support conditional
locking, split the function resp_write_same() such that all locking
statements end up in the same branch of an if-statement.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.garry@linux.dev>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 38 +++++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 44b4587b53c6..cadd94e17109 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -5412,8 +5412,8 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 	return ret;
 }
 
-static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
-			   u32 ei_lba, bool unmap, bool ndob)
+static int __resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
+			     u32 ei_lba, bool unmap, bool ndob, bool lbp)
 {
 	struct scsi_device *sdp = scp->device;
 	struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata;
@@ -5425,21 +5425,14 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
 						scp->device->hostdata, true);
 	u8 *fs1p;
 	u8 *fsp;
-	bool meta_data_locked = false;
-	bool lbp = scsi_debug_lbp();
-
-	if (sdebug_dev_is_zoned(devip) || lbp) {
-		sdeb_meta_write_lock(sip);
-		meta_data_locked = true;
-	}
 
 	ret = check_device_access_params(scp, lba, num, true);
 	if (ret)
-		goto out;
+		return ret;
 
 	if (unmap && lbp) {
 		unmap_region(sip, lba, num);
-		goto out;
+		return ret;
 	}
 	lbaa = lba;
 	block = do_div(lbaa, sdebug_store_sectors);
@@ -5475,9 +5468,28 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
 	ret = 0;
 unlock:
 	sdeb_data_write_unlock(sip);
-out:
-	if (meta_data_locked)
+	return ret;
+}
+
+static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, u32 ei_lba,
+			   bool unmap, bool ndob)
+{
+	struct scsi_device *sdp = scp->device;
+	struct sdebug_dev_info *devip = sdp->hostdata;
+	struct sdeb_store_info *sip = devip2sip(devip, true);
+	const bool lbp = scsi_debug_lbp();
+	int ret;
+
+	if (sdebug_dev_is_zoned(devip) || lbp) {
+		sdeb_meta_write_lock(sip);
+		ret = __resp_write_same(scp, lba, num, ei_lba, unmap, ndob,
+					lbp);
 		sdeb_meta_write_unlock(sip);
+	} else {
+		ret = __resp_write_same(scp, lba, num, ei_lba, unmap, ndob,
+					lbp);
+	}
+
 	return ret;
 }
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 3/8] scsi: scsi_debug: Split corrupt_lbas()
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 1/8] scsi: scsi_debug: Fix a locking bug in resp_write_same() Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same() Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0() Bart Van Assche
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Move the inner logic of corrupt_lbas() into a new helper function
__corrupt_lbas() and call it from separate locked and unlocked branches
in corrupt_lbas(). This patch prepares for enabling context analysis.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.garry@linux.dev>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 42 +++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index cadd94e17109..eafcadc6ef07 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -4984,37 +4984,25 @@ static int resp_write_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	return 0;
 }
 
-static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num,
-		u32 nr_bit_errors, s32 reftag_adjust)
+static int __corrupt_lbas(struct sdeb_store_info *sip, u64 lba, u32 num,
+			  u32 nr_bit_errors, s32 reftag_adjust, bool lbp)
 {
-	struct sdeb_store_info *sip = devip2sip(devip, false);
-	bool meta_data_locked = false;
-	bool lbp = scsi_debug_lbp();
 	u32 block, num_mapped, b, i;
-	int error = 0;
-
-	if (sdebug_dev_is_zoned(devip) || sdebug_dix || lbp) {
-		sdeb_meta_write_lock(sip);
-		meta_data_locked = true;
-	}
 
 	if (!sip) {
 		pr_err("can't corrupt with fake_rw\n");
-		error = -EINVAL;
-		goto out_unlock;
+		return -EINVAL;
 	}
 
 	if (num > sdebug_capacity || lba > sdebug_capacity - num) {
 		pr_err("logical blocks out of bounds: %llu:%u", lba, num);
-		error = -EINVAL;
-		goto out_unlock;
+		return -EINVAL;
 	}
 
 	if (lbp && (!map_state(sip, lba, &num_mapped) || num > num_mapped)) {
 		pr_err("can't modify unmapped logical blocks: %llu:%u",
 			lba, num);
-		error = -EINVAL;
-		goto out_unlock;
+		return -EINVAL;
 	}
 
 	/*
@@ -5052,9 +5040,25 @@ static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num,
 	}
 	sdeb_data_unlock(sip, false);
 
-out_unlock:
-	if (meta_data_locked)
+	return 0;
+}
+
+static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num,
+			u32 nr_bit_errors, s32 reftag_adjust)
+{
+	struct sdeb_store_info *sip = devip2sip(devip, false);
+	const bool lbp = scsi_debug_lbp();
+	int error = 0;
+
+	if (sdebug_dev_is_zoned(devip) || sdebug_dix || lbp) {
+		sdeb_meta_write_lock(sip);
+		error = __corrupt_lbas(sip, lba, num, nr_bit_errors,
+				       reftag_adjust, lbp);
 		sdeb_meta_write_unlock(sip);
+	} else {
+		error = __corrupt_lbas(sip, lba, num, nr_bit_errors,
+				       reftag_adjust, lbp);
+	}
 	return error;
 }
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0()
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
                   ` (2 preceding siblings ...)
  2026-10-08 22:42 ` [PATCH v5 3/8] scsi: scsi_debug: Split corrupt_lbas() Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-12 12:23   ` Christoph Hellwig
  2026-10-12 17:18   ` John Garry
  2026-10-08 22:42 ` [PATCH v5 5/8] scsi: scsi_debug: Split resp_write_dt0() Bart Van Assche
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Split this function to remove conditional locking. This patch prepares
for enabling context analysis.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 110 ++++++++++++++++++++++++--------------
 1 file changed, 71 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index eafcadc6ef07..c66f8556896d 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -4608,6 +4608,70 @@ static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	return 0;
 }
 
+/*
+ * Returns 0 upon success or -1 with *scsi_status set to a SCSI status code upon
+ * failure.
+ */
+static int __resp_read_dt0_dix(struct scsi_cmnd *scp, u64 lba, u32 num,
+			       u32 ei_lba, int *scsi_status)
+{
+	const u8 *const cmd = scp->cmnd;
+
+	switch (prot_verify_read(scp, lba, num, ei_lba)) {
+	case 1: /* Guard tag error */
+		if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
+			mk_sense_buffer(scp, ABORTED_COMMAND,
+					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
+			*scsi_status = check_condition_result;
+			return -1;
+		}
+		if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) {
+			mk_sense_buffer(scp, ILLEGAL_REQUEST,
+					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
+			*scsi_status = illegal_condition_result;
+			return -1;
+		}
+		break;
+	case 3: /* Reference tag error */
+		if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
+			mk_sense_buffer(scp, ABORTED_COMMAND,
+				LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
+			*scsi_status = check_condition_result;
+			return -1;
+		}
+		if (scp->prot_flags & SCSI_PROT_REF_CHECK) {
+			mk_sense_buffer(scp, ILLEGAL_REQUEST,
+				LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
+			*scsi_status = illegal_condition_result;
+			return -1;
+		}
+		break;
+	}
+	return 0;
+}
+
+/*
+ * Returns the number of bytes transferred, or -1 with *scsi_status set to a
+ * SCSI status code on failure.
+ */
+static int __resp_read_dt0(struct scsi_cmnd *scp, struct sdeb_store_info *sip,
+			   u64 lba, u32 num, u32 ei_lba, int *scsi_status)
+{
+	int ret;
+
+	/* DIX + T10 DIF */
+	if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
+		ret = __resp_read_dt0_dix(scp, lba, num, ei_lba, scsi_status);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = do_device_access(sip, scp, 0, lba, num, 0, false, false);
+	if (ret < 0)
+		*scsi_status = DID_ERROR << 16;
+	return ret;
+}
+
 static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 {
 	bool check_prot;
@@ -4617,7 +4681,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	u64 lba;
 	struct sdeb_store_info *sip = devip2sip(devip, true);
 	u8 *cmd = scp->cmnd;
-	bool meta_data_locked = false;
+	int scsi_status;
 
 	switch (cmd[0]) {
 	case READ_16:
@@ -4699,48 +4763,16 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	}
 
 	if (sdebug_dev_is_zoned(devip) ||
-	    (sdebug_dix && scsi_prot_sg_count(scp)))  {
+	    (sdebug_dix && scsi_prot_sg_count(scp))) {
 		sdeb_meta_read_lock(sip);
-		meta_data_locked = true;
-	}
-
-	/* DIX + T10 DIF */
-	if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
-		switch (prot_verify_read(scp, lba, num, ei_lba)) {
-		case 1: /* Guard tag error */
-			if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
-				sdeb_meta_read_unlock(sip);
-				mk_sense_buffer(scp, ABORTED_COMMAND,
-					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
-				return check_condition_result;
-			} else if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) {
-				sdeb_meta_read_unlock(sip);
-				mk_sense_buffer(scp, ILLEGAL_REQUEST,
-					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
-				return illegal_condition_result;
-			}
-			break;
-		case 3: /* Reference tag error */
-			if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */
-				sdeb_meta_read_unlock(sip);
-				mk_sense_buffer(scp, ABORTED_COMMAND,
-				      LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
-				return check_condition_result;
-			} else if (scp->prot_flags & SCSI_PROT_REF_CHECK) {
-				sdeb_meta_read_unlock(sip);
-				mk_sense_buffer(scp, ILLEGAL_REQUEST,
-				      LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
-				return illegal_condition_result;
-			}
-			break;
-		}
+		ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status);
+		sdeb_meta_read_unlock(sip);
+	} else {
+		ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status);
 	}
 
-	ret = do_device_access(sip, scp, 0, lba, num, 0, false, false);
-	if (meta_data_locked)
-		sdeb_meta_read_unlock(sip);
 	if (unlikely(ret == -1))
-		return DID_ERROR << 16;
+		return scsi_status;
 
 	scsi_set_resid(scp, scsi_bufflen(scp) - ret);
 

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 5/8] scsi: scsi_debug: Split resp_write_dt0()
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
                   ` (3 preceding siblings ...)
  2026-10-08 22:42 ` [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0() Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 6/8] scsi: scsi_debug: Split resp_atomic_write() Bart Van Assche
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Prepare for enabling lock context analysis by eliminating conditional
locking.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 139 ++++++++++++++++++++++++--------------
 1 file changed, 87 insertions(+), 52 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index c66f8556896d..685949aedf9a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -5094,6 +5094,85 @@ static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num,
 	return error;
 }
 
+/*
+ * Returns 0 upon success or -1 with *scsi_status set to a SCSI status code upon
+ * failure.
+ */
+static int __resp_write_dt0_dix(struct scsi_cmnd *scp,
+				u64 lba, u32 num,
+				u32 ei_lba, int *scsi_status)
+{
+	switch (prot_verify_write(scp, lba, num, ei_lba)) {
+	case 1: /* Guard tag error */
+		if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) {
+			mk_sense_buffer(scp, ILLEGAL_REQUEST,
+					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
+			*scsi_status = illegal_condition_result;
+			return -1;
+		}
+		if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */
+			mk_sense_buffer(scp, ABORTED_COMMAND,
+					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
+			*scsi_status = check_condition_result;
+			return -1;
+		}
+		break;
+	case 3: /* Reference tag error */
+		if (scp->prot_flags & SCSI_PROT_REF_CHECK) {
+			mk_sense_buffer(scp, ILLEGAL_REQUEST,
+				LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
+			*scsi_status = illegal_condition_result;
+			return -1;
+		}
+		if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */
+			mk_sense_buffer(scp, ABORTED_COMMAND,
+				LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
+			*scsi_status = check_condition_result;
+			return -1;
+		}
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * Returns the number of bytes transferred, or -1 with *scsi_status set to a
+ * SCSI status code on failure.
+ */
+static int __resp_write_dt0(struct scsi_cmnd *scp,
+			    struct sdebug_dev_info *devip,
+			    struct sdeb_store_info *sip, u64 lba, u32 num,
+			    u32 ei_lba, u8 group, bool lbp, int *scsi_status)
+{
+	int ret;
+
+	*scsi_status = check_device_access_params(scp, lba, num, true);
+	if (*scsi_status)
+		return -1;
+
+	/* DIX + T10 DIF */
+	if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
+		ret = __resp_write_dt0_dix(scp, lba, num, ei_lba,
+					   scsi_status);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = do_device_access(sip, scp, 0, lba, num, group, true, false);
+	if (ret < 0)
+		*scsi_status = DID_ERROR << 16;
+
+	if (unlikely(lbp))
+		map_region(sip, lba, num);
+
+	/* If ZBC zone then bump its write pointer */
+	if (sdebug_dev_is_zoned(devip) && ret > 0)
+		zbc_inc_wp(devip, lba, ret >> ilog2(sdebug_sector_size));
+
+	return ret;
+}
+
 static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 {
 	bool check_prot;
@@ -5104,7 +5183,7 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	u64 lba;
 	struct sdeb_store_info *sip = devip2sip(devip, true);
 	u8 *cmd = scp->cmnd;
-	bool meta_data_locked = false;
+	int scsi_status = DID_ERROR << 16;
 	bool lbp = scsi_debug_lbp();
 
 	if (unlikely(sdebug_opts & SDEBUG_OPT_UNALIGNED_WRITE &&
@@ -5174,60 +5253,16 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
 	if (sdebug_dev_is_zoned(devip) ||
 	    (sdebug_dix && scsi_prot_sg_count(scp)) || lbp) {
 		sdeb_meta_write_lock(sip);
-		meta_data_locked = true;
-	}
-
-	ret = check_device_access_params(scp, lba, num, true);
-	if (ret) {
-		if (meta_data_locked)
-			sdeb_meta_write_unlock(sip);
-		return ret;
-	}
-
-	/* DIX + T10 DIF */
-	if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) {
-		switch (prot_verify_write(scp, lba, num, ei_lba)) {
-		case 1: /* Guard tag error */
-			if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) {
-				sdeb_meta_write_unlock(sip);
-				mk_sense_buffer(scp, ILLEGAL_REQUEST,
-					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
-				return illegal_condition_result;
-			} else if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */
-				sdeb_meta_write_unlock(sip);
-				mk_sense_buffer(scp, ABORTED_COMMAND,
-					LOGICAL_BLOCK_GUARD_CHECK_FAILED);
-				return check_condition_result;
-			}
-			break;
-		case 3: /* Reference tag error */
-			if (scp->prot_flags & SCSI_PROT_REF_CHECK) {
-				sdeb_meta_write_unlock(sip);
-				mk_sense_buffer(scp, ILLEGAL_REQUEST,
-					LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
-				return illegal_condition_result;
-			} else if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */
-				sdeb_meta_write_unlock(sip);
-				mk_sense_buffer(scp, ABORTED_COMMAND,
-					LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED);
-				return check_condition_result;
-			}
-			break;
-		}
-	}
-
-	ret = do_device_access(sip, scp, 0, lba, num, group, true, false);
-	if (unlikely(lbp))
-		map_region(sip, lba, num);
-
-	/* If ZBC zone then bump its write pointer over the data written */
-	if (sdebug_dev_is_zoned(devip) && ret > 0)
-		zbc_inc_wp(devip, lba, ret >> ilog2(sdebug_sector_size));
-	if (meta_data_locked)
+		ret = __resp_write_dt0(scp, devip, sip, lba, num, ei_lba, group,
+				       lbp, &scsi_status);
 		sdeb_meta_write_unlock(sip);
+	} else {
+		ret = __resp_write_dt0(scp, devip, sip, lba, num, ei_lba, group,
+				       lbp, &scsi_status);
+	}
 
 	if (unlikely(-1 == ret))
-		return DID_ERROR << 16;
+		return scsi_status;
 	else if (unlikely(sdebug_verbose &&
 			  (ret < (num * sdebug_sector_size))))
 		sdev_printk(KERN_INFO, scp->device,

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 6/8] scsi: scsi_debug: Split resp_atomic_write()
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
                   ` (4 preceding siblings ...)
  2026-10-08 22:42 ` [PATCH v5 5/8] scsi: scsi_debug: Split resp_write_dt0() Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations Bart Van Assche
  2026-10-08 22:42 ` [PATCH v5 8/8] scsi: core: Enable lock context analysis for the scsi_debug driver Bart Van Assche
  7 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Prepare for enabling lock context analysis by eliminating conditional
locking.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 685949aedf9a..244250ba460b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -6352,13 +6352,13 @@ static int resp_atomic_write(struct scsi_cmnd *scp,
 	if (scsi_bufflen(scp) < len * sdebug_sector_size)
 		return DID_ERROR << 16;
 
-	if (lbp)
-		sdeb_meta_write_lock(sip);
-
-	ret = do_device_access(sip, scp, 0, lba, len, 0, true, true);
 	if (lbp) {
+		sdeb_meta_write_lock(sip);
+		ret = do_device_access(sip, scp, 0, lba, len, 0, true, true);
 		map_region(sip, lba, len);
 		sdeb_meta_write_unlock(sip);
+	} else {
+		ret = do_device_access(sip, scp, 0, lba, len, 0, true, true);
 	}
 
 	if (unlikely(ret == -1))

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
                   ` (5 preceding siblings ...)
  2026-10-08 22:42 ` [PATCH v5 6/8] scsi: scsi_debug: Split resp_atomic_write() Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  2026-10-12 12:24   ` Christoph Hellwig
  2026-10-08 22:42 ` [PATCH v5 8/8] scsi: core: Enable lock context analysis for the scsi_debug driver Bart Van Assche
  7 siblings, 1 reply; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Prepare the scsi_debug driver for enabling compiler-based lock context
analysis:
- Annotate the lock and unlock helper functions with __acquires,
  __releases, __acquires_shared, and __releases_shared.
- Add __acquire() and __release() calls in the paths that do not match
  the __acquires() / __releases() annotations.
- Annotate sdeb_meta_{read,write}_{,un}lock() with __context_unsafe()
  because adding __acquire() and __release() calls in these functions is
  not possible without triggering undefined behavior (taking the address
  of a member of a structure with a NULL pointer as base address).

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_debug.c | 84 +++++++++++++++++++++++----------------
 1 file changed, 50 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 244250ba460b..1ca3a2dc7358 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -4052,24 +4052,27 @@ static inline struct sdeb_store_info *devip2sip(struct sdebug_dev_info *devip,
 
 static inline void
 sdeb_read_lock(rwlock_t *lock)
+	__acquires_shared(lock)
 {
 	if (sdebug_no_rwlock)
-		__acquire(lock);
+		__acquire_shared(lock);
 	else
 		read_lock(lock);
 }
 
 static inline void
 sdeb_read_unlock(rwlock_t *lock)
+	__releases_shared(lock)
 {
 	if (sdebug_no_rwlock)
-		__release(lock);
+		__release_shared(lock);
 	else
 		read_unlock(lock);
 }
 
 static inline void
 sdeb_write_lock(rwlock_t *lock)
+	__acquires(lock)
 {
 	if (sdebug_no_rwlock)
 		__acquire(lock);
@@ -4079,6 +4082,7 @@ sdeb_write_lock(rwlock_t *lock)
 
 static inline void
 sdeb_write_unlock(rwlock_t *lock)
+	__releases(lock)
 {
 	if (sdebug_no_rwlock)
 		__release(lock);
@@ -4088,6 +4092,7 @@ sdeb_write_unlock(rwlock_t *lock)
 
 static inline void
 sdeb_data_read_lock(struct sdeb_store_info *sip)
+	__acquires_shared(&sip->macc_data_lck)
 {
 	BUG_ON(!sip);
 
@@ -4096,6 +4101,7 @@ sdeb_data_read_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_read_unlock(struct sdeb_store_info *sip)
+	__releases_shared(&sip->macc_data_lck)
 {
 	BUG_ON(!sip);
 
@@ -4104,6 +4110,7 @@ sdeb_data_read_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_write_lock(struct sdeb_store_info *sip)
+	__acquires(&sip->macc_data_lck)
 {
 	BUG_ON(!sip);
 
@@ -4112,6 +4119,7 @@ sdeb_data_write_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_write_unlock(struct sdeb_store_info *sip)
+	__releases(&sip->macc_data_lck)
 {
 	BUG_ON(!sip);
 
@@ -4120,6 +4128,7 @@ sdeb_data_write_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_read_lock(struct sdeb_store_info *sip)
+	__acquires_shared(&sip->macc_sector_lck)
 {
 	BUG_ON(!sip);
 
@@ -4128,6 +4137,7 @@ sdeb_data_sector_read_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_read_unlock(struct sdeb_store_info *sip)
+	__releases_shared(&sip->macc_sector_lck)
 {
 	BUG_ON(!sip);
 
@@ -4136,6 +4146,7 @@ sdeb_data_sector_read_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_write_lock(struct sdeb_store_info *sip)
+	__acquires(&sip->macc_sector_lck)
 {
 	BUG_ON(!sip);
 
@@ -4144,6 +4155,7 @@ sdeb_data_sector_write_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_write_unlock(struct sdeb_store_info *sip)
+	__releases(&sip->macc_sector_lck)
 {
 	BUG_ON(!sip);
 
@@ -4165,50 +4177,63 @@ sdeb_data_sector_write_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_lock(struct sdeb_store_info *sip, bool atomic)
+	__acquires(&sip->macc_data_lck)
 {
-	if (atomic)
+	if (atomic) {
 		sdeb_data_write_lock(sip);
-	else
+	} else {
 		sdeb_data_read_lock(sip);
+		__release_shared(&sip->macc_data_lck);
+		__acquire(&sip->macc_data_lck);
+	}
 }
 
 static inline void
 sdeb_data_unlock(struct sdeb_store_info *sip, bool atomic)
+	__releases(&sip->macc_data_lck)
 {
-	if (atomic)
+	if (atomic) {
 		sdeb_data_write_unlock(sip);
-	else
+	} else {
+		__release(&sip->macc_data_lck);
+		__acquire_shared(&sip->macc_data_lck);
 		sdeb_data_read_unlock(sip);
+	}
 }
 
 /* Allow many reads but only 1x write per sector */
 static inline void
 sdeb_data_sector_lock(struct sdeb_store_info *sip, bool do_write)
+	__acquires(&sip->macc_sector_lck)
 {
-	if (do_write)
+	if (do_write) {
 		sdeb_data_sector_write_lock(sip);
-	else
+	} else {
 		sdeb_data_sector_read_lock(sip);
+		__release_shared(&sip->macc_sector_lck);
+		__acquire(&sip->macc_sector_lck);
+	}
 }
 
 static inline void
 sdeb_data_sector_unlock(struct sdeb_store_info *sip, bool do_write)
+	__releases(&sip->macc_sector_lck)
 {
-	if (do_write)
+	if (do_write) {
 		sdeb_data_sector_write_unlock(sip);
-	else
+	} else {
+		__release(&sip->macc_sector_lck);
+		__acquire_shared(&sip->macc_sector_lck);
 		sdeb_data_sector_read_unlock(sip);
+	}
 }
 
 static inline void
 sdeb_meta_read_lock(struct sdeb_store_info *sip)
+	__acquires_shared(&sip->macc_meta_lck)
+	__context_unsafe(/*conditional locking*/)
 {
-	if (sdebug_no_rwlock) {
-		if (sip)
-			__acquire(&sip->macc_meta_lck);
-		else
-			__acquire(&sdeb_fake_rw_lck);
-	} else {
+	if (!sdebug_no_rwlock) {
 		if (sip)
 			read_lock(&sip->macc_meta_lck);
 		else
@@ -4218,13 +4243,10 @@ sdeb_meta_read_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_meta_read_unlock(struct sdeb_store_info *sip)
+	__releases_shared(&sip->macc_meta_lck)
+	__context_unsafe(/*conditional locking*/)
 {
-	if (sdebug_no_rwlock) {
-		if (sip)
-			__release(&sip->macc_meta_lck);
-		else
-			__release(&sdeb_fake_rw_lck);
-	} else {
+	if (!sdebug_no_rwlock) {
 		if (sip)
 			read_unlock(&sip->macc_meta_lck);
 		else
@@ -4234,13 +4256,10 @@ sdeb_meta_read_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_meta_write_lock(struct sdeb_store_info *sip)
+	__acquires(&sip->macc_meta_lck)
+	__context_unsafe(/*conditional locking*/)
 {
-	if (sdebug_no_rwlock) {
-		if (sip)
-			__acquire(&sip->macc_meta_lck);
-		else
-			__acquire(&sdeb_fake_rw_lck);
-	} else {
+	if (!sdebug_no_rwlock) {
 		if (sip)
 			write_lock(&sip->macc_meta_lck);
 		else
@@ -4250,13 +4269,10 @@ sdeb_meta_write_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_meta_write_unlock(struct sdeb_store_info *sip)
+	__releases(&sip->macc_meta_lck)
+	__context_unsafe(/*conditional locking*/)
 {
-	if (sdebug_no_rwlock) {
-		if (sip)
-			__release(&sip->macc_meta_lck);
-		else
-			__release(&sdeb_fake_rw_lck);
-	} else {
+	if (!sdebug_no_rwlock) {
 		if (sip)
 			write_unlock(&sip->macc_meta_lck);
 		else

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v5 8/8] scsi: core: Enable lock context analysis for the scsi_debug driver
  2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
                   ` (6 preceding siblings ...)
  2026-10-08 22:42 ` [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations Bart Van Assche
@ 2026-10-08 22:42 ` Bart Van Assche
  7 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 22:42 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: linux-scsi, John Garry, Christoph Hellwig, Bart Van Assche

Enable lock context analysis now that all lock context analysis warnings
have been fixed.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.garry@linux.dev>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 533623382eca..32d816e942d6 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -18,6 +18,7 @@ CONTEXT_ANALYSIS_constants.o := y
 CONTEXT_ANALYSIS_hosts.o := y
 CONTEXT_ANALYSIS_scsi.o := y
 CONTEXT_ANALYSIS_scsi_common.o := y
+CONTEXT_ANALYSIS_scsi_debug.o := y
 CONTEXT_ANALYSIS_scsi_devinfo.o := y
 CONTEXT_ANALYSIS_scsi_dh.o := y
 CONTEXT_ANALYSIS_scsi_error.o := y

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same()
  2026-10-08 22:42 ` [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same() Bart Van Assche
@ 2026-10-08 22:52   ` sashiko-bot
  2026-10-08 23:27     ` Bart Van Assche
  0 siblings, 1 reply; 15+ messages in thread
From: sashiko-bot @ 2026-10-08 22:52 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] scsi_debug: data race on sip->storep between unmap_region() and do_device_access()
--

commit b0d6230062e0df8cfca0c47695724e008bd7da04
Author: Bart Van Assche <bvanassche@acm.org>

scsi: scsi_debug: Split resp_write_same()

This commit splits resp_write_same() into two functions to ensure all locking
statements end up in the same branch of an if-statement. This change is
intended to support the Clang thread-safety analyzer.

> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 44b4587b53c66..cadd94e17109a 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
[ ... ]
> -static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
> -			   u32 ei_lba, bool unmap, bool ndob)
> +static int __resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
> +			     u32 ei_lba, bool unmap, bool ndob, bool lbp)
>  {
>  	struct scsi_device *sdp = scp->device;
[ ... ]
>  	ret = check_device_access_params(scp, lba, num, true);
>  	if (ret)
> -		goto out;
> +		return ret;
>  
>  	if (unmap && lbp) {
>  		unmap_region(sip, lba, num);
> -		goto out;
> +		return ret;

[Severity: Medium]
Does this early return result in a data race on the sip->storep buffer?

When a SCSI UNMAP command (or WRITE SAME with the unmap bit set) and a READ
command execute concurrently on the same LBA range of an LBP-enabled device,
unmap_region() modifies the data store via memset().

By returning early here, __resp_write_same() only holds the
sdeb_meta_write_lock (acquired in the resp_write_same() caller) and bypasses
acquiring the sdeb_data_write_lock.

Concurrently, read operations like resp_read_dt0() -> do_device_access()
acquire only the sdeb_data_read_lock and skip the sdeb_meta_read_lock entirely
when running on non-zoned/non-DIX devices. 

Could this concurrent access to sip->storep result in torn or mixed reads?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1791499174.git.bvanassche@acm.org?part=2

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same()
  2026-10-08 22:52   ` sashiko-bot
@ 2026-10-08 23:27     ` Bart Van Assche
  0 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-08 23:27 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: linux-scsi


On 10/8/26 3:52 PM, sashiko-bot@kernel.org wrote:
> [Severity: Medium]
> Does this early return result in a data race on the sip->storep buffer?

I think this counts as a preexisting issue that has not been introduced
by this patch series.

Bart.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0()
  2026-10-08 22:42 ` [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0() Bart Van Assche
@ 2026-10-12 12:23   ` Christoph Hellwig
  2026-10-12 17:18   ` John Garry
  1 sibling, 0 replies; 15+ messages in thread
From: Christoph Hellwig @ 2026-10-12 12:23 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Martin K . Petersen, linux-scsi, John Garry, Christoph Hellwig

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations
  2026-10-08 22:42 ` [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations Bart Van Assche
@ 2026-10-12 12:24   ` Christoph Hellwig
  2026-10-12 15:31     ` Bart Van Assche
  0 siblings, 1 reply; 15+ messages in thread
From: Christoph Hellwig @ 2026-10-12 12:24 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Martin K . Petersen, linux-scsi, John Garry, Christoph Hellwig

On Thu, Oct 08, 2026 at 03:42:18PM -0700, Bart Van Assche wrote:
>  static inline void
>  sdeb_meta_read_lock(struct sdeb_store_info *sip)
> +	__acquires_shared(&sip->macc_meta_lck)
> +	__context_unsafe(/*conditional locking*/)
>  {
> -	if (sdebug_no_rwlock) {
> -		if (sip)
> -			__acquire(&sip->macc_meta_lck);
> -		else
> -			__acquire(&sdeb_fake_rw_lck);
> -	} else {
> +	if (!sdebug_no_rwlock) {

Why can't this be modelled using a __acquire variant?  And if you
add __context_unsafe(/*conditional locking*/) please add a detailed
comment why that is needed, otherwise no one is going to understand
this in the future.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations
  2026-10-12 12:24   ` Christoph Hellwig
@ 2026-10-12 15:31     ` Bart Van Assche
  0 siblings, 0 replies; 15+ messages in thread
From: Bart Van Assche @ 2026-10-12 15:31 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Martin K . Petersen, linux-scsi, John Garry

On 10/12/26 5:24 AM, Christoph Hellwig wrote:
> On Thu, Oct 08, 2026 at 03:42:18PM -0700, Bart Van Assche wrote:
>>   static inline void
>>   sdeb_meta_read_lock(struct sdeb_store_info *sip)
>> +	__acquires_shared(&sip->macc_meta_lck)
>> +	__context_unsafe(/*conditional locking*/)
>>   {
>> -	if (sdebug_no_rwlock) {
>> -		if (sip)
>> -			__acquire(&sip->macc_meta_lck);
>> -		else
>> -			__acquire(&sdeb_fake_rw_lck);
>> -	} else {
>> +	if (!sdebug_no_rwlock) {
> 
> Why can't this be modelled using a __acquire variant?  And if you
> add __context_unsafe(/*conditional locking*/) please add a detailed
> comment why that is needed, otherwise no one is going to understand
> this in the future.

Hi Christoph,

I will change the comment into "can't be annotated with
__{acquire,release}(,_shared}() without triggering undefined behavior".

What Sashiko reported on a Google-internal server for an
earlier attempt to annotate this and similar functions with
__{acquire,release}(,_shared}() has been included below. I think that
Sashiko is right:
=======================================================================
 >  static inline void
 >  sdeb_meta_read_lock(struct sdeb_store_info *sip)
 > +	__acquires_shared(&sip->macc_meta_lck)
 >  {
 >  	if (sdebug_no_rwlock) {
 > -		if (sip)
 > -			__acquire(&sip->macc_meta_lck);
 > -		else
 > -			__acquire(&sdeb_fake_rw_lck);
 > +		__acquire_shared(&sip->macc_meta_lck);
 >  	} else {
 > -		if (sip)
 > +		if (sip) {
 >  			read_lock(&sip->macc_meta_lck);
 > -		else
 > +		} else {
 >  			read_lock(&sdeb_fake_rw_lck);
 > +			__release_shared(&sdeb_fake_rw_lck);
 > +			__acquire_shared(&sip->macc_meta_lck);
                                          ^^^^^^^^^^^^^^^^^^^
Can this regression trigger an undefined behavior splat when sip is NULL?
When the scsi_debug driver is used with the module parameter fake_rw=1,
devip2sip() returns NULL. In this else branch, sip is explicitly NULL,
so evaluating &sip->macc_meta_lck means taking the address of a member
from a NULL pointer.
When compiled with Context Analysis and UBSAN (-fsanitize=null or
-fsanitize=pointer-overflow), the inline function call evaluates the
argument before the call and will trigger a runtime splat. Without UBSAN,
it calculates an invalid offset from a NULL pointer.
=======================================================================

Bart.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0()
  2026-10-08 22:42 ` [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0() Bart Van Assche
  2026-10-12 12:23   ` Christoph Hellwig
@ 2026-10-12 17:18   ` John Garry
  1 sibling, 0 replies; 15+ messages in thread
From: John Garry @ 2026-10-12 17:18 UTC (permalink / raw)
  To: Bart Van Assche, Martin K . Petersen; +Cc: linux-scsi, Christoph Hellwig

On 10/8/26 23:42, Bart Van Assche wrote:

Reviewed-by: John Garry <john.garry@linux.dev>

> +		ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status);
> +		sdeb_meta_read_unlock(sip);
> +	} else {
> +		ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status);
>   	}
>   
> -	ret = do_device_access(sip, scp, 0, lba, num, 0, false, false);
> -	if (meta_data_locked)
> -		sdeb_meta_read_unlock(sip);
>   	if (unlikely(ret == -1))

I think that ret < 0 is a better check, but this is pre-existing code 
and this is not too important.

> -		return DID_ERROR << 16;
> +		return scsi_status;


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-10-12 17:18 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08 22:42 [PATCH v5 0/8] scsi_debug: Enable lock context analysis Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 1/8] scsi: scsi_debug: Fix a locking bug in resp_write_same() Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 2/8] scsi: scsi_debug: Split resp_write_same() Bart Van Assche
2026-10-08 22:52   ` sashiko-bot
2026-10-08 23:27     ` Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 3/8] scsi: scsi_debug: Split corrupt_lbas() Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 4/8] scsi: scsi_debug: Split resp_read_dt0() Bart Van Assche
2026-10-12 12:23   ` Christoph Hellwig
2026-10-12 17:18   ` John Garry
2026-10-08 22:42 ` [PATCH v5 5/8] scsi: scsi_debug: Split resp_write_dt0() Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 6/8] scsi: scsi_debug: Split resp_atomic_write() Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 7/8] scsi: scsi_debug: Improve lock context annotations Bart Van Assche
2026-10-12 12:24   ` Christoph Hellwig
2026-10-12 15:31     ` Bart Van Assche
2026-10-08 22:42 ` [PATCH v5 8/8] scsi: core: Enable lock context analysis for the scsi_debug driver Bart Van Assche

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox