Linux SCSI subsystem development
 help / color / mirror / Atom feed
* [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem
@ 2026-07-30 22:44 Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 01/57] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
                   ` (56 more replies)
  0 siblings, 57 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen; +Cc: Marco Elver, linux-scsi, Bart Van Assche

This patch series enables lock context analysis for all SCSI drivers and also
for the SCSI core. The advantages are as follows:
 - The compiler (only Clang) verifies whether the lock and unlock calls match
   what has been declared via __must_hold(), __acquires() or __releases().
   This is useful for catching locking bugs in error paths.
 - Support for __guarded_by() is enabled. If a member variable is annotated
   with __guarded_by(lock), the compiler will issue a warning if that member
   variable is accessed without holding 'lock'.

Additionally, a patch is included that suppresses KCSAN complaints about SCSI
host state changes.

More information about lock context analysis is available in the cover letter of
[PATCH v5 00/36] Compiler-Based Context- and Locking-Analysis
(https://lore.kernel.org/lkml/20251219154418.3592607-1-elver@google.com/).

Please consider this patch series for the next merge window.

Thanks,

Bart.

Changes compared to v2:
 - Added patch "scsi: core: Pass the SCSI host pointer directly".
 - Corrected several annotations that had missing or extra ampersands (&).
 - Reduced the number of __assume_ctx_lock() statements.

Changes compared to v1:
 - Split patch "Enable lock context analysis" into one patch per driver.

Bart Van Assche (57):
  PCI: Convert to_pci_dev() into an inline function
  scsi: scsi_debug: Prepare for enabling lock context analysis
  scsi: sg: Prepare for enabling lock context analysis
  scsi: st: Prepare for enabling lock context analysis
  scsi: BusLogic: Introduce two local variables
  scsi: BusLogic: Prepare for enabling lock context analysis
  scsi: NCR5380: Prepare for enabling lock context analysis
  scsi: aacraid: Prepare for enabling lock context analysis
  scsi: aic7xxx: Enable lock context analysis
  scsi: aha152x: Prepare for enabling lock context analysis
  scsi: aic7xxx: Prepare for enabling lock context analysis
  scsi: aic94xx: Enable lock context analysis
  scsi: arcmsr: Enable lock context analysis
  scsi: arm: Enable lock context analysis
  scsi: be2iscsi: Prepare for enabling lock context analysis
  scsi: be2iscsi: Enable lock context analysis
  scsi: cxgbi: Enable lock context analysis
  scsi: bfa: Enable lock context analysis
  scsi: bnx2fc: Enable lock context analysis
  scsi: bnx2i: Introduce a local variable
  scsi: bnx2i: Enable lock context analysis
  scsi: csiostor: Enable lock context analysis
  scsi: elx: Enable lock context analysis
  scsi: esas2r: Enable lock context analysis
  scsi: fcoe: Enable lock context analysis
  scsi: fnic: Enable lock context analysis
  scsi: hisi_sas: Enable lock context analysis
  scsi: hpsa: Prepare for enabling lock context analysis
  scsi: ibmvscsi: Enable lock context analysis
  scsi: ibmvscsi_tgt: Enable lock context analysis
  scsi: ipr: Prepare for enabling lock context analysis
  scsi: ips: Prepare for enabling lock context analysis
  scsi: isci: Enable lock context analysis
  scsi: libfc: Enable lock context analysis
  scsi: libiscsi: Prepare for enabling lock context analysis
  scsi: libsas: Prepare for enabling lock context analysis
  scsi: libsas: Enable lock context analysis
  scsi: lpfc: Prepare for enabling lock context analysis
  scsi: megaraid_sas: Prepare for enabling lock context analysis
  scsi: megaraid: Enable lock context analysis
  scsi: mpt3sas: Enable lock context analysis
  scsi: mvsas: Enable lock context analysis
  scsi: pcmcia: Enable lock context analysis
  scsi: pm8001: Enable lock context analysis
  scsi: qedf: Enable lock context analysis
  scsi: qedi: Enable lock context analysis
  scsi: qla1280: Prepare for enabling lock context analysis
  scsi: qla2xxx: Enable lock context analysis
  scsi: qla4xxx: Enable lock context analysis
  scsi: ufs: Enable lock context analysis
  scsi: iSCSI transport: Prepare for enabling lock context analysis
  scsi: smartpqi: Enable lock context analysis
  scsi: snic: Enable lock context analysis
  scsi: sym53c8xx_2: Enable lock context analysis
  scsi: core: Pass the SCSI host pointer directly
  scsi: core: Enable lock context analysis
  scsi: core: Protect host state changes with the host lock

 drivers/scsi/BusLogic.c                     | 19 +++---
 drivers/scsi/BusLogic.h                     |  3 +-
 drivers/scsi/Makefile                       |  1 +
 drivers/scsi/NCR5380.c                      |  4 +-
 drivers/scsi/aacraid/Makefile               |  2 +
 drivers/scsi/aacraid/commctrl.c             |  1 +
 drivers/scsi/aacraid/commsup.c              |  3 +
 drivers/scsi/aha152x.c                      |  1 +
 drivers/scsi/aic7xxx/Makefile               |  2 +
 drivers/scsi/aic7xxx/aic79xx_osm.h          |  2 +
 drivers/scsi/aic7xxx/aic7xxx_osm.h          |  2 +
 drivers/scsi/aic94xx/Makefile               |  2 +
 drivers/scsi/arcmsr/Makefile                |  2 +
 drivers/scsi/arm/Makefile                   |  2 +
 drivers/scsi/be2iscsi/Makefile              |  2 +
 drivers/scsi/be2iscsi/be_main.c             |  4 ++
 drivers/scsi/bfa/Makefile                   |  3 +
 drivers/scsi/bnx2fc/Makefile                |  3 +
 drivers/scsi/bnx2fc/bnx2fc.h                |  5 +-
 drivers/scsi/bnx2fc/bnx2fc_els.c            |  2 +
 drivers/scsi/bnx2fc/bnx2fc_hwi.c            |  3 +
 drivers/scsi/bnx2fc/bnx2fc_io.c             |  6 +-
 drivers/scsi/bnx2i/Makefile                 |  3 +
 drivers/scsi/bnx2i/bnx2i_hwi.c              | 14 ++++-
 drivers/scsi/bnx2i/bnx2i_iscsi.c            |  1 +
 drivers/scsi/csiostor/Makefile              |  2 +
 drivers/scsi/csiostor/csio_hw.c             | 12 ++++
 drivers/scsi/csiostor/csio_lnode.c          |  3 +
 drivers/scsi/csiostor/csio_rnode.c          |  6 ++
 drivers/scsi/csiostor/csio_scsi.c           |  6 ++
 drivers/scsi/cxgbi/Makefile                 |  3 +
 drivers/scsi/device_handler/Makefile        |  3 +
 drivers/scsi/elx/Makefile                   |  1 +
 drivers/scsi/esas2r/Makefile                |  3 +
 drivers/scsi/fcoe/Makefile                  |  3 +
 drivers/scsi/fnic/Makefile                  |  3 +
 drivers/scsi/fnic/fdls_disc.c               | 52 +++++++++++++++-
 drivers/scsi/fnic/fip.c                     |  2 +
 drivers/scsi/fnic/fnic_fcs.c                |  6 ++
 drivers/scsi/fnic/fnic_scsi.c               |  4 ++
 drivers/scsi/hisi_sas/Makefile              |  3 +
 drivers/scsi/hosts.c                        | 13 ++--
 drivers/scsi/hpsa.c                         |  2 +-
 drivers/scsi/ibmvscsi/Makefile              |  3 +
 drivers/scsi/ibmvscsi_tgt/Makefile          |  3 +
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c    |  7 +++
 drivers/scsi/ipr.c                          | 11 ++++
 drivers/scsi/ips.c                          |  1 +
 drivers/scsi/isci/Makefile                  |  3 +
 drivers/scsi/libfc/Makefile                 |  2 +
 drivers/scsi/libfc/fc_disc.c                |  6 +-
 drivers/scsi/libfc/fc_exch.c                |  6 ++
 drivers/scsi/libfc/fc_fcp.c                 |  4 ++
 drivers/scsi/libiscsi.c                     | 19 +++++-
 drivers/scsi/libsas/Makefile                |  2 +
 drivers/scsi/libsas/sas_ata.c               |  2 +-
 drivers/scsi/lpfc/lpfc_els.c                |  2 +
 drivers/scsi/lpfc/lpfc_nportdisc.c          |  1 +
 drivers/scsi/lpfc/lpfc_scsi.c               |  1 +
 drivers/scsi/lpfc/lpfc_sli.c                |  2 +
 drivers/scsi/megaraid/Makefile              |  3 +
 drivers/scsi/megaraid/megaraid_sas.h        |  9 ++-
 drivers/scsi/megaraid/megaraid_sas_base.c   | 17 ++++--
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  2 +
 drivers/scsi/mpt3sas/Makefile               |  3 +
 drivers/scsi/mpt3sas/mpt3sas_scsih.c        |  2 +-
 drivers/scsi/mvsas/Makefile                 |  2 +
 drivers/scsi/mvsas/mv_sas.c                 |  7 +++
 drivers/scsi/pcmcia/Makefile                |  2 +
 drivers/scsi/pm8001/Makefile                |  1 +
 drivers/scsi/pm8001/pm80xx_hwi.c            |  2 +
 drivers/scsi/qedf/Makefile                  |  3 +
 drivers/scsi/qedi/Makefile                  |  3 +
 drivers/scsi/qedi/qedi_fw.c                 |  1 +
 drivers/scsi/qla1280.c                      | 18 ++++++
 drivers/scsi/qla2xxx/Makefile               |  3 +
 drivers/scsi/qla2xxx/qla_nx.c               |  2 +
 drivers/scsi/qla2xxx/qla_target.c           | 29 +++++----
 drivers/scsi/qla2xxx/qla_tmpl.c             |  1 +
 drivers/scsi/qla4xxx/Makefile               |  3 +
 drivers/scsi/qla4xxx/ql4_nx.c               |  2 +
 drivers/scsi/qla4xxx/ql4_os.c               |  6 +-
 drivers/scsi/scsi_debug.c                   | 65 +++++++++-----------
 drivers/scsi/scsi_lib.c                     |  3 +-
 drivers/scsi/scsi_scan.c                    | 51 +++++++++-------
 drivers/scsi/scsi_sysfs.c                   |  7 ++-
 drivers/scsi/scsi_transport_iscsi.c         |  1 +
 drivers/scsi/sg.c                           |  1 +
 drivers/scsi/smartpqi/Makefile              |  3 +
 drivers/scsi/smartpqi/smartpqi_init.c       | 67 +++++++++++++++++----
 drivers/scsi/snic/Makefile                  |  3 +
 drivers/scsi/st.c                           |  1 +
 drivers/scsi/sym53c8xx_2/Makefile           |  2 +
 drivers/ufs/core/Makefile                   |  2 +
 drivers/ufs/core/ufs-debugfs.c              |  8 ++-
 drivers/ufs/core/ufshcd.c                   | 14 +++++
 drivers/ufs/host/Makefile                   |  2 +
 include/linux/pci.h                         |  5 +-
 include/scsi/libiscsi.h                     |  5 +-
 include/scsi/scsi_host.h                    | 25 +++++---
 100 files changed, 543 insertions(+), 137 deletions(-)


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

* [PATCH v3 01/57] PCI: Convert to_pci_dev() into an inline function
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis Bart Van Assche
                   ` (55 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Bjorn Helgaas,
	Nathan Chancellor

Clang's context analysis checker performs alias analysis on expressions
passed to annotations like __acquires(). Clang's alias analysis does not
support container_of(). Convert to_pci_dev() from a macro into an inline
function such that Clang recognizes multiple to_pci_dev() expressions as
identical if the 'dev' argument is the same.

It is on purpose that to_pci_dev() accepts a const pointer and returns a
pointer that is not const. Any other choice, e.g. accepting a non-const
pointer or returning a const pointer, triggers compiler errors in code
that uses the to_pci_dev() macro.

While _Generic() could be used to support const and non-const struct
device pointers in a more elegant way, Clang's alias analysis does not
support _Generic().

Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 include/linux/pci.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index ebb5b9d76360..727050c5425a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -605,7 +605,10 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
 
 struct pci_dev *pci_alloc_dev(struct pci_bus *bus);
 
-#define	to_pci_dev(n) container_of(n, struct pci_dev, dev)
+static inline struct pci_dev *to_pci_dev(const struct device *dev)
+{
+	return container_of(dev, struct pci_dev, dev);
+}
 #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
 #define for_each_pci_dev_reverse(d) \
 	while ((d = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)

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

* [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 01/57] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 23:01   ` sashiko-bot
  2026-07-30 22:44 ` [PATCH v3 03/57] scsi: sg: " Bart Van Assche
                   ` (54 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley,
	Nathan Chancellor

Suppress lock context analysis for the functions that perform conditional
locking to prevent that the Clang thread-safety analyzer complains about
these functions. Remove incorrect __acquire() and __release() annotations.

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

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 9d1c9c41d0f9..d88164d5f409 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -4006,42 +4006,39 @@ static inline struct sdeb_store_info *devip2sip(struct sdebug_dev_info *devip,
 
 static inline void
 sdeb_read_lock(rwlock_t *lock)
+	__context_unsafe(conditional locking)
 {
-	if (sdebug_no_rwlock)
-		__acquire(lock);
-	else
+	if (!sdebug_no_rwlock)
 		read_lock(lock);
 }
 
 static inline void
 sdeb_read_unlock(rwlock_t *lock)
+	__context_unsafe(conditional locking)
 {
-	if (sdebug_no_rwlock)
-		__release(lock);
-	else
+	if (!sdebug_no_rwlock)
 		read_unlock(lock);
 }
 
 static inline void
 sdeb_write_lock(rwlock_t *lock)
+	__context_unsafe(conditional locking)
 {
-	if (sdebug_no_rwlock)
-		__acquire(lock);
-	else
+	if (!sdebug_no_rwlock)
 		write_lock(lock);
 }
 
 static inline void
 sdeb_write_unlock(rwlock_t *lock)
+	__context_unsafe(conditional locking)
 {
-	if (sdebug_no_rwlock)
-		__release(lock);
-	else
+	if (!sdebug_no_rwlock)
 		write_unlock(lock);
 }
 
 static inline void
 sdeb_data_read_lock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4050,6 +4047,7 @@ sdeb_data_read_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_read_unlock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4058,6 +4056,7 @@ sdeb_data_read_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_write_lock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4066,6 +4065,7 @@ sdeb_data_write_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_write_unlock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4074,6 +4074,7 @@ sdeb_data_write_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_read_lock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4082,6 +4083,7 @@ sdeb_data_sector_read_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_read_unlock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4090,6 +4092,7 @@ sdeb_data_sector_read_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_write_lock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4098,6 +4101,7 @@ sdeb_data_sector_write_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_sector_write_unlock(struct sdeb_store_info *sip)
+	__context_unsafe(conditional locking)
 {
 	BUG_ON(!sip);
 
@@ -4119,6 +4123,7 @@ sdeb_data_sector_write_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_data_lock(struct sdeb_store_info *sip, bool atomic)
+	__context_unsafe(conditional locking)
 {
 	if (atomic)
 		sdeb_data_write_lock(sip);
@@ -4128,6 +4133,7 @@ sdeb_data_lock(struct sdeb_store_info *sip, bool atomic)
 
 static inline void
 sdeb_data_unlock(struct sdeb_store_info *sip, bool atomic)
+	__context_unsafe(conditional locking)
 {
 	if (atomic)
 		sdeb_data_write_unlock(sip);
@@ -4138,6 +4144,7 @@ sdeb_data_unlock(struct sdeb_store_info *sip, bool atomic)
 /* Allow many reads but only 1x write per sector */
 static inline void
 sdeb_data_sector_lock(struct sdeb_store_info *sip, bool do_write)
+	__context_unsafe(conditional locking)
 {
 	if (do_write)
 		sdeb_data_sector_write_lock(sip);
@@ -4147,6 +4154,7 @@ sdeb_data_sector_lock(struct sdeb_store_info *sip, bool do_write)
 
 static inline void
 sdeb_data_sector_unlock(struct sdeb_store_info *sip, bool do_write)
+	__context_unsafe(conditional locking)
 {
 	if (do_write)
 		sdeb_data_sector_write_unlock(sip);
@@ -4156,13 +4164,9 @@ sdeb_data_sector_unlock(struct sdeb_store_info *sip, bool do_write)
 
 static inline void
 sdeb_meta_read_lock(struct sdeb_store_info *sip)
+	__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
@@ -4172,13 +4176,9 @@ sdeb_meta_read_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_meta_read_unlock(struct sdeb_store_info *sip)
+	__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
@@ -4188,13 +4188,9 @@ sdeb_meta_read_unlock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_meta_write_lock(struct sdeb_store_info *sip)
+	__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
@@ -4204,13 +4200,9 @@ sdeb_meta_write_lock(struct sdeb_store_info *sip)
 
 static inline void
 sdeb_meta_write_unlock(struct sdeb_store_info *sip)
+	__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
@@ -5239,6 +5231,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
 
 static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
 			   u32 ei_lba, bool unmap, bool ndob)
+	__context_unsafe(conditional locking)
 {
 	struct scsi_device *sdp = scp->device;
 	struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata;

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

* [PATCH v3 03/57] scsi: sg: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 01/57] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 04/57] scsi: st: " Bart Van Assche
                   ` (53 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Doug Gilbert,
	James E.J. Bottomley

Annotate open_wait() with __must_hold() since it unlocks and locks a
mutex.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/sg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 74cd4e8a61c2..dd3ca717ed13 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -245,6 +245,7 @@ static int sg_allow_access(struct file *filp, unsigned char *cmd)
 
 static int
 open_wait(Sg_device *sdp, int flags)
+	__must_hold(&sdp->open_rel_lock)
 {
 	int retval = 0;
 

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

* [PATCH v3 04/57] scsi: st: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (2 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 03/57] scsi: sg: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables Bart Van Assche
                   ` (52 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Document what mutex is released by st_common_ioctl().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/st.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index f1c3c4946637..234482e1b70b 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3535,6 +3535,7 @@ static int partition_tape(struct scsi_tape *STp, int size)
 static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm,
 			    struct file *file, unsigned int cmd_in,
 			    unsigned long arg)
+	__releases(&STp->lock)
 {
 	int i, retval = 0;
 

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

* [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (3 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 04/57] scsi: st: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 23:01   ` sashiko-bot
  2026-07-30 22:44 ` [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
                   ` (51 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Khalid Aziz,
	James E.J. Bottomley

Introduce two local variables to prepare for enabling lock context
analysis. No functionality has been changed.

Cc: Khalid Aziz <khalid@gonehiking.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/BusLogic.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 5304d2febd63..f2a6ed710c77 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2859,17 +2859,16 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt)
 {
 	struct blogic_adapter *adapter =
 		(struct blogic_adapter *) SCpnt->device->host->hostdata;
-
+	struct Scsi_Host *shost = adapter->scsi_host;
 	unsigned int id = SCpnt->device->id;
 	struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
 	int rc;
 
-	spin_lock_irq(SCpnt->device->host->host_lock);
-
+	spin_lock_irq(shost->host_lock);
 	blogic_inc_count(&stats->adapter_reset_req);
-
 	rc = blogic_resetadapter(adapter, false);
-	spin_unlock_irq(SCpnt->device->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
+
 	return rc;
 }
 
@@ -2886,6 +2885,7 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
 	struct blogic_tgt_flags *tgt_flags =
 		&adapter->tgt_flags[command->device->id];
 	struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
+	struct Scsi_Host *const shost = command->device->host;
 	unsigned char *cdb = command->cmnd;
 	int cdblen = command->cmd_len;
 	int tgt_id = command->device->id;
@@ -2915,9 +2915,9 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
 	 */
 	ccb = blogic_alloc_ccb(adapter);
 	if (ccb == NULL) {
-		spin_unlock_irq(adapter->scsi_host->host_lock);
+		spin_unlock_irq(shost->host_lock);
 		blogic_delay(1);
-		spin_lock_irq(adapter->scsi_host->host_lock);
+		spin_lock_irq(shost->host_lock);
 		ccb = blogic_alloc_ccb(adapter);
 		if (ccb == NULL) {
 			command->result = DID_ERROR << 16;
@@ -3062,10 +3062,10 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
 		   be initiated soon.
 		 */
 		if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
-			spin_unlock_irq(adapter->scsi_host->host_lock);
+			spin_unlock_irq(shost->host_lock);
 			blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter);
 			blogic_delay(1);
-			spin_lock_irq(adapter->scsi_host->host_lock);
+			spin_lock_irq(shost->host_lock);
 			if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
 						ccb)) {
 				blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);

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

* [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (4 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 23:06   ` sashiko-bot
  2026-07-30 22:44 ` [PATCH v3 07/57] scsi: NCR5380: " Bart Van Assche
                   ` (50 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Khalid Aziz,
	James E.J. Bottomley

Document locking requirements with __must_hold().

Acked-by: Khalid Aziz <khalid@gonehiking.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/BusLogic.c | 1 +
 drivers/scsi/BusLogic.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index f2a6ed710c77..dafec8b24e58 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2878,6 +2878,7 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt)
 */
 
 static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
+	__must_hold(command->device->host->host_lock)
 {
 	void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
 	struct blogic_adapter *adapter =
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
index 24697a5bedc8..c152b93fb6dd 100644
--- a/drivers/scsi/BusLogic.h
+++ b/drivers/scsi/BusLogic.h
@@ -1279,7 +1279,8 @@ static int blogic_sdev_configure(struct scsi_device *,
 				 struct queue_limits *lim);
 static void blogic_qcompleted_ccb(struct blogic_ccb *);
 static irqreturn_t blogic_inthandler(int, void *);
-static int blogic_resetadapter(struct blogic_adapter *, bool hard_reset);
+static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
+	__must_hold(adapter->scsi_host->host_lock);
 static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
 static int __init blogic_setup(char *);
 

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

* [PATCH v3 07/57] scsi: NCR5380: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (5 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 08/57] scsi: aacraid: " Bart Van Assche
                   ` (49 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Finn Thain,
	Michael Schmitz, James E.J. Bottomley

Expand 'hostdata' in the lock context annotations because 'hostdata' is
not a function argument.

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

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 006dcf981218..029fe6362629 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -961,7 +961,7 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
  */
 
 static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
-	__releases(&hostdata->lock) __acquires(&hostdata->lock)
+	__must_hold(&((struct NCR5380_hostdata *)shost_priv(instance))->lock)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char tmp[3], phase;
@@ -1657,7 +1657,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
  */
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
-	__releases(&hostdata->lock) __acquires(&hostdata->lock)
+	__must_hold(&((struct NCR5380_hostdata *)shost_priv(instance))->lock)
 {
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	unsigned char msgout = NOP;

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

* [PATCH v3 08/57] scsi: aacraid: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (6 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 07/57] scsi: NCR5380: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 23:04   ` sashiko-bot
  2026-07-30 22:44 ` [PATCH v3 09/57] scsi: aic7xxx: Enable " Bart Van Assche
                   ` (48 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche,
	Adaptec OEM Raid Solutions, James E.J. Bottomley

Document the aac_send_reset_adapter() locking requirements with
__must_hold(). Annotate functions that perform conditional locking with
__no_context_analysis.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/aacraid/Makefile   | 2 ++
 drivers/scsi/aacraid/commctrl.c | 1 +
 drivers/scsi/aacraid/commsup.c  | 3 +++
 3 files changed, 6 insertions(+)

diff --git a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile
index 8f0eec682bb6..415e0ed5ad24 100644
--- a/drivers/scsi/aacraid/Makefile
+++ b/drivers/scsi/aacraid/Makefile
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 # Adaptec aacraid
 
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_AACRAID) := aacraid.o
 
 aacraid-objs	:= linit.o aachba.o commctrl.o comminit.o commsup.o \
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index bd82aeb679ae..ac73c7b6d7be 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -1043,6 +1043,7 @@ struct aac_reset_iop {
 };
 
 static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg)
+	__must_hold(&dev->ioctl_mutex)
 {
 	struct aac_reset_iop reset;
 	int retval;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index c4485629f792..fb4d78233c6d 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -475,6 +475,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
 int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 		int priority, int wait, int reply, fib_callback callback,
 		void *callback_data)
+	__context_unsafe(conditional locking)
 {
 	struct aac_dev * dev = fibptr->dev;
 	struct hw_fib * hw_fib = fibptr->hw_fib_va;
@@ -698,6 +699,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 
 int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
 		void *callback_data)
+	__context_unsafe(conditional locking)
 {
 	struct aac_dev *dev = fibptr->dev;
 	int wait;
@@ -1466,6 +1468,7 @@ static void aac_schedule_bus_scan(struct aac_dev *aac)
 }
 
 static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
+	__context_unsafe(conditional locking)
 {
 	int index, quirks;
 	int retval;

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

* [PATCH v3 09/57] scsi: aic7xxx: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (7 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 08/57] scsi: aacraid: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 10/57] scsi: aha152x: Prepare for enabling " Bart Van Assche
                   ` (47 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Hannes Reinecke,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/aic7xxx/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile
index 853c72a81ae0..2da370d3d904 100644
--- a/drivers/scsi/aic7xxx/Makefile
+++ b/drivers/scsi/aic7xxx/Makefile
@@ -5,6 +5,8 @@
 # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#8 $
 #
 
+CONTEXT_ANALYSIS := y
+
 # Let kbuild descend into aicasm when cleaning
 subdir-				+= aicasm
 

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

* [PATCH v3 10/57] scsi: aha152x: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (8 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 09/57] scsi: aic7xxx: Enable " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 23:18   ` sashiko-bot
  2026-07-30 22:44 ` [PATCH v3 11/57] scsi: aic7xxx: " Bart Van Assche
                   ` (46 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Juergen E. Fischer,
	James E.J. Bottomley

Annotate is_complete() with __context_unsafe() because it performs
conditional locking.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/aha152x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index e3ccb6bb62c0..c16dcb9274eb 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -2319,6 +2319,7 @@ static void rsti_run(struct Scsi_Host *shpnt)
  *
  */
 static void is_complete(struct Scsi_Host *shpnt)
+	__context_unsafe(conditional locking)
 {
 	int dataphase;
 	unsigned long flags;

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

* [PATCH v3 11/57] scsi: aic7xxx: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (9 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 10/57] scsi: aha152x: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 12/57] scsi: aic94xx: Enable " Bart Van Assche
                   ` (45 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Hannes Reinecke,
	James E.J. Bottomley

Document locking requirements with __acquires() and __releases().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/aic7xxx/aic79xx_osm.h | 2 ++
 drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 793fe19993a9..c6eb2b97e929 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -376,12 +376,14 @@ ahd_lockinit(struct ahd_softc *ahd)
 
 static inline void
 ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
+	__acquires(&ahd->platform_data->spin_lock)
 {
 	spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
 }
 
 static inline void
 ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
+	__releases(&ahd->platform_data->spin_lock)
 {
 	spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
 }
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 51d9f4de0734..5e78fe7d3f32 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -389,12 +389,14 @@ ahc_lockinit(struct ahc_softc *ahc)
 
 static inline void
 ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
+	__acquires(&ahc->platform_data->spin_lock)
 {
 	spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
 }
 
 static inline void
 ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
+	__releases(&ahc->platform_data->spin_lock)
 {
 	spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
 }

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

* [PATCH v3 12/57] scsi: aic94xx: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (10 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 11/57] scsi: aic7xxx: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 13/57] scsi: arcmsr: " Bart Van Assche
                   ` (44 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/aic94xx/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/aic94xx/Makefile b/drivers/scsi/aic94xx/Makefile
index db9fbe3a8e4c..4ab04ce6edf2 100644
--- a/drivers/scsi/aic94xx/Makefile
+++ b/drivers/scsi/aic94xx/Makefile
@@ -6,6 +6,8 @@
 # Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
 #
 
+CONTEXT_ANALYSIS := y
+
 ccflags-$(CONFIG_AIC94XX_DEBUG) := -DASD_DEBUG -DASD_ENTER_EXIT
 
 obj-$(CONFIG_SCSI_AIC94XX) += aic94xx.o

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

* [PATCH v3 13/57] scsi: arcmsr: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (11 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 12/57] scsi: aic94xx: Enable " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 14/57] scsi: arm: " Bart Van Assche
                   ` (43 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/arcmsr/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/arcmsr/Makefile b/drivers/scsi/arcmsr/Makefile
index 9051f66cae36..6c12d36994da 100644
--- a/drivers/scsi/arcmsr/Makefile
+++ b/drivers/scsi/arcmsr/Makefile
@@ -2,6 +2,8 @@
 # File: drivers/arcmsr/Makefile
 # Makefile for the ARECA PCI-X PCI-EXPRESS SATA RAID controllers SCSI driver.
 
+CONTEXT_ANALYSIS := y
+
 arcmsr-objs := arcmsr_attr.o arcmsr_hba.o
 
 obj-$(CONFIG_SCSI_ARCMSR) := arcmsr.o

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

* [PATCH v3 14/57] scsi: arm: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (12 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 13/57] scsi: arcmsr: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:44 ` [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling " Bart Van Assche
                   ` (42 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Russell King,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/arm/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/arm/Makefile b/drivers/scsi/arm/Makefile
index b576d9276f71..417d47644a8d 100644
--- a/drivers/scsi/arm/Makefile
+++ b/drivers/scsi/arm/Makefile
@@ -3,6 +3,8 @@
 # Makefile for drivers/scsi/arm
 #
 
+CONTEXT_ANALYSIS := y
+
 acornscsi_mod-objs	:= acornscsi.o acornscsi-io.o
 
 obj-$(CONFIG_SCSI_ACORNSCSI_3)	+= acornscsi_mod.o queue.o msgqueue.o

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

* [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (13 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 14/57] scsi: arm: " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 23:04   ` sashiko-bot
  2026-07-30 22:44 ` [PATCH v3 16/57] scsi: be2iscsi: Enable " Bart Van Assche
                   ` (41 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Ketan Mukadam,
	James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/be2iscsi/be_main.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index fd18d4d3d219..289d9d18482c 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1185,6 +1185,7 @@ static void
 be_complete_logout(struct beiscsi_conn *beiscsi_conn,
 		    struct iscsi_task *task,
 		    struct common_sol_cqe *csol_cqe)
+	__must_hold(&beiscsi_conn->conn->session->back_lock)
 {
 	struct iscsi_logout_rsp *hdr;
 	struct beiscsi_io_task *io_task = task->dd_data;
@@ -1212,6 +1213,7 @@ static void
 be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
 		 struct iscsi_task *task,
 		 struct common_sol_cqe *csol_cqe)
+	__must_hold(&beiscsi_conn->conn->session->back_lock)
 {
 	struct iscsi_tm_rsp *hdr;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
@@ -1268,6 +1270,7 @@ static void
 be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
 			struct iscsi_task *task,
 			struct common_sol_cqe *csol_cqe)
+	__must_hold(&beiscsi_conn->conn->session->back_lock)
 {
 	struct iscsi_nopin *hdr;
 	struct iscsi_conn *conn = beiscsi_conn->conn;
@@ -1423,6 +1426,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
 static unsigned int
 beiscsi_complete_pdu(struct beiscsi_conn *beiscsi_conn,
 		struct pdu_base *phdr, void *pdata, unsigned int dlen)
+	__must_hold(&beiscsi_conn->conn->session->back_lock)
 {
 	struct beiscsi_hba *phba = beiscsi_conn->phba;
 	struct iscsi_conn *conn = beiscsi_conn->conn;

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

* [PATCH v3 16/57] scsi: be2iscsi: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (14 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:44 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 17/57] scsi: cxgbi: " Bart Van Assche
                   ` (40 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:44 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Ketan Mukadam,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/be2iscsi/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/be2iscsi/Makefile b/drivers/scsi/be2iscsi/Makefile
index 910885343a75..73d47c687007 100644
--- a/drivers/scsi/be2iscsi/Makefile
+++ b/drivers/scsi/be2iscsi/Makefile
@@ -4,6 +4,8 @@
 #
 #
 
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_BE2ISCSI) += be2iscsi.o
 
 be2iscsi-y := be_iscsi.o be_main.o be_mgmt.o be_cmds.o

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

* [PATCH v3 17/57] scsi: cxgbi: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (15 preceding siblings ...)
  2026-07-30 22:44 ` [PATCH v3 16/57] scsi: be2iscsi: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 18/57] scsi: bfa: " Bart Van Assche
                   ` (39 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/cxgbi/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/cxgbi/Makefile b/drivers/scsi/cxgbi/Makefile
index abfd38a26fec..c614afa18a33 100644
--- a/drivers/scsi/cxgbi/Makefile
+++ b/drivers/scsi/cxgbi/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 ccflags-y += -I $(srctree)/drivers/net/ethernet/chelsio/libcxgb
 
 obj-$(CONFIG_SCSI_CXGB3_ISCSI)	+= libcxgbi.o cxgb3i/

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

* [PATCH v3 18/57] scsi: bfa: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (16 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 17/57] scsi: cxgbi: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 19/57] scsi: bnx2fc: " Bart Van Assche
                   ` (38 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Anil Gurumurthy,
	Sudarsana Kalluru, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/bfa/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
index 442fc3db8f1f..50c16fcfb01c 100644
--- a/drivers/scsi/bfa/Makefile
+++ b/drivers/scsi/bfa/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
 
 bfa-y := bfad.o bfad_im.o bfad_attr.o bfad_debugfs.o bfad_bsg.o

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

* [PATCH v3 19/57] scsi: bnx2fc: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (17 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 18/57] scsi: bfa: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:01   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 20/57] scsi: bnx2i: Introduce a local variable Bart Van Assche
                   ` (37 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Saurav Kashyap,
	Javed Hasan, GR-QLogic-Storage-Upstream, James E.J. Bottomley

Document the locking requirements with __must_hold(). Inform the
compiler about aliases for synchronization objects with
__assume_ctx_lock(). Make the argument names in the definition and the
declaration of bnx2fc_process_seq_cleanup_compl() consistent.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/bnx2fc/Makefile     | 3 +++
 drivers/scsi/bnx2fc/bnx2fc.h     | 5 +++--
 drivers/scsi/bnx2fc/bnx2fc_els.c | 2 ++
 drivers/scsi/bnx2fc/bnx2fc_hwi.c | 3 +++
 drivers/scsi/bnx2fc/bnx2fc_io.c  | 6 +++++-
 5 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/bnx2fc/Makefile b/drivers/scsi/bnx2fc/Makefile
index 1d72e279a97d..3feb6b4dae64 100644
--- a/drivers/scsi/bnx2fc/Makefile
+++ b/drivers/scsi/bnx2fc/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_BNX2X_FCOE) += bnx2fc.o
 
 bnx2fc-y := bnx2fc_els.o bnx2fc_fcoe.o bnx2fc_hwi.o bnx2fc_io.o bnx2fc_tgt.o \
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 8c8968ec8cb4..566632d7e880 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -592,9 +592,10 @@ int bnx2fc_send_stat_req(struct bnx2fc_hba *hba);
 int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, struct bnx2fc_cmd *io_req);
 int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req);
 int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl);
-void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnup_req,
+void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req,
 				      struct fcoe_task_ctx_entry *task,
-				      u8 rx_state);
+				      u8 rx_state)
+	__must_hold(&seq_clnp_req->cb_arg->aborted_io_req->tgt->tgt_lock);
 int bnx2fc_initiate_seq_cleanup(struct bnx2fc_cmd *orig_io_req, u32 offset,
 				enum fc_rctl r_ctl);
 
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c
index 749e30aaf926..1f333a135879 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_els.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_els.c
@@ -263,6 +263,7 @@ int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp)
 }
 
 static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
+	__must_hold(&cb_arg->aborted_io_req->tgt->tgt_lock)
 {
 	struct bnx2fc_mp_req *mp_req;
 	struct fc_frame_header *fc_hdr, *fh;
@@ -373,6 +374,7 @@ static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
 }
 
 static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
+	__must_hold(&cb_arg->aborted_io_req->tgt->tgt_lock)
 {
 	struct bnx2fc_cmd *orig_io_req, *new_io_req;
 	struct bnx2fc_cmd *rec_req;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index a5ecb87d5b2d..a3670c48900b 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -880,6 +880,9 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe,
 		return;
 	}
 
+	/* Tell the compiler that there is an alias for tgt->tgt_lock. */
+	__assume_ctx_lock(&io_req->cb_arg->aborted_io_req->tgt->tgt_lock);
+
 	/* Timestamp IO completion time */
 	cmd_type = io_req->cmd_type;
 
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 9c7a541a4523..351c72404b5f 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1080,7 +1080,7 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 }
 
 static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
-	__must_hold(&tgt->tgt_lock)
+	__must_hold(&io_req->tgt->tgt_lock)
 {
 	struct bnx2fc_rport *tgt = io_req->tgt;
 	unsigned int time_left;
@@ -1207,6 +1207,8 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
 		if (cancel_delayed_work(&io_req->timeout_work))
 			kref_put(&io_req->refcount,
 				 bnx2fc_cmd_release); /* drop timer hold */
+		/* Tell the compiler that io_req->tgt == tgt. */
+		__assume_ctx_lock(&io_req->tgt->tgt_lock);
 		/*
 		 * We don't want to hold off the upper layer timer so simply
 		 * cleanup the command and return that I/O was successfully
@@ -1258,6 +1260,8 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
 		/* Let the scsi-ml try to recover this command */
 		printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
 		       io_req->xid);
+		/* Tell the compiler that io_req->tgt == tgt. */
+		__assume_ctx_lock(&io_req->tgt->tgt_lock);
 		/*
 		 * Cleanup firmware residuals before returning control back
 		 * to SCSI ML.

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

* [PATCH v3 20/57] scsi: bnx2i: Introduce a local variable
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (18 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 19/57] scsi: bnx2fc: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis Bart Van Assche
                   ` (36 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Nilesh Javali,
	Manish Rangankar, GR-QLogic-Storage-Upstream,
	James E.J. Bottomley

Prepare for adding a new statement that will use the new local variable
'conn'. No functionality has been changed.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/bnx2i/bnx2i_hwi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index d24cc2c795d6..4fb68ec8e9b0 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1741,6 +1741,7 @@ static void bnx2i_process_async_mesg(struct iscsi_session *session,
 				     struct bnx2i_conn *bnx2i_conn,
 				     struct cqe *cqe)
 {
+	struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
 	struct bnx2i_async_msg *async_cqe;
 	struct iscsi_async *resp_hdr;
 	u8 async_event;
@@ -1751,7 +1752,7 @@ static void bnx2i_process_async_mesg(struct iscsi_session *session,
 	async_event = async_cqe->async_event;
 
 	if (async_event == ISCSI_ASYNC_MSG_SCSI_EVENT) {
-		iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data,
+		iscsi_conn_printk(KERN_ALERT, conn,
 				  "async: scsi events not supported\n");
 		return;
 	}
@@ -1773,8 +1774,7 @@ static void bnx2i_process_async_mesg(struct iscsi_session *session,
 	resp_hdr->param2 = cpu_to_be16(async_cqe->param2);
 	resp_hdr->param3 = cpu_to_be16(async_cqe->param3);
 
-	__iscsi_complete_pdu(bnx2i_conn->cls_conn->dd_data,
-			     (struct iscsi_hdr *)resp_hdr, NULL, 0);
+	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
 	spin_unlock(&session->back_lock);
 }
 

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

* [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (19 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 20/57] scsi: bnx2i: Introduce a local variable Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:29   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 22/57] scsi: csiostor: " Bart Van Assche
                   ` (35 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Nilesh Javali,
	Manish Rangankar, GR-QLogic-Storage-Upstream,
	James E.J. Bottomley

Document locking requirements with __must_hold(). Use
__assume_ctx_lock() to inform the compiler about aliases for
synchronization objects.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/bnx2i/Makefile      | 3 +++
 drivers/scsi/bnx2i/bnx2i_hwi.c   | 8 ++++++++
 drivers/scsi/bnx2i/bnx2i_iscsi.c | 1 +
 3 files changed, 12 insertions(+)

diff --git a/drivers/scsi/bnx2i/Makefile b/drivers/scsi/bnx2i/Makefile
index 25378671bb1e..2d8e8f0fdd29 100644
--- a/drivers/scsi/bnx2i/Makefile
+++ b/drivers/scsi/bnx2i/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 bnx2i-y := bnx2i_init.o bnx2i_hwi.o bnx2i_iscsi.o bnx2i_sysfs.o
 
 obj-$(CONFIG_SCSI_BNX2_ISCSI) += bnx2i.o
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 4fb68ec8e9b0..5d927880d297 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -1347,6 +1347,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session,
 
 	resp_cqe = (struct bnx2i_cmd_response *)cqe;
 	spin_lock_bh(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	task = iscsi_itt_to_task(conn,
 				 resp_cqe->itt & ISCSI_CMD_RESPONSE_INDEX);
 	if (!task)
@@ -1443,6 +1444,7 @@ static int bnx2i_process_login_resp(struct iscsi_session *session,
 
 	login = (struct bnx2i_login_response *) cqe;
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	task = iscsi_itt_to_task(conn,
 				 login->itt & ISCSI_LOGIN_RESPONSE_INDEX);
 	if (!task)
@@ -1511,6 +1513,7 @@ static int bnx2i_process_text_resp(struct iscsi_session *session,
 
 	text = (struct bnx2i_text_response *) cqe;
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX);
 	if (!task)
 		goto done;
@@ -1570,6 +1573,7 @@ static int bnx2i_process_tmf_resp(struct iscsi_session *session,
 
 	tmf_cqe = (struct bnx2i_tmf_response *)cqe;
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	task = iscsi_itt_to_task(conn,
 				 tmf_cqe->itt & ISCSI_TMF_RESPONSE_INDEX);
 	if (!task)
@@ -1609,6 +1613,7 @@ static int bnx2i_process_logout_resp(struct iscsi_session *session,
 
 	logout = (struct bnx2i_logout_response *) cqe;
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	task = iscsi_itt_to_task(conn,
 				 logout->itt & ISCSI_LOGOUT_RESPONSE_INDEX);
 	if (!task)
@@ -1698,6 +1703,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
 	nop_in = (struct bnx2i_nop_in_msg *)cqe;
 
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	hdr = (struct iscsi_nopin *)&bnx2i_conn->gen_pdu.resp_hdr;
 	memset(hdr, 0, sizeof(struct iscsi_hdr));
 	hdr->opcode = nop_in->op_code;
@@ -1758,6 +1764,7 @@ static void bnx2i_process_async_mesg(struct iscsi_session *session,
 	}
 
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	resp_hdr = (struct iscsi_async *) &bnx2i_conn->gen_pdu.resp_hdr;
 	memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
 	resp_hdr->opcode = async_cqe->op_code;
@@ -1803,6 +1810,7 @@ static void bnx2i_process_reject_mesg(struct iscsi_session *session,
 		bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
 
 	spin_lock(&session->back_lock);
+	__assume_ctx_lock(&conn->session->back_lock);
 	hdr = (struct iscsi_reject *) &bnx2i_conn->gen_pdu.resp_hdr;
 	memset(hdr, 0, sizeof(struct iscsi_hdr));
 	hdr->opcode = reject->op_code;
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 6c80e5b514fd..c868eada72c3 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1154,6 +1154,7 @@ static void bnx2i_cpy_scsi_cdb(struct scsi_cmnd *sc, struct bnx2i_cmd *cmd)
 }
 
 static void bnx2i_cleanup_task(struct iscsi_task *task)
+	__must_hold(&task->conn->session->back_lock)
 {
 	struct iscsi_conn *conn = task->conn;
 	struct bnx2i_conn *bnx2i_conn = conn->dd_data;

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

* [PATCH v3 22/57] scsi: csiostor: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (20 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:19   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 23/57] scsi: elx: " Bart Van Assche
                   ` (34 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley,
	Kees Cook, Colin Ian King

Document lock context requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/csiostor/Makefile     |  2 ++
 drivers/scsi/csiostor/csio_hw.c    | 12 ++++++++++++
 drivers/scsi/csiostor/csio_lnode.c |  3 +++
 drivers/scsi/csiostor/csio_rnode.c |  6 ++++++
 drivers/scsi/csiostor/csio_scsi.c  |  6 ++++++
 5 files changed, 29 insertions(+)

diff --git a/drivers/scsi/csiostor/Makefile b/drivers/scsi/csiostor/Makefile
index d047e22eac0d..a19031efa7c4 100644
--- a/drivers/scsi/csiostor/Makefile
+++ b/drivers/scsi/csiostor/Makefile
@@ -4,6 +4,8 @@
 #
 ##
 
+CONTEXT_ANALYSIS := y
+
 ccflags-y += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb4
 
 obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor.o
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index df9f81f29950..4b4d3c42667f 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -914,6 +914,7 @@ csio_hw_dev_ready(struct csio_hw *hw)
  */
 static int
 csio_do_hello(struct csio_hw *hw, enum csio_dev_state *state)
+	__must_hold(&hw->lock)
 {
 	struct csio_mb	*mbp;
 	int	rv = 0;
@@ -2050,6 +2051,7 @@ csio_hw_flash_config(struct csio_hw *hw, u32 *fw_cfg_param, char *path)
  */
 static int
 csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param)
+	__must_hold(&hw->lock)
 {
 	struct csio_mb	*mbp = NULL;
 	struct fw_caps_config_cmd *caps_cmd;
@@ -2475,6 +2477,7 @@ static int csio_hw_check_fwver(struct csio_hw *hw)
  */
 static void
 csio_hw_configure(struct csio_hw *hw)
+	__must_hold(&hw->lock)
 {
 	int reset = 1;
 	int rv;
@@ -2604,6 +2607,7 @@ csio_hw_configure(struct csio_hw *hw)
  */
 static void
 csio_hw_initialize(struct csio_hw *hw)
+	__must_hold(&hw->lock)
 {
 	struct csio_mb	*mbp;
 	enum fw_retval retval;
@@ -2778,6 +2782,7 @@ csio_hw_fatal_err(struct csio_hw *hw)
  */
 static void
 csio_hws_uninit(struct csio_hw *hw, enum csio_hw_ev evt)
+	__must_hold(&hw->lock)
 {
 	hw->prev_evt = hw->cur_evt;
 	hw->cur_evt = evt;
@@ -2803,6 +2808,7 @@ csio_hws_uninit(struct csio_hw *hw, enum csio_hw_ev evt)
  */
 static void
 csio_hws_configuring(struct csio_hw *hw, enum csio_hw_ev evt)
+	__must_hold(&hw->lock)
 {
 	hw->prev_evt = hw->cur_evt;
 	hw->cur_evt = evt;
@@ -2988,6 +2994,7 @@ csio_hws_quiescing(struct csio_hw *hw, enum csio_hw_ev evt)
  */
 static void
 csio_hws_quiesced(struct csio_hw *hw, enum csio_hw_ev evt)
+	__must_hold(&hw->lock)
 {
 	hw->prev_evt = hw->cur_evt;
 	hw->cur_evt = evt;
@@ -3013,6 +3020,7 @@ csio_hws_quiesced(struct csio_hw *hw, enum csio_hw_ev evt)
  */
 static void
 csio_hws_resetting(struct csio_hw *hw, enum csio_hw_ev evt)
+	__must_hold(&hw->lock)
 {
 	hw->prev_evt = hw->cur_evt;
 	hw->cur_evt = evt;
@@ -3074,6 +3082,7 @@ csio_hws_removing(struct csio_hw *hw, enum csio_hw_ev evt)
  */
 static void
 csio_hws_pcierr(struct csio_hw *hw, enum csio_hw_ev evt)
+	__must_hold(&hw->lock)
 {
 	hw->prev_evt = hw->cur_evt;
 	hw->cur_evt = evt;
@@ -3763,6 +3772,7 @@ csio_hw_mb_timer(struct timer_list *t)
  */
 static void
 csio_hw_mbm_cleanup(struct csio_hw *hw)
+	__must_hold(&hw->lock)
 {
 	LIST_HEAD(cbfn_q);
 
@@ -3883,6 +3893,7 @@ csio_free_evt(struct csio_hw *hw, struct csio_evt_msg *evt_entry)
 
 void
 csio_evtq_flush(struct csio_hw *hw)
+	__must_hold(&hw->lock)
 {
 	uint32_t count;
 	count = 30;
@@ -4142,6 +4153,7 @@ csio_mgmt_tmo_handler(struct timer_list *t)
 
 static void
 csio_mgmtm_cleanup(struct csio_mgmtm *mgmtm)
+	__must_hold(&mgmtm->hw->lock)
 {
 	struct csio_hw *hw = mgmtm->hw;
 	struct csio_ioreq *io_req;
diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c
index 78d5ecd14f65..161973957976 100644
--- a/drivers/scsi/csiostor/csio_lnode.c
+++ b/drivers/scsi/csiostor/csio_lnode.c
@@ -872,6 +872,7 @@ csio_ln_read_fcf_entry(struct csio_lnode *ln,
 static void
 csio_handle_link_up(struct csio_hw *hw, uint8_t portid, uint32_t fcfi,
 		    uint32_t vnpi)
+	__must_hold(&hw->lock)
 {
 	struct csio_lnode *ln = NULL;
 
@@ -1165,6 +1166,7 @@ csio_lns_uninit(struct csio_lnode *ln, enum csio_ln_ev evt)
  */
 static void
 csio_lns_online(struct csio_lnode *ln, enum csio_ln_ev evt)
+	__must_hold(&csio_lnode_to_hw(ln)->lock)
 {
 	struct csio_hw *hw = csio_lnode_to_hw(ln);
 
@@ -1216,6 +1218,7 @@ csio_lns_online(struct csio_lnode *ln, enum csio_ln_ev evt)
  */
 static void
 csio_lns_ready(struct csio_lnode *ln, enum csio_ln_ev evt)
+	__must_hold(&csio_lnode_to_hw(ln)->lock)
 {
 	struct csio_hw *hw = csio_lnode_to_hw(ln);
 
diff --git a/drivers/scsi/csiostor/csio_rnode.c b/drivers/scsi/csiostor/csio_rnode.c
index 713e13adf4dc..74ef1e858cf3 100644
--- a/drivers/scsi/csiostor/csio_rnode.c
+++ b/drivers/scsi/csiostor/csio_rnode.c
@@ -546,6 +546,7 @@ csio_rn_verify_rparams(struct csio_lnode *ln, struct csio_rnode *rn,
 
 static void
 __csio_reg_rnode(struct csio_rnode *rn)
+	__must_hold(&csio_lnode_to_hw(csio_rnode_to_lnode(rn))->lock)
 {
 	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
 	struct csio_hw *hw = csio_lnode_to_hw(ln);
@@ -563,6 +564,7 @@ __csio_reg_rnode(struct csio_rnode *rn)
 
 static void
 __csio_unreg_rnode(struct csio_rnode *rn)
+	__must_hold(&csio_lnode_to_hw(csio_rnode_to_lnode(rn))->lock)
 {
 	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
 	struct csio_hw *hw = csio_lnode_to_hw(ln);
@@ -602,6 +604,7 @@ __csio_unreg_rnode(struct csio_rnode *rn)
  */
 static void
 csio_rns_uninit(struct csio_rnode *rn, enum csio_rn_ev evt)
+	__must_hold(&csio_rnode_to_lnode(rn)->hwp->lock)
 {
 	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
 	int ret = 0;
@@ -642,6 +645,7 @@ csio_rns_uninit(struct csio_rnode *rn, enum csio_rn_ev evt)
  */
 static void
 csio_rns_ready(struct csio_rnode *rn, enum csio_rn_ev evt)
+	__must_hold(&csio_rnode_to_lnode(rn)->hwp->lock)
 {
 	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
 	int ret = 0;
@@ -727,6 +731,7 @@ csio_rns_ready(struct csio_rnode *rn, enum csio_rn_ev evt)
  */
 static void
 csio_rns_offline(struct csio_rnode *rn, enum csio_rn_ev evt)
+	__must_hold(&csio_rnode_to_lnode(rn)->hwp->lock)
 {
 	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
 	int ret = 0;
@@ -786,6 +791,7 @@ csio_rns_offline(struct csio_rnode *rn, enum csio_rn_ev evt)
  */
 static void
 csio_rns_disappeared(struct csio_rnode *rn, enum csio_rn_ev evt)
+	__must_hold(&csio_rnode_to_lnode(rn)->hwp->lock)
 {
 	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
 	int ret = 0;
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index b1de615cf316..b74fed463640 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1157,6 +1157,7 @@ csio_scsi_cmpl_handler(struct csio_hw *hw, void *wr, uint32_t len,
  */
 void
 csio_scsi_cleanup_io_q(struct csio_scsim *scm, struct list_head *q)
+	__must_hold(&scm->hw->lock)
 {
 	struct csio_hw *hw = scm->hw;
 	struct csio_ioreq *ioreq;
@@ -1231,6 +1232,7 @@ csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd)
  */
 static int
 csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo)
+	__must_hold(&scm->hw->lock)
 {
 	struct csio_hw *hw = scm->hw;
 	struct list_head *tmp, *next;
@@ -1271,6 +1273,7 @@ csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo)
  */
 int
 csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
+	__must_hold(&scm->hw->lock)
 {
 	struct csio_hw *hw = scm->hw;
 	int rv = 0;
@@ -1316,6 +1319,7 @@ csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
  */
 int
 csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln)
+	__must_hold(&scm->hw->lock)
 {
 	struct csio_hw *hw = scm->hw;
 	struct csio_scsi_level_data sld;
@@ -2192,6 +2196,8 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
 	 * completes, we gather pending I/Os after the LUN reset.
 	 */
 	spin_lock_irq(&hw->lock);
+	/* Tell the compiler that scsim->hw == hw. */
+	__assume_ctx_lock(&scsim->hw->lock);
 	csio_scsi_gather_active_ios(scsim, &sld, &local_q);
 
 	retval = csio_scsi_abort_io_q(scsim, &local_q, 30000);

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

* [PATCH v3 23/57] scsi: elx: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (21 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 22/57] scsi: csiostor: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 24/57] scsi: esas2r: " Bart Van Assche
                   ` (33 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Ram Vegesna,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/elx/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/elx/Makefile b/drivers/scsi/elx/Makefile
index a8537d7a2a6e..0ed508e379fb 100644
--- a/drivers/scsi/elx/Makefile
+++ b/drivers/scsi/elx/Makefile
@@ -4,6 +4,7 @@
 # * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 # */
 
+CONTEXT_ANALYSIS := y
 
 obj-$(CONFIG_SCSI_EFCT) := efct.o
 

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

* [PATCH v3 24/57] scsi: esas2r: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (22 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 23/57] scsi: elx: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 25/57] scsi: fcoe: " Bart Van Assche
                   ` (32 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/esas2r/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/esas2r/Makefile b/drivers/scsi/esas2r/Makefile
index 279d9cb3ca69..325fa0e634fa 100644
--- a/drivers/scsi/esas2r/Makefile
+++ b/drivers/scsi/esas2r/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_ESAS2R)	+= esas2r.o
 
 esas2r-objs := esas2r_log.o esas2r_disc.o esas2r_flash.o esas2r_init.o \

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

* [PATCH v3 25/57] scsi: fcoe: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (23 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 24/57] scsi: esas2r: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 26/57] scsi: fnic: " Bart Van Assche
                   ` (31 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Hannes Reinecke,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/fcoe/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/fcoe/Makefile b/drivers/scsi/fcoe/Makefile
index 1183e80a09e7..5e7121231801 100644
--- a/drivers/scsi/fcoe/Makefile
+++ b/drivers/scsi/fcoe/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_FCOE) += fcoe.o
 obj-$(CONFIG_LIBFCOE) += libfcoe.o
 

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

* [PATCH v3 26/57] scsi: fnic: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (24 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 25/57] scsi: fcoe: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:11   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 27/57] scsi: hisi_sas: " Bart Van Assche
                   ` (30 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Karan Tilak Kumar,
	Satish Kharat, Sesidhar Baddela, James E.J. Bottomley

Document locking requirements with __must_hold(). Suppress complaints
about conditional locking in fnic_device_reset() with __acquire() and
__release().

Acked-by: Karan Tilak Kumar <kartilak@cisco.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/fnic/Makefile    |  3 ++
 drivers/scsi/fnic/fdls_disc.c | 52 +++++++++++++++++++++++++++++++++--
 drivers/scsi/fnic/fip.c       |  2 ++
 drivers/scsi/fnic/fnic_fcs.c  |  6 ++++
 drivers/scsi/fnic/fnic_scsi.c |  4 +++
 5 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile
index 48c5e0cb8ca6..22a463380dee 100644
--- a/drivers/scsi/fnic/Makefile
+++ b/drivers/scsi/fnic/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_FCOE_FNIC) += fnic.o
 
 fnic-y	:= \
diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c
index 8cb40466872f..e64fe1097e37 100644
--- a/drivers/scsi/fnic/fdls_disc.c
+++ b/drivers/scsi/fnic/fdls_disc.c
@@ -417,6 +417,7 @@ static void fdls_reset_oxid_pool(struct fnic_iport_s *iport)
 }
 
 void fnic_del_fabric_timer_sync(struct fnic *fnic)
+	__must_hold(&fnic->fnic_lock)
 {
 	fnic->iport.fabric.del_timer_inprogress = 1;
 	spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
@@ -425,8 +426,8 @@ void fnic_del_fabric_timer_sync(struct fnic *fnic)
 	fnic->iport.fabric.del_timer_inprogress = 0;
 }
 
-void fnic_del_tport_timer_sync(struct fnic *fnic,
-						struct fnic_tport_s *tport)
+void fnic_del_tport_timer_sync(struct fnic *fnic, struct fnic_tport_s *tport)
+	__must_hold(&fnic->fnic_lock)
 {
 	tport->del_timer_inprogress = 1;
 	spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
@@ -437,6 +438,7 @@ void fnic_del_tport_timer_sync(struct fnic *fnic,
 
 static void
 fdls_start_fabric_timer(struct fnic_iport_s *iport, int timeout)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	u64 fabric_tov;
 	struct fnic *fnic = iport->fnic;
@@ -462,6 +464,7 @@ fdls_start_fabric_timer(struct fnic_iport_s *iport, int timeout)
 static void
 fdls_start_tport_timer(struct fnic_iport_s *iport,
 					   struct fnic_tport_s *tport, int timeout)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	u64 fabric_tov;
 	struct fnic *fnic = iport->fnic;
@@ -717,6 +720,7 @@ int fdls_send_ls_req_abts(struct fnic_iport_s *iport,
 void
 fdls_send_tport_abts(struct fnic_iport_s *iport,
 					 struct fnic_tport_s *tport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	uint8_t s_id[3];
@@ -760,7 +764,9 @@ fdls_send_tport_abts(struct fnic_iport_s *iport,
 	/* Even if fnic_send_fcoe_frame() fails we want to retry after timeout */
 	fdls_start_tport_timer(iport, tport, 2 * iport->e_d_tov);
 }
+
 static void fdls_send_fabric_abts(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	uint8_t s_id[3];
@@ -932,6 +938,7 @@ static void fdls_send_fdmi_abts(struct fnic_iport_s *iport)
 }
 
 static void fdls_send_fabric_flogi(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_flogi *pflogi;
@@ -992,6 +999,7 @@ static void fdls_send_fabric_flogi(struct fnic_iport_s *iport)
 }
 
 static void fdls_send_fabric_plogi(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_flogi *pplogi;
@@ -1084,6 +1092,7 @@ static void fdls_send_fdmi_plogi(struct fnic_iport_s *iport)
 }
 
 static void fdls_send_rpn_id(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_rpn_id *prpn_id;
@@ -1143,6 +1152,7 @@ static void fdls_send_rpn_id(struct fnic_iport_s *iport)
 }
 
 static void fdls_send_scr(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_scr *pscr;
@@ -1198,6 +1208,7 @@ static void fdls_send_scr(struct fnic_iport_s *iport)
 }
 
 static void fdls_send_gpn_ft(struct fnic_iport_s *iport, int fdls_state)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_gpn_ft *pgpn_ft;
@@ -1257,6 +1268,7 @@ static void fdls_send_gpn_ft(struct fnic_iport_s *iport, int fdls_state)
 
 static void
 fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_els_adisc *padisc;
@@ -1322,6 +1334,7 @@ fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
 }
 
 bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_tport_event_s *tport_del_evt;
 	struct fnic *fnic = iport->fnic;
@@ -1387,6 +1400,7 @@ bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
 
 static void
 fdls_send_tgt_plogi(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_flogi *pplogi;
@@ -1455,6 +1469,7 @@ fnic_fc_plogi_rsp_rdf(struct fnic_iport_s *iport,
 }
 
 static void fdls_send_register_fc4_types(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_rft_id *prft_id;
@@ -1522,6 +1537,7 @@ static void fdls_send_register_fc4_types(struct fnic_iport_s *iport)
 }
 
 static void fdls_send_register_fc4_features(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_rff_id *prff_id;
@@ -1581,6 +1597,7 @@ static void fdls_send_register_fc4_features(struct fnic_iport_s *iport)
 
 static void
 fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_els_prli *pprli;
@@ -1662,6 +1679,7 @@ fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
  * Currently this assumes to be called with fnic lock held.
  */
 void fdls_send_fabric_logo(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint8_t *frame;
 	struct fc_std_logo *plogo;
@@ -1761,6 +1779,7 @@ void fdls_tgt_logout(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
 }
 
 static void fdls_tgt_discovery_start(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_tport_s *tport, *next;
 	u32 old_link_down_cnt = iport->fnic->link_down_cnt;
@@ -1811,6 +1830,7 @@ static void fdls_tgt_discovery_start(struct fnic_iport_s *iport)
  * pointing to it will be freed later
  */
 static void fdls_target_restart_nexus(struct fnic_tport_s *tport)
+	__must_hold(&((struct fnic_iport_s *)tport->iport)->fnic->fnic_lock)
 {
 	struct fnic_iport_s *iport = tport->iport;
 	struct fnic_tport_s *new_tport = NULL;
@@ -2617,6 +2637,7 @@ static void fdls_tport_timer_callback(struct timer_list *t)
 }
 
 static void fnic_fdls_start_flogi(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	iport->fabric.retry_counter = 0;
 	fdls_send_fabric_flogi(iport);
@@ -2625,6 +2646,7 @@ static void fnic_fdls_start_flogi(struct fnic_iport_s *iport)
 }
 
 static void fnic_fdls_start_plogi(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	iport->fabric.retry_counter = 0;
 	fdls_send_fabric_plogi(iport);
@@ -2643,6 +2665,7 @@ static void fnic_fdls_start_plogi(struct fnic_iport_s *iport)
 static void
 fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport,
 			   struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint32_t tgt_fcid;
 	struct fnic_tport_s *tport;
@@ -2733,6 +2756,7 @@ fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport,
 			   struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint32_t tgt_fcid;
 	struct fnic_tport_s *tport;
@@ -2767,6 +2791,8 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport,
 	if (tport->state != FDLS_TGT_STATE_PLOGI) {
 		FNIC_FCS_DBG(KERN_INFO, fnic,
 			     "PLOGI rsp recvd in wrong state. Drop the frame and restart nexus");
+		/* Tell the compiler that tport->iport == iport. */
+		__assume_ctx_lock(&((struct fnic_iport_s *)tport->iport)->fnic->fnic_lock);
 		fdls_target_restart_nexus(tport);
 		return;
 	}
@@ -2854,9 +2880,11 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport,
 	fdls_set_tport_state(tport, FDLS_TGT_STATE_PRLI);
 	fdls_send_tgt_prli(iport, tport);
 }
+
 static void
 fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport,
 			  struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint32_t tgt_fcid;
 	struct fnic_tport_s *tport;
@@ -2893,6 +2921,8 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport,
 	if (tport->state != FDLS_TGT_STATE_PRLI) {
 		FNIC_FCS_DBG(KERN_INFO, fnic,
 			     "PRLI rsp recvd in wrong state. Drop frame. Restarting nexus");
+		/* Tell the compiler that tport->iport == iport. */
+		__assume_ctx_lock(&((struct fnic_iport_s *)tport->iport)->fnic->fnic_lock);
 		fdls_target_restart_nexus(tport);
 		return;
 	}
@@ -3025,6 +3055,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_rff_id_rsp(struct fnic_iport_s *iport,
 			struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic *fnic = iport->fnic;
 	struct fnic_fdls_fabric_s *fdls = &iport->fabric;
@@ -3098,6 +3129,7 @@ fdls_process_rff_id_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_rft_id_rsp(struct fnic_iport_s *iport,
 			struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_fdls_fabric_s *fdls = &iport->fabric;
 	struct fc_std_rft_id *rft_rsp = (struct fc_std_rft_id *) fchdr;
@@ -3173,6 +3205,7 @@ fdls_process_rft_id_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_rpn_id_rsp(struct fnic_iport_s *iport,
 			struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_fdls_fabric_s *fdls = &iport->fabric;
 	struct fc_std_rpn_id *rpn_rsp = (struct fc_std_rpn_id *) fchdr;
@@ -3243,6 +3276,7 @@ fdls_process_rpn_id_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_scr_rsp(struct fnic_iport_s *iport,
 		     struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_fdls_fabric_s *fdls = &iport->fabric;
 	struct fc_std_scr *scr_rsp = (struct fc_std_scr *) fchdr;
@@ -3315,6 +3349,7 @@ fdls_process_scr_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_gpn_ft_tgt_list(struct fnic_iport_s *iport,
 			     struct fc_frame_header *fchdr, int len)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fc_gpn_ft_rsp_iu *gpn_ft_tgt;
 	struct fnic_tport_s *tport, *next;
@@ -3413,6 +3448,7 @@ fdls_process_gpn_ft_tgt_list(struct fnic_iport_s *iport,
 static void
 fdls_process_gpn_ft_rsp(struct fnic_iport_s *iport,
 			struct fc_frame_header *fchdr, int len)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_fdls_fabric_s *fdls = &iport->fabric;
 	struct fc_std_gpn_ft *gpn_ft_rsp = (struct fc_std_gpn_ft *) fchdr;
@@ -3549,6 +3585,7 @@ fdls_process_gpn_ft_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_fabric_logo_rsp(struct fnic_iport_s *iport,
 			     struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fc_std_flogi *flogo_rsp = (struct fc_std_flogi *) fchdr;
 	struct fnic_fdls_fabric_s *fdls = &iport->fabric;
@@ -3602,6 +3639,7 @@ fdls_process_fabric_logo_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_flogi_rsp(struct fnic_iport_s *iport,
 		       struct fc_frame_header *fchdr, void *rx_frame)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_fdls_fabric_s *fabric = &iport->fabric;
 	struct fc_std_flogi *flogi_rsp = (struct fc_std_flogi *) fchdr;
@@ -3741,6 +3779,7 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport,
 			      struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fc_std_flogi *plogi_rsp = (struct fc_std_flogi *) fchdr;
 	struct fc_std_els_rjt_rsp *els_rjt = (struct fc_std_els_rjt_rsp *) fchdr;
@@ -4002,6 +4041,7 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport,
 static void
 fdls_process_fabric_abts_rsp(struct fnic_iport_s *iport,
 			     struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint32_t s_id;
 	struct fc_std_abts_ba_acc *ba_acc = (struct fc_std_abts_ba_acc *)fchdr;
@@ -4359,6 +4399,7 @@ fdls_process_els_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr,
 static void
 fdls_process_tgt_abts_rsp(struct fnic_iport_s *iport,
 			  struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	uint32_t s_id;
 	struct fnic_tport_s *tport;
@@ -4548,6 +4589,7 @@ fdls_process_plogi_req(struct fnic_iport_s *iport,
 
 static void
 fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fc_std_logo *logo = (struct fc_std_logo *)fchdr;
 	uint32_t nport_id;
@@ -4588,6 +4630,8 @@ fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
 		FNIC_FCS_DBG(KERN_ERR, fnic,
 					 "tport fcid 0x%x: Canceling disc timer\n",
 					 tport->fcid);
+		/* Tell the compiler that tport->iport == iport. */
+		__assume_ctx_lock(&((struct fnic_iport_s *)tport->iport)->fnic->fnic_lock);
 		fnic_del_tport_timer_sync(fnic, tport);
 		tport->timer_pending = 0;
 	}
@@ -4625,6 +4669,7 @@ fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
 
 static void
 fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fc_std_rscn *rscn;
 	struct fc_els_rscn_page *rscn_port = NULL;
@@ -4758,6 +4803,7 @@ fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr)
 }
 
 void fnic_fdls_disc_start(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic *fnic = iport->fnic;
 
@@ -5102,6 +5148,7 @@ fnic_fdls_validate_and_get_frame_type(struct fnic_iport_s *iport,
 
 void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame,
 						  int len, int fchdr_offset)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fc_frame_header *fchdr;
 	uint32_t s_id = 0;
@@ -5223,6 +5270,7 @@ void fnic_fdls_disc_init(struct fnic_iport_s *iport)
 }
 
 void fnic_fdls_link_down(struct fnic_iport_s *iport)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic_tport_s *tport, *next;
 	struct fnic *fnic = iport->fnic;
diff --git a/drivers/scsi/fnic/fip.c b/drivers/scsi/fnic/fip.c
index 21d08a710f0d..6bca0dd89ee1 100644
--- a/drivers/scsi/fnic/fip.c
+++ b/drivers/scsi/fnic/fip.c
@@ -602,6 +602,7 @@ void fnic_common_fip_cleanup(struct fnic *fnic)
  * and clean up and restart the vlan discovery.
  */
 void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph)
+	__must_hold(&fnic->fnic_lock)
 {
 	struct fnic_iport_s *iport = &fnic->iport;
 	struct fip_cvl *cvl_msg = (struct fip_cvl *)fiph;
@@ -678,6 +679,7 @@ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph)
  * @frame: Received ethernet frame
  */
 int fdls_fip_recv_frame(struct fnic *fnic, void *frame)
+	__must_hold(&fnic->fnic_lock)
 {
 	struct ethhdr *eth = (struct ethhdr *)frame;
 	struct fip_header *fiph;
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index b00672ef8b00..d1d860275b60 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -944,6 +944,7 @@ void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
 void
 fnic_fdls_add_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport,
 					unsigned long flags)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic *fnic = iport->fnic;
 	struct fc_rport *rport;
@@ -983,6 +984,7 @@ fnic_fdls_add_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport,
 void
 fnic_fdls_remove_tport(struct fnic_iport_s *iport,
 					   struct fnic_tport_s *tport, unsigned long flags)
+	__must_hold(&iport->fnic->fnic_lock)
 {
 	struct fnic *fnic = iport->fnic;
 	struct rport_dd_data_s *rdd_data;
@@ -1032,6 +1034,8 @@ void fnic_delete_fcp_tports(struct fnic *fnic)
 	unsigned long flags;
 
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
+	/* Tell the compiler that fnic->iport.fnic == fnic. */
+	__assume_ctx_lock(&fnic->iport.fnic->fnic_lock);
 	list_for_each_entry_safe(tport, next, &fnic->iport.tport_list, links) {
 		FNIC_FCS_DBG(KERN_INFO, fnic,
 					 "removing fcp rport fcid: 0x%x", tport->fcid);
@@ -1059,6 +1063,8 @@ void fnic_tport_event_handler(struct work_struct *work)
 	struct fnic_tport_s *tport;
 
 	spin_lock_irqsave(&fnic->fnic_lock, flags);
+	/* Tell the compiler that fnic->iport.fnic == fnic. */
+	__assume_ctx_lock(&fnic->iport.fnic->fnic_lock);
 	list_for_each_entry_safe(cur_evt, next, &fnic->tport_event_list, links) {
 		tport = cur_evt->arg1;
 		switch (cur_evt->event) {
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 9607684bc610..afd6bf03b02d 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -2641,6 +2641,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 		 * allocated by mid layer.
 		 */
 		mutex_lock(&fnic->sgreset_mutex);
+		/* Fake __release() to keep the lock context analyzer happy. */
+		__release(&fnic->sgreset_mutex);
 		mqtag = fnic->fnic_max_tag_id;
 		new_sc = 1;
 	}  else {
@@ -2826,6 +2828,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 
 	if (new_sc) {
 		fnic->sgreset_sc = NULL;
+		/* Fake __acquire() to keep the lock context analyzer happy. */
+		__acquire(&fnic->sgreset_mutex);
 		mutex_unlock(&fnic->sgreset_mutex);
 	}
 

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

* [PATCH v3 27/57] scsi: hisi_sas: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (25 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 26/57] scsi: fnic: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:02   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 28/57] scsi: hpsa: Prepare for enabling " Bart Van Assche
                   ` (29 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Xingui Yang,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/hisi_sas/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile
index 742e732cd51d..8576c78d4afe 100644
--- a/drivers/scsi/hisi_sas/Makefile
+++ b/drivers/scsi/hisi_sas/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_main.o
 obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_v1_hw.o hisi_sas_v2_hw.o
 obj-$(CONFIG_SCSI_HISI_SAS_PCI)		+= hisi_sas_v3_hw.o

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

* [PATCH v3 28/57] scsi: hpsa: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (26 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 27/57] scsi: hisi_sas: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:27   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 29/57] scsi: ibmvscsi: Enable " Bart Van Assche
                   ` (28 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Don Brace,
	James E.J. Bottomley, Nathan Chancellor

mutex_lock_interruptible() returns a negative value upon failure or zero
upon success. Since the Clang thread-safety analyzer only supports == 0
and != 0 tests for functions that perform conditional locking, change
the == -EINTR test into != 0. This change does not modify the behavior
of hpsa_do_reset().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/hpsa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index a1b116cd4723..1b3595c6e036 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3163,7 +3163,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
 	int rc = 0;
 
 	/* We can really only handle one reset at a time */
-	if (mutex_lock_interruptible(&h->reset_mutex) == -EINTR) {
+	if (mutex_lock_interruptible(&h->reset_mutex)) {
 		dev_warn(&h->pdev->dev, "concurrent reset wait interrupted.\n");
 		return -EINTR;
 	}

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

* [PATCH v3 29/57] scsi: ibmvscsi: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (27 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 28/57] scsi: hpsa: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 30/57] scsi: ibmvscsi_tgt: " Bart Van Assche
                   ` (27 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Madhavan Srinivasan,
	Michael Ellerman, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ibmvscsi/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile
index 9408c7f4cdee..de6ed9e64b63 100644
--- a/drivers/scsi/ibmvscsi/Makefile
+++ b/drivers/scsi/ibmvscsi/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 ibmvfc-objs := ibmvfc-core.o ibmvfc-nvme.o
 
 obj-$(CONFIG_SCSI_IBMVSCSI)	+= ibmvscsi.o

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

* [PATCH v3 30/57] scsi: ibmvscsi_tgt: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (28 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 29/57] scsi: ibmvscsi: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:27   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 31/57] scsi: ipr: Prepare for enabling " Bart Van Assche
                   ` (26 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Tyrel Datwyler,
	James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ibmvscsi_tgt/Makefile       | 3 +++
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 7 +++++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/scsi/ibmvscsi_tgt/Makefile b/drivers/scsi/ibmvscsi_tgt/Makefile
index cc7a8256dcf8..7ae12ee9a347 100644
--- a/drivers/scsi/ibmvscsi_tgt/Makefile
+++ b/drivers/scsi/ibmvscsi_tgt/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_IBMVSCSIS)	+= ibmvscsis.o
 
 ibmvscsis-y := libsrp.o ibmvscsi_tgt.o
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index 61f682800765..8e532a195bf9 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -251,6 +251,7 @@ static void ibmvscsis_delete_client_info(struct scsi_info *vscsi,
  *	Process level, interrupt lock is held
  */
 static long ibmvscsis_free_command_q(struct scsi_info *vscsi)
+	__must_hold(&vscsi->intr_lock)
 {
 	int bytes;
 	u32 flags_under_lock;
@@ -874,6 +875,7 @@ static long ibmvscsis_establish_new_q(struct scsi_info *vscsi)
  *	Process environment, called with interrupt lock held
  */
 static void ibmvscsis_reset_queue(struct scsi_info *vscsi)
+	__must_hold(&vscsi->intr_lock)
 {
 	int bytes;
 	long rc = ADAPT_SUCCESS;
@@ -974,6 +976,7 @@ static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
  *	Process or interrupt environment called with interrupt lock held
  */
 static long ibmvscsis_ready_for_suspend(struct scsi_info *vscsi, bool idle)
+	__must_hold(&vscsi->intr_lock)
 {
 	long rc = 0;
 	struct viosrp_crq *crq;
@@ -1030,6 +1033,7 @@ static long ibmvscsis_ready_for_suspend(struct scsi_info *vscsi, bool idle)
  */
 static long ibmvscsis_trans_event(struct scsi_info *vscsi,
 				  struct viosrp_crq *crq)
+	__must_hold(&vscsi->intr_lock)
 {
 	long rc = ADAPT_SUCCESS;
 
@@ -1166,6 +1170,7 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi,
  *	intr_lock must be held
  */
 static void ibmvscsis_poll_cmd_q(struct scsi_info *vscsi)
+	__must_hold(&vscsi->intr_lock)
 {
 	struct viosrp_crq *crq;
 	long rc;
@@ -1310,6 +1315,7 @@ static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi)
  *	Process environment called with interrupt lock held
  */
 static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)
+	__must_hold(&vscsi->intr_lock)
 {
 	int free_qs = false;
 	long rc = 0;
@@ -2520,6 +2526,7 @@ static long ibmvscsis_ping_response(struct scsi_info *vscsi)
  */
 static long ibmvscsis_parse_command(struct scsi_info *vscsi,
 				    struct viosrp_crq *crq)
+	__must_hold(&vscsi->intr_lock)
 {
 	long rc = ADAPT_SUCCESS;
 

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

* [PATCH v3 31/57] scsi: ipr: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (29 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 30/57] scsi: ibmvscsi_tgt: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:15   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 32/57] scsi: ips: " Bart Van Assche
                   ` (25 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Brian King,
	James E.J. Bottomley

Document locking requirements with __must_hold().

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

diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index d207e5e81afe..51092834876c 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1016,6 +1016,7 @@ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
 static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd,
 				  void (*timeout_func) (struct timer_list *),
 				  u32 timeout)
+	__must_hold(ipr_cmd->ioa_cfg->host->host_lock)
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
 
@@ -5012,6 +5013,7 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd)
  **/
 static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
 			    struct ipr_resource_entry *res)
+	__must_hold(ioa_cfg->host->host_lock)
 {
 	struct ipr_cmnd *ipr_cmd;
 	struct ipr_ioarcb *ioarcb;
@@ -5020,6 +5022,8 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
 
 	ENTER;
 	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+	/* Tell the compiler that ipr_cmd->ioa_cfg == ioa_cfg. */
+	__assume_ctx_lock(ipr_cmd->ioa_cfg->host->host_lock);
 	ioarcb = &ipr_cmd->ioarcb;
 	cmd_pkt = &ioarcb->cmd_pkt;
 
@@ -5050,6 +5054,7 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
  *	SUCCESS / FAILED
  **/
 static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
+	__must_hold(scsi_cmd->device->host->host_lock)
 {
 	struct ipr_ioa_cfg *ioa_cfg;
 	struct ipr_resource_entry *res;
@@ -5069,6 +5074,9 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
 	if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead)
 		return FAILED;
 
+	/* Tell the compiler that ioa_cfg->host == scsi_cmd->device->host. */
+	__assume_ctx_lock(ioa_cfg->host->host_lock);
+
 	res->resetting_device = 1;
 	scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");
 
@@ -5189,6 +5197,7 @@ static void ipr_abort_timeout(struct timer_list *t)
  *	SUCCESS / FAILED
  **/
 static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
+	__must_hold(scsi_cmd->device->host->host_lock)
 {
 	struct ipr_cmnd *ipr_cmd;
 	struct ipr_ioa_cfg *ioa_cfg;
@@ -5239,6 +5248,8 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
 		return SUCCESS;
 
 	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
+	/* Tell the compiler that ipr_cmd->ioa_cfg == ioa_cfg. */
+	__assume_ctx_lock(ipr_cmd->ioa_cfg->host->host_lock);
 	ipr_cmd->ioarcb.res_handle = res->res_handle;
 	cmd_pkt = &ipr_cmd->ioarcb.cmd_pkt;
 	cmd_pkt->request_type = IPR_RQTYPE_IOACMD;

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

* [PATCH v3 32/57] scsi: ips: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (30 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 31/57] scsi: ipr: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:15   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 33/57] scsi: isci: Enable " Bart Van Assche
                   ` (24 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche,
	Adaptec OEM Raid Solutions, James E.J. Bottomley

Annotate ips_next() with __no_context_analysis because it performs
conditional locking.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/ips.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 41ed73966a48..5ef70f058ecd 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -2506,6 +2506,7 @@ ips_hainit(ips_ha_t * ha)
 /****************************************************************************/
 static void
 ips_next(ips_ha_t * ha, int intr)
+	__context_unsafe(conditional locking)
 {
 	ips_scb_t *scb;
 	struct scsi_cmnd *SC;

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

* [PATCH v3 33/57] scsi: isci: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (31 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 32/57] scsi: ips: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 34/57] scsi: libfc: " Bart Van Assche
                   ` (23 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/isci/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile
index da6f04cae272..00fd5c1a8d39 100644
--- a/drivers/scsi/isci/Makefile
+++ b/drivers/scsi/isci/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_ISCI) += isci.o
 isci-objs := init.o phy.o request.o \
 	     remote_device.o port.o \

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

* [PATCH v3 34/57] scsi: libfc: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (32 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 33/57] scsi: isci: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:19   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling " Bart Van Assche
                   ` (22 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Hannes Reinecke,
	James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/libfc/Makefile  | 2 ++
 drivers/scsi/libfc/fc_disc.c | 6 +++++-
 drivers/scsi/libfc/fc_exch.c | 6 ++++++
 drivers/scsi/libfc/fc_fcp.c  | 4 ++++
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/libfc/Makefile b/drivers/scsi/libfc/Makefile
index 65396f86c307..b265cf2a84a2 100644
--- a/drivers/scsi/libfc/Makefile
+++ b/drivers/scsi/libfc/Makefile
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # $Id: Makefile
 
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_LIBFC) += libfc.o
 
 libfc-objs := \
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 7792724d5b97..862516dcd324 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -37,7 +37,7 @@
 #define FC_DISC_RETRY_LIMIT	3	/* max retries */
 #define FC_DISC_RETRY_DELAY	500UL	/* (msecs) delay */
 
-static void fc_disc_gpn_ft_req(struct fc_disc *);
+static void fc_disc_gpn_ft_req(struct fc_disc *disc) __must_hold(&disc->disc_mutex);
 static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
 static void fc_disc_done(struct fc_disc *, enum fc_disc_event);
 static void fc_disc_timeout(struct work_struct *);
@@ -200,6 +200,7 @@ static void fc_disc_recv_req(struct fc_lport *lport, struct fc_frame *fp)
  * @disc: The discovery object to be restarted
  */
 static void fc_disc_restart(struct fc_disc *disc)
+	__must_hold(&disc->disc_mutex)
 {
 	lockdep_assert_held(&disc->disc_mutex);
 
@@ -250,6 +251,7 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
  * @event: The discovery completion status
  */
 static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event)
+	__must_hold(&disc->disc_mutex)
 {
 	struct fc_lport *lport = fc_disc_lport(disc);
 	struct fc_rport_priv *rdata;
@@ -294,6 +296,7 @@ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event)
  * @fp:	  The error code encoded as a frame pointer
  */
 static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
+	__must_hold(&disc->disc_mutex)
 {
 	struct fc_lport *lport = fc_disc_lport(disc);
 	unsigned long delay = 0;
@@ -374,6 +377,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc)
  * Goes through the list of IDs and names resulting from a request.
  */
 static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
+	__must_hold(&disc->disc_mutex)
 {
 	struct fc_lport *lport;
 	struct fc_gpn_ft_resp *np;
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 9183a0e9568a..9057a95d8612 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -811,6 +811,7 @@ static void fc_exch_timeout(struct work_struct *work)
  */
 static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
 					struct fc_exch_mgr *mp)
+	__context_unsafe(conditionally acquires &_res->ex_lock)
 {
 	struct fc_exch *ep;
 	unsigned int cpu;
@@ -904,6 +905,7 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
  */
 static struct fc_exch *fc_exch_alloc(struct fc_lport *lport,
 				     struct fc_frame *fp)
+	__context_unsafe(conditionally acquires &_res->ex_lock)
 {
 	struct fc_exch_mgr_anchor *ema;
 	struct fc_exch *ep;
@@ -996,6 +998,8 @@ static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
 
 	ep = fc_exch_alloc(lport, fp);
 	if (ep) {
+		/* Acquired by fc_exch_alloc(). */
+		__acquire(&ep->ex_lock);
 		ep->class = fc_frame_class(fp);
 
 		/*
@@ -2191,6 +2195,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
 		fc_frame_free(fp);
 		return NULL;
 	}
+	/* Acquired by fc_exch_alloc(). */
+	__acquire(&ep->ex_lock);
 	ep->esb_stat |= ESB_ST_SEQ_INIT;
 	fh = fc_frame_header_get(fp);
 	fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id));
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index a5139e43ca4c..9ba31a8a5250 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -207,6 +207,7 @@ static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp)
  * needed.
  */
 static inline int fc_fcp_lock_pkt(struct fc_fcp_pkt *fsp)
+	__cond_acquires(0, &fsp->scsi_pkt_lock)
 {
 	spin_lock_bh(&fsp->scsi_pkt_lock);
 	if (fsp->state & FC_SRB_COMPL) {
@@ -224,6 +225,7 @@ static inline int fc_fcp_lock_pkt(struct fc_fcp_pkt *fsp)
  * @fsp: The FCP packet to be unlocked and decremented
  */
 static inline void fc_fcp_unlock_pkt(struct fc_fcp_pkt *fsp)
+	__releases(&fsp->scsi_pkt_lock)
 {
 	spin_unlock_bh(&fsp->scsi_pkt_lock);
 	fc_fcp_pkt_release(fsp);
@@ -1242,6 +1244,7 @@ static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
  * Called to send an abort and then wait for abort completion
  */
 static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp)
+	__must_hold(&fsp->scsi_pkt_lock)
 {
 	int rc = FAILED;
 	unsigned long ticks_left;
@@ -1950,6 +1953,7 @@ EXPORT_SYMBOL(fc_queuecommand);
  * The fcp packet lock must be held when calling.
  */
 static void fc_io_compl(struct fc_fcp_pkt *fsp)
+	__must_hold(&fsp->scsi_pkt_lock)
 {
 	struct fc_fcp_internal *si;
 	struct scsi_cmnd *sc_cmd;

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

* [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (33 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 34/57] scsi: libfc: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:17   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 36/57] scsi: libsas: " Bart Van Assche
                   ` (21 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Lee Duncan, Chris Leech,
	Mike Christie, James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/libiscsi.c | 19 ++++++++++++++++++-
 include/scsi/libiscsi.h |  5 +++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 160f02f2f51d..c6abaeb79d9c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1088,6 +1088,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
 
 static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 			       char *data, int datalen)
+	__must_hold(&conn->session->back_lock)
 {
 	struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
 	struct iscsi_hdr rejected_pdu;
@@ -1500,6 +1501,7 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
 
 static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
 			   bool was_requeue)
+	__must_hold(&conn->session->frwd_lock)
 {
 	int rc;
 
@@ -1915,7 +1917,8 @@ static void iscsi_tmf_timedout(struct timer_list *t)
 static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
 				   struct iscsi_tm *hdr, int age,
 				   int timeout)
-	__must_hold(&session->frwd_lock)
+	__must_hold(&conn->session->frwd_lock)
+	__must_hold(&conn->session->eh_mutex)
 {
 	struct iscsi_session *session = conn->session;
 
@@ -1962,6 +1965,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
  * Fail commands. session frwd lock held and xmit thread flushed.
  */
 static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error)
+	__must_hold(&conn->session->frwd_lock)
 {
 	struct iscsi_session *session = conn->session;
 	struct iscsi_task *task;
@@ -2408,6 +2412,9 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 
 	ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n", sc, task->itt);
 	conn = session->leadconn;
+	/* Tell the compiler that conn->session == session. */
+	__assume_ctx_lock(&conn->session->eh_mutex);
+	__assume_ctx_lock(&conn->session->frwd_lock);
 	iscsi_get_conn(conn->cls_conn);
 	conn->eh_abort_cnt++;
 	age = session->age;
@@ -2531,6 +2538,9 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
 	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
 		goto unlock;
 	conn = session->leadconn;
+	/* Tell the compiler that conn->session == session. */
+	__assume_ctx_lock(&conn->session->frwd_lock);
+	__assume_ctx_lock(&conn->session->eh_mutex);
 
 	/* only have one tmf outstanding at a time */
 	if (session->tmf_state != TMF_INITIAL)
@@ -2564,6 +2574,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
 	iscsi_suspend_tx(conn);
 
 	spin_lock_bh(&session->frwd_lock);
+	/* Tell the compiler that conn->session == session. */
+	__assume_ctx_lock(&conn->session->frwd_lock);
 	memset(hdr, 0, sizeof(*hdr));
 	fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
 	session->tmf_state = TMF_INITIAL;
@@ -2693,6 +2705,9 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
 	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
 		goto unlock;
 	conn = session->leadconn;
+	/* Tell the compiler that conn->session == session. */
+	__assume_ctx_lock(&conn->session->eh_mutex);
+	__assume_ctx_lock(&conn->session->frwd_lock);
 
 	/* only have one tmf outstanding at a time */
 	if (session->tmf_state != TMF_INITIAL)
@@ -2726,6 +2741,8 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
 	iscsi_suspend_tx(conn);
 
 	spin_lock_bh(&session->frwd_lock);
+	/* Tell the compiler that conn->session == session. */
+	__assume_ctx_lock(&conn->session->frwd_lock);
 	memset(hdr, 0, sizeof(*hdr));
 	fail_scsi_tasks(conn, -1, DID_ERROR);
 	session->tmf_state = TMF_INITIAL;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 3d765c77bcd9..d39b5b268e6f 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -474,8 +474,9 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
 				char *, uint32_t);
 extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
 			      char *, int);
-extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
-				char *, int);
+extern int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *,
+				char *, int)
+		__must_hold(&conn->session->back_lock);
 extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
 extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
 extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);

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

* [PATCH v3 36/57] scsi: libsas: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (34 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 37/57] scsi: libsas: Enable " Bart Van Assche
                   ` (20 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley,
	Nathan Chancellor, Kees Cook

Since Clang requires that lock context annotations only refer to
variables that are visible, modify a __must_hold() annotation.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/libsas/sas_ata.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 61368e55bf86..2340790c9f6b 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -153,7 +153,7 @@ static void sas_ata_task_done(struct sas_task *task)
 }
 
 static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
-	__must_hold(ap->lock)
+	__must_hold(qc->ap->lock)
 {
 	struct sas_task *task;
 	struct scatterlist *sg;

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

* [PATCH v3 37/57] scsi: libsas: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (35 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 36/57] scsi: libsas: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 38/57] scsi: lpfc: Prepare for enabling " Bart Van Assche
                   ` (19 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/libsas/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/libsas/Makefile b/drivers/scsi/libsas/Makefile
index 9dc32736cf21..6f6f1336b438 100644
--- a/drivers/scsi/libsas/Makefile
+++ b/drivers/scsi/libsas/Makefile
@@ -6,6 +6,8 @@
 # Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
 #
 
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas.o
 libsas-y +=  sas_init.o     \
 		sas_phy.o      \

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

* [PATCH v3 38/57] scsi: lpfc: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (36 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 37/57] scsi: libsas: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:09   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 39/57] scsi: megaraid_sas: " Bart Van Assche
                   ` (18 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Justin Tee, Paul Ely,
	James E.J. Bottomley

Annotate the functions that perform conditional locking with
__context_unsafe().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/lpfc/lpfc_els.c       | 2 ++
 drivers/scsi/lpfc/lpfc_nportdisc.c | 1 +
 drivers/scsi/lpfc/lpfc_scsi.c      | 1 +
 drivers/scsi/lpfc/lpfc_sli.c       | 2 ++
 4 files changed, 6 insertions(+)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 52fc5058976d..45e7f147b163 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -9597,6 +9597,7 @@ lpfc_els_timeout(struct timer_list *t)
  **/
 void
 lpfc_els_timeout_handler(struct lpfc_vport *vport)
+	__context_unsafe(conditional locking)
 {
 	struct lpfc_hba  *phba = vport->phba;
 	struct lpfc_sli_ring *pring;
@@ -9719,6 +9720,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
  **/
 void
 lpfc_els_flush_cmd(struct lpfc_vport *vport)
+	__context_unsafe(conditional locking)
 {
 	LIST_HEAD(abort_list);
 	LIST_HEAD(cancel_list);
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 9c449055a55e..79e5e876c879 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -220,6 +220,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
  */
 void
 lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
+	__context_unsafe(conditional locking)
 {
 	LIST_HEAD(abort_list);
 	LIST_HEAD(drv_cmpl_list);
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index f2cab134af7f..6c3fd3c33c53 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5520,6 +5520,7 @@ void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport)
  **/
 static int
 lpfc_abort_handler(struct scsi_cmnd *cmnd)
+	__context_unsafe(conditional locking)
 {
 	struct Scsi_Host  *shost = cmnd->device->host;
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 62a30a92b792..c76d62e8907c 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -3721,6 +3721,7 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba,
 static int
 lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 			  struct lpfc_iocbq *saveq)
+	__context_unsafe(conditional locking)
 {
 	struct lpfc_iocbq *cmdiocbp;
 	unsigned long iflag;
@@ -12871,6 +12872,7 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id,
 int
 lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
 			uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd cmd)
+	__context_unsafe(conditional locking)
 {
 	struct lpfc_hba *phba = vport->phba;
 	struct lpfc_io_buf *lpfc_cmd;

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

* [PATCH v3 39/57] scsi: megaraid_sas: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (37 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 38/57] scsi: lpfc: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:15   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 40/57] scsi: megaraid: Enable " Bart Van Assche
                   ` (17 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Kashyap Desai,
	Sumit Saxena, Shivasharan S, Chandrakanth patil,
	James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/megaraid/megaraid_sas.h        |  9 ++++++---
 drivers/scsi/megaraid/megaraid_sas_base.c   | 15 ++++++++++++---
 drivers/scsi/megaraid/megaraid_sas_fusion.c |  2 ++
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 8ee2bfe47571..67713173793a 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2696,15 +2696,18 @@ __le16 get_updated_dev_handle(struct megasas_instance *instance,
 			      struct MR_DRV_RAID_MAP_ALL *drv_map);
 void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
 	struct LD_LOAD_BALANCE_INFO *lbInfo);
-int megasas_get_ctrl_info(struct megasas_instance *instance);
+int megasas_get_ctrl_info(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex);
 /* PD sequence */
 int
 megasas_sync_pd_seq_num(struct megasas_instance *instance, bool pend);
 void megasas_set_dynamic_target_properties(struct scsi_device *sdev,
 		struct queue_limits *lim, bool is_target_prop);
 int megasas_get_target_prop(struct megasas_instance *instance,
-			    struct scsi_device *sdev);
-void megasas_get_snapdump_properties(struct megasas_instance *instance);
+			    struct scsi_device *sdev)
+	__must_hold(&instance->reset_mutex);
+void megasas_get_snapdump_properties(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex);
 
 int megasas_set_crash_dump_params(struct megasas_instance *instance,
 	u8 crash_buf_state);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index ecd365d78ae3..ccefe5841a17 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -132,14 +132,16 @@ MODULE_AUTHOR("megaraidlinux.pdl@broadcom.com");
 MODULE_DESCRIPTION("Broadcom MegaRAID SAS Driver");
 
 int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
-static int megasas_get_pd_list(struct megasas_instance *instance);
+static int megasas_get_pd_list(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex);
 static int megasas_ld_list_query(struct megasas_instance *instance,
 				 u8 query_type);
 static int megasas_issue_init_mfi(struct megasas_instance *instance);
 static int megasas_register_aen(struct megasas_instance *instance,
 				u32 seq_num, u32 class_locale_word);
 static void megasas_get_pd_info(struct megasas_instance *instance,
-				struct scsi_device *sdev);
+				struct scsi_device *sdev)
+	__must_hold(&instance->reset_mutex);
 static void
 megasas_set_ld_removed_by_fw(struct megasas_instance *instance);
 
@@ -229,7 +231,8 @@ megasas_adp_reset_gen2(struct megasas_instance *instance,
 		       struct megasas_register_set __iomem *reg_set);
 static irqreturn_t megasas_isr(int irq, void *devp);
 static u32
-megasas_init_adapter_mfi(struct megasas_instance *instance);
+megasas_init_adapter_mfi(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex);
 u32
 megasas_build_and_issue_cmd(struct megasas_instance *instance,
 			    struct scsi_cmnd *scmd);
@@ -4754,6 +4757,7 @@ megasas_get_pd_list(struct megasas_instance *instance)
  */
 static int
 megasas_get_ld_list(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex)
 {
 	int ret = 0, ld_index = 0, ids = 0;
 	struct megasas_cmd *cmd;
@@ -4871,6 +4875,7 @@ megasas_get_ld_list(struct megasas_instance *instance)
  */
 static int
 megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
+	__must_hold(&instance->reset_mutex)
 {
 	int ret = 0, ld_index = 0, ids = 0;
 	struct megasas_cmd *cmd;
@@ -4993,6 +4998,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
 static int
 megasas_host_device_list_query(struct megasas_instance *instance,
 			       bool is_probe)
+	__must_hold(&instance->reset_mutex)
 {
 	int ret, i, target_id;
 	struct megasas_cmd *cmd;
@@ -5874,6 +5880,7 @@ static void megasas_setup_reply_map(struct megasas_instance *instance)
  */
 static
 int megasas_get_device_list(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex)
 {
 	if (instance->enable_fw_dev_list) {
 		if (megasas_host_device_list_query(instance, true))
@@ -7789,6 +7796,7 @@ megasas_suspend(struct device *dev)
  */
 static int __maybe_unused
 megasas_resume(struct device *dev)
+	__must_hold(&((struct megasas_instance *)dev_get_drvdata(dev))->reset_mutex)
 {
 	int rval;
 	struct Scsi_Host *host;
@@ -8765,6 +8773,7 @@ static inline void megasas_remove_scsi_device(struct scsi_device *sdev)
 static
 int megasas_update_device_list(struct megasas_instance *instance,
 			       int event_type)
+	__must_hold(&instance->reset_mutex)
 {
 	int dcmd_ret;
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 056cbe50e19e..a55094a31c82 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -1792,6 +1792,7 @@ static inline void megasas_free_ioc_init_cmd(struct megasas_instance *instance)
  */
 static u32
 megasas_init_adapter_fusion(struct megasas_instance *instance)
+	__must_hold(&instance->reset_mutex)
 {
 	struct fusion_context *fusion;
 	u32 scratch_pad_1;
@@ -4539,6 +4540,7 @@ static int
 megasas_issue_tm(struct megasas_instance *instance, u16 device_handle,
 	uint channel, uint id, u16 smid_task, u8 type,
 	struct MR_PRIV_DEVICE *mr_device_priv_data)
+	__must_hold(&instance->reset_mutex)
 {
 	struct MR_TASK_MANAGE_REQUEST *mr_request;
 	struct MPI2_SCSI_TASK_MANAGE_REQUEST *mpi_request;

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

* [PATCH v3 40/57] scsi: megaraid: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (38 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 39/57] scsi: megaraid_sas: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:15   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 41/57] scsi: mpt3sas: " Bart Van Assche
                   ` (16 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Kashyap Desai,
	Sumit Saxena, Shivasharan S, Chandrakanth patil,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/megaraid/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/megaraid/Makefile b/drivers/scsi/megaraid/Makefile
index 12177e4cae65..9a6976a4dc22 100644
--- a/drivers/scsi/megaraid/Makefile
+++ b/drivers/scsi/megaraid/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_MEGARAID_MM)	+= megaraid_mm.o
 obj-$(CONFIG_MEGARAID_MAILBOX)	+= megaraid_mbox.o
 obj-$(CONFIG_MEGARAID_SAS)	+= megaraid_sas.o

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

* [PATCH v3 41/57] scsi: mpt3sas: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (39 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 40/57] scsi: megaraid: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 42/57] scsi: mvsas: " Bart Van Assche
                   ` (15 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Sathya Prakash,
	Sreekanth Reddy, Suganath Prabu Subramani, Ranjan Kumar,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/mpt3sas/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/mpt3sas/Makefile b/drivers/scsi/mpt3sas/Makefile
index 18e2d87eb4a2..c698a106f3e3 100644
--- a/drivers/scsi/mpt3sas/Makefile
+++ b/drivers/scsi/mpt3sas/Makefile
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # mpt3sas makefile
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o
 mpt3sas-y +=  mpt3sas_base.o     \
 		mpt3sas_config.o \

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

* [PATCH v3 42/57] scsi: mvsas: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (40 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 41/57] scsi: mpt3sas: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:18   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 43/57] scsi: pcmcia: " Bart Van Assche
                   ` (14 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley,
	Damien Le Moal, Kees Cook, John Garry, Niklas Cassel

Document locking requirements with __must_hold(). Annotate functions
that perform conditional locking with __no_context_analysis.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/mvsas/Makefile | 2 ++
 drivers/scsi/mvsas/mv_sas.c | 7 +++++++
 2 files changed, 9 insertions(+)

diff --git a/drivers/scsi/mvsas/Makefile b/drivers/scsi/mvsas/Makefile
index 75849258e898..7f45cca38127 100644
--- a/drivers/scsi/mvsas/Makefile
+++ b/drivers/scsi/mvsas/Makefile
@@ -7,6 +7,8 @@
 # Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
 #
 
+CONTEXT_ANALYSIS := y
+
 ccflags-$(CONFIG_SCSI_MVSAS_DEBUG) := -DMV_DEBUG
 
 obj-$(CONFIG_SCSI_MVSAS) += mvsas.o
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index 359226e80eae..f63e0dc1abd2 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1055,6 +1055,7 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st)
 }
 
 static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock)
+	__context_unsafe(conditional locking)
 {
 	struct sas_ha_struct *sas_ha = sas_phy->ha;
 	struct mvs_info *mvi = NULL; int i = 0, hi;
@@ -1153,6 +1154,7 @@ static void mvs_free_dev(struct mvs_device *mvi_dev)
 }
 
 static int mvs_dev_found_notify(struct domain_device *dev, int lock)
+	__context_unsafe(conditional locking)
 {
 	unsigned long flags = 0;
 	int res = 0;
@@ -1517,6 +1519,7 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task,
 }
 
 int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
+	__must_hold(&mvi->lock)
 {
 	u32 slot_idx = rx_desc & RXQ_SLOT_MASK;
 	struct mvs_slot_info *slot = &mvi->slot_info[slot_idx];
@@ -1644,6 +1647,7 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
 
 void mvs_do_release_task(struct mvs_info *mvi,
 		int phy_no, struct domain_device *dev)
+	__must_hold(&mvi->lock)
 {
 	u32 slot_idx;
 	struct mvs_phy *phy;
@@ -1677,6 +1681,7 @@ void mvs_do_release_task(struct mvs_info *mvi,
 
 void mvs_release_task(struct mvs_info *mvi,
 		      struct domain_device *dev)
+	__must_hold(&mvi->lock)
 {
 	int i, phyno[WIDE_PORT_MAX_PHY], num;
 	num = mvs_find_dev_phyno(dev, phyno);
@@ -1769,6 +1774,7 @@ static void mvs_sig_time_out(struct timer_list *t)
 }
 
 void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
+	__must_hold(&mvi->lock)
 {
 	u32 tmp;
 	struct mvs_phy *phy = &mvi->phy[phy_no];
@@ -1862,6 +1868,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
 }
 
 int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
+	__must_hold(&mvi->lock)
 {
 	u32 rx_prod_idx, rx_desc;
 	bool attn = false;

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

* [PATCH v3 43/57] scsi: pcmcia: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (41 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 42/57] scsi: mvsas: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 44/57] scsi: pm8001: " Bart Van Assche
                   ` (13 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/pcmcia/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/pcmcia/Makefile b/drivers/scsi/pcmcia/Makefile
index 02f5b44a2685..06ea2bfcd42a 100644
--- a/drivers/scsi/pcmcia/Makefile
+++ b/drivers/scsi/pcmcia/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
+CONTEXT_ANALYSIS := y
+
 ccflags-y		:= -I $(srctree)/drivers/scsi
 
 # 16-bit client drivers

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

* [PATCH v3 44/57] scsi: pm8001: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (42 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 43/57] scsi: pcmcia: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:31   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 45/57] scsi: qedf: " Bart Van Assche
                   ` (12 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Jack Wang,
	James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/pm8001/Makefile     | 1 +
 drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/scsi/pm8001/Makefile b/drivers/scsi/pm8001/Makefile
index bbb51b7312f1..b236359810fe 100644
--- a/drivers/scsi/pm8001/Makefile
+++ b/drivers/scsi/pm8001/Makefile
@@ -4,6 +4,7 @@
 #
 # Copyright (C) 2008-2009  USI Co., Ltd.
 
+CONTEXT_ANALYSIS := y
 
 obj-$(CONFIG_SCSI_PM8001) += pm80xx.o
 
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 7a348f0194bd..ff6fdb761a70 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -2294,6 +2294,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 static void
 mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
 		struct outbound_queue_table *circularQ, void *piomb)
+	__must_hold(&circularQ->oq_lock)
 {
 	struct sas_task *t;
 	struct pm8001_ccb_info *ccb;
@@ -3858,6 +3859,7 @@ static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha,
  */
 static void process_one_iomb(struct pm8001_hba_info *pm8001_ha,
 		struct outbound_queue_table *circularQ, void *piomb)
+	__must_hold(&circularQ->oq_lock)
 {
 	__le32 pHeader = *(__le32 *)piomb;
 	u32 opc = (u32)((le32_to_cpu(pHeader)) & 0xFFF);

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

* [PATCH v3 45/57] scsi: qedf: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (43 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 44/57] scsi: pm8001: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 46/57] scsi: qedi: " Bart Van Assche
                   ` (11 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Saurav Kashyap,
	Javed Hasan, GR-QLogic-Storage-Upstream, James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/qedf/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/qedf/Makefile b/drivers/scsi/qedf/Makefile
index c46287826fb8..465982ba5dae 100644
--- a/drivers/scsi/qedf/Makefile
+++ b/drivers/scsi/qedf/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_QEDF) := qedf.o
 qedf-y = qedf_dbg.o qedf_main.o qedf_io.o qedf_fip.o \
 	 qedf_attr.o qedf_els.o drv_scsi_fw_funcs.o drv_fcoe_fw_funcs.o

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

* [PATCH v3 46/57] scsi: qedi: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (44 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 45/57] scsi: qedf: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:17   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 47/57] scsi: qla1280: Prepare for enabling " Bart Van Assche
                   ` (10 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Nilesh Javali,
	Manish Rangankar, GR-QLogic-Storage-Upstream,
	James E.J. Bottomley

Annotate qedi_cleanup_all_io() with __no_context_analysis since it
performs conditional locking.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/qedi/Makefile  | 3 +++
 drivers/scsi/qedi/qedi_fw.c | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/scsi/qedi/Makefile b/drivers/scsi/qedi/Makefile
index d84eedfd031b..f081d047b6eb 100644
--- a/drivers/scsi/qedi/Makefile
+++ b/drivers/scsi/qedi/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_QEDI) := qedi.o
 qedi-y := qedi_main.o qedi_iscsi.o qedi_fw.o qedi_sysfs.o \
 	    qedi_dbg.o qedi_fw_api.o
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
index 854efa4f61d8..e162061ca49c 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -1134,6 +1134,7 @@ int qedi_send_iscsi_logout(struct qedi_conn *qedi_conn,
 
 int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn,
 			struct iscsi_task *task, bool in_recovery)
+	__context_unsafe(conditional locking)
 {
 	int rval;
 	struct iscsi_task *ctask;

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

* [PATCH v3 47/57] scsi: qla1280: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (45 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 46/57] scsi: qedi: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:19   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 48/57] scsi: qla2xxx: Enable " Bart Van Assche
                   ` (9 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Document locking requirements with __must_hold().

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

diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index cdd6fe002c32..ebc878068684 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -737,6 +737,7 @@ static void qla1280_mailbox_timeout(struct timer_list *t)
 static int
 _qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp,
 				 struct completion *wait)
+	__must_hold(ha->host->host_lock)
 {
 	int	status = FAILED;
 	struct scsi_cmnd *cmd = sp->cmd;
@@ -754,6 +755,7 @@ _qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp,
 
 static int
 qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp)
+	__must_hold(ha->host->host_lock)
 {
 	DECLARE_COMPLETION_ONSTACK(wait);
 
@@ -763,6 +765,7 @@ qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp)
 
 static int
 qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target)
+	__must_hold(ha->host->host_lock)
 {
 	int		cnt;
 	int		status;
@@ -809,6 +812,7 @@ qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target)
  **************************************************************************/
 static int
 qla1280_error_action(struct scsi_cmnd *cmd, enum action action)
+	__must_hold(cmd->device->host->host_lock)
 {
 	struct scsi_qla_host *ha;
 	int bus, target, lun;
@@ -822,6 +826,10 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action)
 	ENTER("qla1280_error_action");
 
 	ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata);
+
+	/* Tell the compiler that ha->host == cmd->device->host. */
+	__assume_ctx_lock(ha->host->host_lock);
+
 	sp = scsi_cmd_priv(cmd);
 	bus = SCSI_BUS_32(cmd);
 	target = SCSI_TCN_32(cmd);
@@ -1490,6 +1498,7 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
  */
 static const struct firmware *
 qla1280_request_firmware(struct scsi_qla_host *ha)
+	__must_hold(ha->host->host_lock)
 {
 	const struct firmware *fw;
 	int err;
@@ -1655,6 +1664,7 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
 
 static int
 qla1280_load_firmware_pio(struct scsi_qla_host *ha)
+	__must_hold(ha->host->host_lock)
 {
 	/* enter with host_lock acquired */
 
@@ -1705,6 +1715,7 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha)
 #define DUMP_IT_BACK 0		/* for debug of RISC loading */
 static int
 qla1280_load_firmware_dma(struct scsi_qla_host *ha)
+	__must_hold(ha->host->host_lock)
 {
 	/* enter with host_lock acquired */
 	const struct firmware *fw;
@@ -1844,6 +1855,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
 
 static int
 qla1280_load_firmware(struct scsi_qla_host *ha)
+	__must_hold(ha->host->host_lock)
 {
 	/* enter with host_lock taken */
 	int err;
@@ -2413,6 +2425,7 @@ qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
  */
 static int
 qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
+	__must_hold(ha->host->host_lock)
 {
 	struct device_reg __iomem *reg = ha->iobase;
 	int status = 0;
@@ -2538,6 +2551,7 @@ qla1280_poll(struct scsi_qla_host *ha)
  */
 static int
 qla1280_bus_reset(struct scsi_qla_host *ha, int bus)
+	__must_hold(ha->host->host_lock)
 {
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	uint16_t reset_delay;
@@ -2598,6 +2612,7 @@ qla1280_bus_reset(struct scsi_qla_host *ha, int bus)
  */
 static int
 qla1280_device_reset(struct scsi_qla_host *ha, int bus, int target)
+	__must_hold(ha->host->host_lock)
 {
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	int status;
@@ -2632,6 +2647,7 @@ qla1280_device_reset(struct scsi_qla_host *ha, int bus, int target)
  */
 static int
 qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle)
+	__must_hold(ha->host->host_lock)
 {
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	unsigned int bus, target, lun;
@@ -3749,6 +3765,7 @@ qla1280_error_entry(struct scsi_qla_host *ha, struct response *pkt,
  */
 static int
 qla1280_abort_isp(struct scsi_qla_host *ha)
+	__must_hold(ha->host->host_lock)
 {
 	struct device_reg __iomem *reg = ha->iobase;
 	struct srb *sp;
@@ -3881,6 +3898,7 @@ qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus)
 static void
 qla1280_get_target_parameters(struct scsi_qla_host *ha,
 			      struct scsi_device *device)
+	__must_hold(ha->host->host_lock)
 {
 	uint16_t mb[MAILBOX_REGISTER_COUNT];
 	int bus, target, lun;

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

* [PATCH v3 48/57] scsi: qla2xxx: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (46 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 47/57] scsi: qla1280: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 49/57] scsi: qla4xxx: " Bart Van Assche
                   ` (8 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Nilesh Javali,
	GR-QLogic-Storage-Upstream, James E.J. Bottomley

Make several code blocks with conditional locking compatible with
thread-safety analysis. Annotate functions that perform conditional
locking with __no_context_analysis. No functionality has been changed.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/qla2xxx/Makefile     |  3 +++
 drivers/scsi/qla2xxx/qla_nx.c     |  2 ++
 drivers/scsi/qla2xxx/qla_target.c | 29 ++++++++++++++++++-----------
 drivers/scsi/qla2xxx/qla_tmpl.c   |  1 +
 4 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index cbc1303e761e..095657510cc3 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
 		qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
 		qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o \
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 298c060c1292..1950583c5734 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -431,6 +431,7 @@ static int qla82xx_crb_win_lock(struct qla_hw_data *ha)
 
 int
 qla82xx_wr_32(struct qla_hw_data *ha, ulong off_in, u32 data)
+	__context_unsafe(conditional locking)
 {
 	void __iomem *off;
 	unsigned long flags = 0;
@@ -461,6 +462,7 @@ qla82xx_wr_32(struct qla_hw_data *ha, ulong off_in, u32 data)
 
 int
 qla82xx_rd_32(struct qla_hw_data *ha, ulong off_in)
+	__context_unsafe(conditional locking)
 {
 	void __iomem *off;
 	unsigned long flags = 0;
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index e47da45e93a0..687ffd4bfdce 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -383,11 +383,13 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
 			    vha->vp_idx, entry->vp_index);
 			break;
 		}
-		if (!ha_locked)
+		if (!ha_locked) {
 			spin_lock_irqsave(&host->hw->hardware_lock, flags);
-		qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio);
-		if (!ha_locked)
+			qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio);
 			spin_unlock_irqrestore(&host->hw->hardware_lock, flags);
+		} else {
+			qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio);
+		}
 		break;
 	}
 
@@ -3774,6 +3776,7 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair,
  */
 void qlt_send_term_exchange(struct qla_qpair *qpair,
 	struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked)
+	__context_unsafe(conditional locking)
 {
 	struct scsi_qla_host *vha;
 	unsigned long flags = 0;
@@ -6727,11 +6730,13 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair,
 	if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
 		return 0;
 
-	if (!ha_locked)
+	if (!ha_locked) {
 		spin_lock_irqsave(&ha->hardware_lock, flags);
-	qlt_send_busy(qpair, atio, qla_sam_status);
-	if (!ha_locked)
+		qlt_send_busy(qpair, atio, qla_sam_status);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	} else {
+		qlt_send_busy(qpair, atio, qla_sam_status);
+	}
 
 	return 1;
 }
@@ -6740,6 +6745,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair,
 /* called via callback from qla2xxx */
 static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
 	struct atio_from_isp *atio, uint8_t ha_locked)
+	__context_unsafe(conditional locking)
 {
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
@@ -6766,12 +6772,13 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
 			    "qla_target(%d): ATIO_TYPE7 "
 			    "received with UNKNOWN exchange address, "
 			    "sending QUEUE_FULL\n", vha->vp_idx);
-			if (!ha_locked)
+			if (!ha_locked) {
 				spin_lock_irqsave(&ha->hardware_lock, flags);
-			qlt_send_busy(ha->base_qpair, atio, qla_sam_status);
-			if (!ha_locked)
-				spin_unlock_irqrestore(&ha->hardware_lock,
-				    flags);
+				qlt_send_busy(ha->base_qpair, atio, qla_sam_status);
+				spin_unlock_irqrestore(&ha->hardware_lock, flags);
+			} else {
+				qlt_send_busy(ha->base_qpair, atio, qla_sam_status);
+			}
 			break;
 		}
 
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
index b0a74b036cf4..f31bd7aeb8dc 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -1004,6 +1004,7 @@ qla27xx_fwdt_template_valid(void *p)
 
 void
 qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
+	__context_unsafe(conditional locking)
 {
 	ulong flags = 0;
 

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

* [PATCH v3 49/57] scsi: qla4xxx: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (47 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 48/57] scsi: qla2xxx: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:25   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 50/57] scsi: ufs: " Bart Van Assche
                   ` (7 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Nilesh Javali,
	Manish Rangankar, GR-QLogic-Storage-Upstream,
	James E.J. Bottomley

Annotate the functions that perform conditional locking with
__no_context_analysis.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/qla4xxx/Makefile | 3 +++
 drivers/scsi/qla4xxx/ql4_nx.c | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile
index 1f8a9096c744..2178d139f3ca 100644
--- a/drivers/scsi/qla4xxx/Makefile
+++ b/drivers/scsi/qla4xxx/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
+
+CONTEXT_ANALYSIS := y
+
 qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \
 		ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o ql4_bsg.o ql4_83xx.o
 
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index f7340cfc990a..513e9e95c888 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -406,6 +406,7 @@ void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha)
 
 void
 qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
+	__context_unsafe(conditional locking)
 {
 	unsigned long flags = 0;
 	int rv;
@@ -429,6 +430,7 @@ qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
 }
 
 uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
+	__context_unsafe(conditional locking)
 {
 	unsigned long flags = 0;
 	int rv;

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

* [PATCH v3 50/57] scsi: ufs: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (48 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 49/57] scsi: qla4xxx: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:19   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
                   ` (6 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley,
	Can Guo, Bean Huo, Peter Wang, Avri Altman, Ajay Neeli,
	Sai Krishna Potthuri

Annotate functions that modify the state of a synchronization object.
Remove the struct semaphore annotations because lock context annotations
are not supported for semaphores.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/ufs/core/Makefile      |  2 ++
 drivers/ufs/core/ufs-debugfs.c |  8 ++++++--
 drivers/ufs/core/ufshcd.c      | 14 ++++++++++++++
 drivers/ufs/host/Makefile      |  2 ++
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/ufs/core/Makefile b/drivers/ufs/core/Makefile
index ce7d16d2cf35..67ab9ffbdf5d 100644
--- a/drivers/ufs/core/Makefile
+++ b/drivers/ufs/core/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_UFSHCD)		+= ufshcd-core.o
 ufshcd-core-y				+= ufshcd.o ufs-sysfs.o ufs-mcq.o ufs-txeq.o
 ufshcd-core-$(CONFIG_RPMB)		+= ufs-rpmb.o
diff --git a/drivers/ufs/core/ufs-debugfs.c b/drivers/ufs/core/ufs-debugfs.c
index e3dd81d6fe82..814816810388 100644
--- a/drivers/ufs/core/ufs-debugfs.c
+++ b/drivers/ufs/core/ufs-debugfs.c
@@ -65,8 +65,10 @@ static int ee_usr_mask_get(void *data, u64 *val)
 	return 0;
 }
 
+token_context_lock(ufs_debugfs);
+
 static int ufs_debugfs_get_user_access(struct ufs_hba *hba)
-__acquires(&hba->host_sem)
+	__cond_acquires(0, ufs_debugfs)
 {
 	down(&hba->host_sem);
 	if (!ufshcd_is_user_access_allowed(hba)) {
@@ -74,14 +76,16 @@ __acquires(&hba->host_sem)
 		return -EBUSY;
 	}
 	ufshcd_rpm_get_sync(hba);
+	__acquire(ufs_debugfs);
 	return 0;
 }
 
 static void ufs_debugfs_put_user_access(struct ufs_hba *hba)
-__releases(&hba->host_sem)
+	__releases(ufs_debugfs)
 {
 	ufshcd_rpm_put_sync(hba);
 	up(&hba->host_sem);
+	__release(ufs_debugfs);
 }
 
 static int ee_usr_mask_set(void *data, u64 val)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 1a5a851d43b2..17fff36222cf 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -1353,6 +1353,8 @@ static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba,
  * On failure, all acquired locks are released and the tagset is unquiesced.
  */
 int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
+	__cond_acquires(0, &hba->host->scan_mutex)
+	__cond_acquires(0, &hba->clk_scaling_lock)
 {
 	int ret = 0;
 
@@ -1377,6 +1379,8 @@ int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
  * This function resumes command submissions.
  */
 void ufshcd_resume_command_processing(struct ufs_hba *hba)
+	__releases(&hba->clk_scaling_lock)
+	__releases(&hba->host->scan_mutex)
 {
 	up_write(&hba->clk_scaling_lock);
 	blk_mq_unquiesce_tagset(&hba->host->tag_set);
@@ -1446,6 +1450,9 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, u32 target_gear, bool scale_up
  * Return: 0 upon success; -EBUSY upon timeout.
  */
 static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
+	__cond_acquires(0, &hba->host->scan_mutex)
+	__cond_acquires(0, &hba->wb_mutex)
+	__cond_acquires(0, &hba->clk_scaling_lock)
 {
 	int ret = 0;
 	/*
@@ -1475,6 +1482,9 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us)
 }
 
 static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err)
+	__releases(&hba->clk_scaling_lock)
+	__releases(&hba->wb_mutex)
+	__releases(&hba->host->scan_mutex)
 {
 	up_write(&hba->clk_scaling_lock);
 	mutex_unlock(&hba->wb_mutex);
@@ -3282,6 +3292,8 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 }
 
 static void ufshcd_dev_man_lock(struct ufs_hba *hba)
+	__acquires(&hba->dev_cmd.lock)
+	__acquires_shared(&hba->clk_scaling_lock)
 {
 	ufshcd_hold(hba);
 	mutex_lock(&hba->dev_cmd.lock);
@@ -3289,6 +3301,8 @@ static void ufshcd_dev_man_lock(struct ufs_hba *hba)
 }
 
 static void ufshcd_dev_man_unlock(struct ufs_hba *hba)
+	__releases_shared(&hba->clk_scaling_lock)
+	__releases(&hba->dev_cmd.lock)
 {
 	up_read(&hba->clk_scaling_lock);
 	mutex_unlock(&hba->dev_cmd.lock);
diff --git a/drivers/ufs/host/Makefile b/drivers/ufs/host/Makefile
index 65d8bb23ab7b..7d8db67eb23c 100644
--- a/drivers/ufs/host/Makefile
+++ b/drivers/ufs/host/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
 obj-$(CONFIG_SCSI_UFS_CDNS_PLATFORM) += cdns-pltfrm.o

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

* [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (49 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 50/57] scsi: ufs: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:23   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 52/57] scsi: smartpqi: Enable " Bart Van Assche
                   ` (5 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Lee Duncan, Chris Leech,
	Mike Christie, James E.J. Bottomley

Document locking requirements with __must_hold().

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_transport_iscsi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 8aa76f813bcd..ade69c7b65b4 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -2243,6 +2243,7 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
 static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
 					 struct iscsi_endpoint *ep,
 					 bool is_active)
+	__must_hold(&conn->ep_mutex)
 {
 	/* Check if this was a conn error and the kernel took ownership */
 	spin_lock_irq(&conn->lock);

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

* [PATCH v3 52/57] scsi: smartpqi: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (50 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:22   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 53/57] scsi: snic: " Bart Van Assche
                   ` (4 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Tomas Henzl, Don Brace,
	James E.J. Bottomley

Document locking requirements with __acquires(), __releases() and
__must_hold(). Annotate functions that perform conditional locking with
__no_context_analysis.

Cc: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/smartpqi/Makefile        |  3 ++
 drivers/scsi/smartpqi/smartpqi_init.c | 67 ++++++++++++++++++++++-----
 2 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/smartpqi/Makefile b/drivers/scsi/smartpqi/Makefile
index 28985e508b5c..71db5cd96284 100644
--- a/drivers/scsi/smartpqi/Makefile
+++ b/drivers/scsi/smartpqi/Makefile
@@ -1,3 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o
 smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index 140e8a6addbe..ba0d248efc8f 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -97,8 +97,12 @@ static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info,
 	struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
 	struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device,
 	struct pqi_scsi_dev_raid_map_data *rmd);
-static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info);
-static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info);
+static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info)
+	__acquires(&ctrl_info->scan_mutex)
+	__acquires(&ctrl_info->lun_reset_mutex);
+static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info)
+	__releases(&ctrl_info->lun_reset_mutex)
+	__releases(&ctrl_info->scan_mutex);
 static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int delay_secs);
 static void pqi_host_setup_buffer(struct pqi_ctrl_info *ctrl_info, struct pqi_host_memory_descriptor *host_memory_descriptor, u32 total_size, u32 min_size);
 static void pqi_host_free_buffer(struct pqi_ctrl_info *ctrl_info, struct pqi_host_memory_descriptor *host_memory_descriptor);
@@ -312,12 +316,14 @@ static inline void pqi_save_fw_triage_setting(struct pqi_ctrl_info *ctrl_info, b
 }
 
 static inline void pqi_ctrl_block_scan(struct pqi_ctrl_info *ctrl_info)
+	__acquires(ctrl_info->scan_mutex)
 {
 	ctrl_info->scan_blocked = true;
 	mutex_lock(&ctrl_info->scan_mutex);
 }
 
 static inline void pqi_ctrl_unblock_scan(struct pqi_ctrl_info *ctrl_info)
+	__releases(ctrl_info->scan_mutex)
 {
 	ctrl_info->scan_blocked = false;
 	mutex_unlock(&ctrl_info->scan_mutex);
@@ -329,11 +335,13 @@ static inline bool pqi_ctrl_scan_blocked(struct pqi_ctrl_info *ctrl_info)
 }
 
 static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info)
+	__acquires(ctrl_info->lun_reset_mutex)
 {
 	mutex_lock(&ctrl_info->lun_reset_mutex);
 }
 
 static inline void pqi_ctrl_unblock_device_reset(struct pqi_ctrl_info *ctrl_info)
+	__releases(ctrl_info->lun_reset_mutex)
 {
 	mutex_unlock(&ctrl_info->lun_reset_mutex);
 }
@@ -436,11 +444,13 @@ static inline bool pqi_device_offline(struct pqi_scsi_dev *device)
 }
 
 static inline void pqi_ctrl_ofa_start(struct pqi_ctrl_info *ctrl_info)
+	__acquires(ctrl_info->ofa_mutex)
 {
 	mutex_lock(&ctrl_info->ofa_mutex);
 }
 
 static inline void pqi_ctrl_ofa_done(struct pqi_ctrl_info *ctrl_info)
+	__releases(ctrl_info->ofa_mutex)
 {
 	mutex_unlock(&ctrl_info->ofa_mutex);
 }
@@ -2305,6 +2315,8 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
 	 * requests before removal.
 	 */
 	if (pqi_ofa_in_progress(ctrl_info)) {
+		/* What guarantees that &ctrl_info->lun_reset_mutex is held here? */
+		__acquire(&ctrl_info->lun_reset_mutex);
 		list_for_each_entry_safe(device, next, &delete_list, delete_list_entry)
 			if (pqi_is_device_added(device))
 				pqi_device_remove_start(device);
@@ -3667,6 +3679,8 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info)
 		pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
 		rc = pqi_ofa_ctrl_restart(ctrl_info, delay_secs);
 		pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory);
+		/* What guarantees that &ctrl_info->ofa_mutex is held here? */
+		__acquire(&ctrl_info->ofa_mutex);
 		pqi_ctrl_ofa_done(ctrl_info);
 		dev_info(&ctrl_info->pci_dev->dev,
 				"Online Firmware Activation: %s\n",
@@ -3678,6 +3692,10 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info)
 		if (ctrl_info->soft_reset_handshake_supported)
 			pqi_clear_soft_reset_status(ctrl_info);
 		pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory);
+		/* What guarantees that these mutexes are held here? */
+		__acquire(&ctrl_info->lun_reset_mutex);
+		__acquire(&ctrl_info->ofa_mutex);
+		__acquire(&ctrl_info->scan_mutex);
 		pqi_ctrl_ofa_done(ctrl_info);
 		pqi_ofa_ctrl_unquiesce(ctrl_info);
 		break;
@@ -3688,6 +3706,10 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info)
 			"unexpected Online Firmware Activation reset status: 0x%x\n",
 			reset_status);
 		pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory);
+		/* What guarantees that these mutexes are held here? */
+		__acquire(&ctrl_info->lun_reset_mutex);
+		__acquire(&ctrl_info->ofa_mutex);
+		__acquire(&ctrl_info->scan_mutex);
 		pqi_ctrl_ofa_done(ctrl_info);
 		pqi_ofa_ctrl_unquiesce(ctrl_info);
 		pqi_take_ctrl_offline(ctrl_info, PQI_OFA_RESPONSE_TIMEOUT);
@@ -3695,25 +3717,32 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info)
 	}
 }
 
-static void pqi_ofa_memory_alloc_worker(struct work_struct *work)
+static inline struct pqi_ctrl_info *alloc_work_to_ctrl_info(struct work_struct *work)
 {
-	struct pqi_ctrl_info *ctrl_info;
+	return container_of(work, struct pqi_ctrl_info, ofa_memory_alloc_work);
+}
 
-	ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_memory_alloc_work);
+static void pqi_ofa_memory_alloc_worker(struct work_struct *work)
+	__acquires(&alloc_work_to_ctrl_info(work)->ofa_mutex)
+{
+	struct pqi_ctrl_info *ctrl_info = alloc_work_to_ctrl_info(work);
 
 	pqi_ctrl_ofa_start(ctrl_info);
 	pqi_host_setup_buffer(ctrl_info, &ctrl_info->ofa_memory, ctrl_info->ofa_bytes_requested, ctrl_info->ofa_bytes_requested);
 	pqi_host_memory_update(ctrl_info, &ctrl_info->ofa_memory, PQI_VENDOR_GENERAL_OFA_MEMORY_UPDATE);
 }
 
-static void pqi_ofa_quiesce_worker(struct work_struct *work)
+static inline struct pqi_ctrl_info *quiesce_work_to_ctrl_info(struct work_struct *work)
 {
-	struct pqi_ctrl_info *ctrl_info;
-	struct pqi_event *event;
-
-	ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_quiesce_work);
+	return container_of(work, struct pqi_ctrl_info, ofa_quiesce_work);
+}
 
-	event = &ctrl_info->events[pqi_event_type_to_event_index(PQI_EVENT_TYPE_OFA)];
+static void pqi_ofa_quiesce_worker(struct work_struct *work)
+	__acquires(&quiesce_work_to_ctrl_info(work)->scan_mutex)
+	__acquires(&quiesce_work_to_ctrl_info(work)->lun_reset_mutex)
+{
+	struct pqi_ctrl_info *ctrl_info = quiesce_work_to_ctrl_info(work);
+	struct pqi_event *event = &ctrl_info->events[pqi_event_type_to_event_index(PQI_EVENT_TYPE_OFA)];
 
 	pqi_ofa_ctrl_quiesce(ctrl_info);
 	pqi_acknowledge_event(ctrl_info, event);
@@ -3744,6 +3773,8 @@ static bool pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info,
 			"received Online Firmware Activation cancel request: reason: %u\n",
 			ctrl_info->ofa_cancel_reason);
 		pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory);
+		/* What guarantees that &ctrl_info->ofa_mutex is held here? */
+		__acquire(&ctrl_info->ofa_mutex);
 		pqi_ctrl_ofa_done(ctrl_info);
 		break;
 	default:
@@ -8888,6 +8919,8 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info)
 	}
 
 	if (pqi_ofa_in_progress(ctrl_info)) {
+		/* What guarantees that &ctrl_info->scan_mutex is held here? */
+		__acquire(&ctrl_info->scan_mutex);
 		pqi_ctrl_unblock_scan(ctrl_info);
 		if (ctrl_info->ctrl_logging_supported) {
 			if (!ctrl_info->ctrl_log_memory.host_memory)
@@ -9648,7 +9681,11 @@ static inline enum bmic_flush_cache_shutdown_event pqi_get_flush_cache_shutdown_
 	return SUSPEND;
 }
 
+#define TO_CTRL_INFO(dev) ((struct pqi_ctrl_info *)pci_get_drvdata(to_pci_dev(dev)))
+
 static int pqi_suspend_or_freeze(struct device *dev, bool suspend)
+	__acquires(&TO_CTRL_INFO(dev)->scan_mutex)
+	__acquires(&TO_CTRL_INFO(dev)->lun_reset_mutex)
 {
 	struct pci_dev *pci_dev;
 	struct pqi_ctrl_info *ctrl_info;
@@ -9682,11 +9719,15 @@ static int pqi_suspend_or_freeze(struct device *dev, bool suspend)
 }
 
 static __maybe_unused int pqi_suspend(struct device *dev)
+	__acquires(&TO_CTRL_INFO(dev)->scan_mutex)
+	__acquires(&TO_CTRL_INFO(dev)->lun_reset_mutex)
 {
 	return pqi_suspend_or_freeze(dev, true);
 }
 
 static int pqi_resume_or_restore(struct device *dev)
+	__cond_releases(0, &TO_CTRL_INFO(dev)->lun_reset_mutex)
+	__cond_releases(0, &TO_CTRL_INFO(dev)->scan_mutex)
 {
 	int rc;
 	struct pci_dev *pci_dev;
@@ -9710,11 +9751,15 @@ static int pqi_resume_or_restore(struct device *dev)
 }
 
 static int pqi_freeze(struct device *dev)
+	__acquires(&TO_CTRL_INFO(dev)->scan_mutex)
+	__acquires(&TO_CTRL_INFO(dev)->lun_reset_mutex)
 {
 	return pqi_suspend_or_freeze(dev, false);
 }
 
 static int pqi_thaw(struct device *dev)
+	__cond_releases(0, &TO_CTRL_INFO(dev)->lun_reset_mutex)
+	__cond_releases(0, &TO_CTRL_INFO(dev)->scan_mutex)
 {
 	int rc;
 	struct pci_dev *pci_dev;

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

* [PATCH v3 53/57] scsi: snic: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (51 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 52/57] scsi: smartpqi: Enable " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 54/57] scsi: sym53c8xx_2: " Bart Van Assche
                   ` (3 subsequent siblings)
  56 siblings, 0 replies; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Narsimhulu Musini,
	Karan Tilak Kumar, Sesidhar Baddela, James E.J. Bottomley

Set the CONTEXT_ANALYSIS variable in the Makefile.

Acked-by: Narsimhulu Musini <nmusini@cisco.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/snic/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/snic/Makefile b/drivers/scsi/snic/Makefile
index 41546e3cb701..b12563cb174d 100644
--- a/drivers/scsi/snic/Makefile
+++ b/drivers/scsi/snic/Makefile
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_SNIC) += snic.o
 
 snic-y := \

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

* [PATCH v3 54/57] scsi: sym53c8xx_2: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (52 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 53/57] scsi: snic: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:27   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly Bart Van Assche
                   ` (2 subsequent siblings)
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Matthew Wilcox,
	James E.J. Bottomley

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/sym53c8xx_2/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/sym53c8xx_2/Makefile b/drivers/scsi/sym53c8xx_2/Makefile
index 0751e2a0cd82..c28fb2b65622 100644
--- a/drivers/scsi/sym53c8xx_2/Makefile
+++ b/drivers/scsi/sym53c8xx_2/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 # Makefile for the NCR/SYMBIOS/LSI 53C8XX PCI SCSI controllers driver.
 
+CONTEXT_ANALYSIS := y
+
 sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_nvram.o
 obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx.o

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

* [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (53 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 54/57] scsi: sym53c8xx_2: " Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:22   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 56/57] scsi: core: Enable lock context analysis Bart Van Assche
  2026-07-30 22:45 ` [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock Bart Van Assche
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

In the functions scsi_probe_and_add_lun(), scsi_sequential_lun_scan(),
scsi_report_lun_scan() and __scsi_scan_target() the SCSI host pointer is
derived from the SCSI target pointer. Pass the SCSI host pointer
directly. This patch prepares for enabling lock context analysis. No
functionality has been changed.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/scsi_scan.c | 46 ++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index e27da038603a..a8994c07d415 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1169,6 +1169,7 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
 
 /**
  * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
+ * @shost:      SCSI host pointer
  * @starget:	pointer to target device structure
  * @lun:	LUN of target device
  * @bflagsp:	store bflags here if not NULL
@@ -1188,7 +1189,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
  *         attached at the LUN
  *   - SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
  **/
-static int scsi_probe_and_add_lun(struct scsi_target *starget,
+static int scsi_probe_and_add_lun(struct Scsi_Host *shost,
+				  struct scsi_target *starget,
 				  u64 lun, blist_flags_t *bflagsp,
 				  struct scsi_device **sdevp,
 				  enum scsi_scan_mode rescan,
@@ -1198,7 +1200,6 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
 	unsigned char *result;
 	blist_flags_t bflags;
 	int res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
 
 	/*
 	 * The rescan flag is used as an optimization, the first scan of a
@@ -1334,6 +1335,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
 
 /**
  * scsi_sequential_lun_scan - sequentially scan a SCSI target
+ * @shost:      SCSI host pointer
  * @starget:	pointer to target structure to scan
  * @bflags:	black/white list flag for LUN 0
  * @scsi_level: Which version of the standard does this device adhere to
@@ -1346,13 +1348,13 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
  *
  *     Modifies sdevscan->lun.
  **/
-static void scsi_sequential_lun_scan(struct scsi_target *starget,
+static void scsi_sequential_lun_scan(struct Scsi_Host *shost,
+				     struct scsi_target *starget,
 				     blist_flags_t bflags, int scsi_level,
 				     enum scsi_scan_mode rescan)
 {
 	uint max_dev_lun;
 	u64 sparse_lun, lun;
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
 
 	SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget,
 		"scsi scan: Sequential scan\n"));
@@ -1412,8 +1414,8 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
 	 * sparse_lun.
 	 */
 	for (lun = 1; lun < max_dev_lun; ++lun)
-		if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan,
-					    NULL) != SCSI_SCAN_LUN_PRESENT) &&
+		if (scsi_probe_and_add_lun(shost, starget, lun, NULL, NULL,
+				rescan, NULL) != SCSI_SCAN_LUN_PRESENT &&
 		    !sparse_lun)
 			return;
 }
@@ -1438,8 +1440,9 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
  *     0: scan completed (or no memory, so further scanning is futile)
  *     1: could not scan with REPORT LUN
  **/
-static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags,
-				enum scsi_scan_mode rescan)
+static int scsi_report_lun_scan(struct Scsi_Host *shost,
+			struct scsi_target *starget, blist_flags_t bflags,
+			enum scsi_scan_mode rescan)
 {
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 	unsigned int length;
@@ -1448,7 +1451,6 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
 	int result;
 	struct scsi_lun *lunp, *lun_data;
 	struct scsi_device *sdev;
-	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
 	struct scsi_failure failure_defs[] = {
 		{
 			.sense = UNIT_ATTENTION,
@@ -1594,7 +1596,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
 		} else {
 			int res;
 
-			res = scsi_probe_and_add_lun(starget,
+			res = scsi_probe_and_add_lun(shost, starget,
 				lun, NULL, NULL, rescan, NULL);
 			if (res == SCSI_SCAN_NO_RESPONSE) {
 				/*
@@ -1641,7 +1643,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
 		scsi_complete_async_scans();
 
 	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
-		scsi_probe_and_add_lun(starget, lun, NULL, &sdev,
+		scsi_probe_and_add_lun(shost, starget, lun, NULL, &sdev,
 				       SCSI_SCAN_RESCAN, hostdata);
 		scsi_autopm_put_host(shost);
 	}
@@ -1763,10 +1765,10 @@ int scsi_rescan_device(struct scsi_device *sdev)
 }
 EXPORT_SYMBOL(scsi_rescan_device);
 
-static void __scsi_scan_target(struct device *parent, unsigned int channel,
-		unsigned int id, u64 lun, enum scsi_scan_mode rescan)
+static void __scsi_scan_target(struct Scsi_Host *shost, struct device *parent,
+			       unsigned int channel, unsigned int id, u64 lun,
+			       enum scsi_scan_mode rescan)
 {
-	struct Scsi_Host *shost = dev_to_shost(parent);
 	blist_flags_t bflags = 0;
 	int res;
 	struct scsi_target *starget;
@@ -1786,7 +1788,8 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
 		/*
 		 * Scan for a specific host/chan/id/lun.
 		 */
-		scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL);
+		scsi_probe_and_add_lun(shost, starget, lun, NULL, NULL, rescan,
+				       NULL);
 		goto out_reap;
 	}
 
@@ -1794,14 +1797,15 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
 	 * Scan LUN 0, if there is some response, scan further. Ideally, we
 	 * would not configure LUN 0 until all LUNs are scanned.
 	 */
-	res = scsi_probe_and_add_lun(starget, 0, &bflags, NULL, rescan, NULL);
+	res = scsi_probe_and_add_lun(shost, starget, 0, &bflags, NULL, rescan,
+				     NULL);
 	if (res == SCSI_SCAN_LUN_PRESENT || res == SCSI_SCAN_TARGET_PRESENT) {
-		if (scsi_report_lun_scan(starget, bflags, rescan) != 0)
+		if (scsi_report_lun_scan(shost, starget, bflags, rescan) != 0)
 			/*
 			 * The REPORT LUN did not scan the target,
 			 * do a sequential scan.
 			 */
-			scsi_sequential_lun_scan(starget, bflags,
+			scsi_sequential_lun_scan(shost, starget, bflags,
 						 starget->scsi_level, rescan);
 	}
 
@@ -1851,7 +1855,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
 		scsi_complete_async_scans();
 
 	if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
-		__scsi_scan_target(parent, channel, id, lun, rescan);
+		__scsi_scan_target(shost, parent, channel, id, lun, rescan);
 		scsi_autopm_put_host(shost);
 	}
 	mutex_unlock(&shost->scan_mutex);
@@ -1882,11 +1886,11 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
 				order_id = shost->max_id - id - 1;
 			else
 				order_id = id;
-			__scsi_scan_target(&shost->shost_gendev, channel,
+			__scsi_scan_target(shost, &shost->shost_gendev, channel,
 					order_id, lun, rescan);
 		}
 	else
-		__scsi_scan_target(&shost->shost_gendev, channel,
+		__scsi_scan_target(shost, &shost->shost_gendev, channel,
 				id, lun, rescan);
 }
 

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

* [PATCH v3 56/57] scsi: core: Enable lock context analysis
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (54 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:36   ` sashiko-bot
  2026-07-30 22:45 ` [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock Bart Van Assche
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, James E.J. Bottomley

Document which functions expect that shost->scan_mutex is held. Inform
the compiler about synchronization object aliases with __assume_ctx_lock().
Enable lock context analysis for the SCSI core and also for all drivers
in the drivers/scsi/ directory.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/Makefile                | 1 +
 drivers/scsi/device_handler/Makefile | 3 +++
 drivers/scsi/scsi_scan.c             | 5 +++++
 include/scsi/scsi_host.h             | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 842c254bb226..a1fbdf4b0705 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -14,6 +14,7 @@
 # satisfy certain initialization assumptions in the SCSI layer.
 # *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
 
+CONTEXT_ANALYSIS := y
 
 CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
 
diff --git a/drivers/scsi/device_handler/Makefile b/drivers/scsi/device_handler/Makefile
index 0a603aefd2bb..5aa282a63e24 100644
--- a/drivers/scsi/device_handler/Makefile
+++ b/drivers/scsi/device_handler/Makefile
@@ -2,6 +2,9 @@
 #
 # SCSI Device Handler
 #
+
+CONTEXT_ANALYSIS := y
+
 obj-$(CONFIG_SCSI_DH_RDAC)	+= scsi_dh_rdac.o
 obj-$(CONFIG_SCSI_DH_HP_SW)	+= scsi_dh_hp_sw.o
 obj-$(CONFIG_SCSI_DH_EMC)	+= scsi_dh_emc.o
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a8994c07d415..8096ca51161b 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1195,6 +1195,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *shost,
 				  struct scsi_device **sdevp,
 				  enum scsi_scan_mode rescan,
 				  void *hostdata)
+	__must_hold(&shost->scan_mutex)
 {
 	struct scsi_device *sdev;
 	unsigned char *result;
@@ -1352,6 +1353,7 @@ static void scsi_sequential_lun_scan(struct Scsi_Host *shost,
 				     struct scsi_target *starget,
 				     blist_flags_t bflags, int scsi_level,
 				     enum scsi_scan_mode rescan)
+	__must_hold(&shost->scan_mutex)
 {
 	uint max_dev_lun;
 	u64 sparse_lun, lun;
@@ -1443,6 +1445,7 @@ static void scsi_sequential_lun_scan(struct Scsi_Host *shost,
 static int scsi_report_lun_scan(struct Scsi_Host *shost,
 			struct scsi_target *starget, blist_flags_t bflags,
 			enum scsi_scan_mode rescan)
+	__must_hold(&shost->scan_mutex)
 {
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 	unsigned int length;
@@ -1768,6 +1771,7 @@ EXPORT_SYMBOL(scsi_rescan_device);
 static void __scsi_scan_target(struct Scsi_Host *shost, struct device *parent,
 			       unsigned int channel, unsigned int id, u64 lun,
 			       enum scsi_scan_mode rescan)
+	__must_hold(&shost->scan_mutex)
 {
 	blist_flags_t bflags = 0;
 	int res;
@@ -1865,6 +1869,7 @@ EXPORT_SYMBOL(scsi_scan_target);
 static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
 			      unsigned int id, u64 lun,
 			      enum scsi_scan_mode rescan)
+	__must_hold(&shost->scan_mutex)
 {
 	uint order_id;
 
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 7e2011830ba4..2bbe7cb0060b 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -534,6 +534,8 @@ struct scsi_host_template {
 		enum scsi_qc_status rc;					\
 									\
 		spin_lock_irqsave(shost->host_lock, irq_flags);		\
+		/* Tell the compiler that cmd->device->host == shost. */\
+		__assume_ctx_lock(cmd->device->host->host_lock);	\
 		rc = func_name##_lck(cmd);				\
 		spin_unlock_irqrestore(shost->host_lock, irq_flags);	\
 		return rc;						\

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

* [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock
  2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
                   ` (55 preceding siblings ...)
  2026-07-30 22:45 ` [PATCH v3 56/57] scsi: core: Enable lock context analysis Bart Van Assche
@ 2026-07-30 22:45 ` Bart Van Assche
  2026-07-30 23:32   ` sashiko-bot
  56 siblings, 1 reply; 90+ messages in thread
From: Bart Van Assche @ 2026-07-30 22:45 UTC (permalink / raw)
  To: Martin K . Petersen
  Cc: Marco Elver, linux-scsi, Bart Van Assche, Jianzhou Zhao,
	James E.J. Bottomley, Kashyap Desai, Sumit Saxena, Shivasharan S,
	Chandrakanth patil, Sathya Prakash, Sreekanth Reddy,
	Suganath Prabu Subramani, Ranjan Kumar, Nilesh Javali,
	Manish Rangankar, GR-QLogic-Storage-Upstream

Some but not all SCSI host state changes are protected with the SCSI
host lock. Annotate the SCSI host state with __guarded_by(host_lock),
protect all SCSI host state changes with the SCSI host lock and use
READ_ONCE() for all SCSI host state reads. This patch prevents that
KCSAN complains about data races when accessing the SCSI host state.

Reported-by: Jianzhou Zhao <luckd0g@163.com>
Closes: https://lore.kernel.org/all/36d59d0e.6db0.19cdbeee01b.Coremail.luckd0g@163.com/
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 drivers/scsi/hosts.c                      | 13 ++++++++-----
 drivers/scsi/megaraid/megaraid_sas_base.c |  2 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c      |  2 +-
 drivers/scsi/qla4xxx/ql4_os.c             |  6 ++----
 drivers/scsi/scsi_lib.c                   |  3 +--
 drivers/scsi/scsi_sysfs.c                 |  7 ++++---
 include/scsi/scsi_host.h                  | 23 ++++++++++++++++-------
 7 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index d512080268af..2b9fd76fb435 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -276,7 +276,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
 	if (error)
 		goto out_disable_runtime_pm;
 
-	scsi_host_set_state(shost, SHOST_RUNNING);
+	scoped_guard(spinlock_irq, shost->host_lock)
+		scsi_host_set_state(shost, SHOST_RUNNING);
 	get_device(shost->shost_gendev.parent);
 
 	device_enable_async_suspend(&shost->shost_dev);
@@ -350,6 +351,7 @@ EXPORT_SYMBOL(scsi_add_host_with_dma);
 static void scsi_host_dev_release(struct device *dev)
 {
 	struct Scsi_Host *shost = dev_to_shost(dev);
+	enum scsi_host_state host_state = scsi_get_host_state(shost);
 	struct device *parent = dev->parent;
 
 	/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
@@ -362,7 +364,7 @@ static void scsi_host_dev_release(struct device *dev)
 	if (shost->work_q)
 		destroy_workqueue(shost->work_q);
 
-	if (shost->shost_state == SHOST_CREATED) {
+	if (host_state == SHOST_CREATED) {
 		/*
 		 * Free the shost_dev device name and remove the proc host dir
 		 * here if scsi_host_{alloc,put}() have been called but neither
@@ -378,7 +380,7 @@ static void scsi_host_dev_release(struct device *dev)
 
 	ida_free(&host_index_ida, shost->host_no);
 
-	if (shost->shost_state != SHOST_CREATED)
+	if (host_state != SHOST_CREATED)
 		put_device(parent);
 	kfree(shost);
 }
@@ -412,7 +414,8 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
 
 	shost->host_lock = &shost->default_lock;
 	spin_lock_init(shost->host_lock);
-	shost->shost_state = SHOST_CREATED;
+	scoped_guard(spinlock_init, shost->host_lock)
+		shost->shost_state = SHOST_CREATED;
 	INIT_LIST_HEAD(&shost->__devices);
 	INIT_LIST_HEAD(&shost->__targets);
 	INIT_LIST_HEAD(&shost->eh_abort_list);
@@ -598,7 +601,7 @@ EXPORT_SYMBOL(scsi_host_lookup);
  **/
 struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
 {
-	if ((shost->shost_state == SHOST_DEL) ||
+	if (scsi_get_host_state(shost) == SHOST_DEL ||
 		!get_device(&shost->shost_gendev))
 		return NULL;
 	return shost;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index ccefe5841a17..97a81a86db82 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3075,7 +3075,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
 
 	scmd_printk(KERN_INFO, scmd,
 		"SCSI host state: %d  SCSI host busy: %d  FW outstanding: %d\n",
-		scmd->device->host->shost_state,
+		scsi_get_host_state(scmd->device->host),
 		scsi_host_busy(scmd->device->host),
 		atomic_read(&instance->fw_outstanding));
 	/*
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index dea78688cc9b..0e12009a87f6 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -5472,7 +5472,7 @@ static enum scsi_qc_status scsih_qcmd(struct Scsi_Host *shost,
 	 * Avoid error handling escallation when device is disconnected
 	 */
 	if (handle == MPT3SAS_INVALID_DEVICE_HANDLE || sas_device_priv_data->block) {
-		if (scmd->device->host->shost_state == SHOST_RECOVERY &&
+		if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY &&
 		    scmd->cmnd[0] == TEST_UNIT_READY) {
 			scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
 			scsi_done(scmd);
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index d598ab4126f8..c9d9fc7c81fb 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -9411,11 +9411,9 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
  * This routine finds that if reset host is called in EH
  * scenario or from some application like sg_reset
  **/
-static int qla4xxx_is_eh_active(struct Scsi_Host *shost)
+static bool qla4xxx_is_eh_active(struct Scsi_Host *shost)
 {
-	if (shost->shost_state == SHOST_RECOVERY)
-		return 1;
-	return 0;
+	return scsi_get_host_state(shost) == SHOST_RECOVERY;
 }
 
 /**
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 22e2e3223440..bd592abf1f39 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1661,10 +1661,9 @@ static enum scsi_qc_status scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 		goto done;
 	}
 
-	if (unlikely(host->shost_state == SHOST_DEL)) {
+	if (scsi_get_host_state(host) == SHOST_DEL) {
 		cmd->result = (DID_NO_CONNECT << 16);
 		goto done;
-
 	}
 
 	trace_scsi_dispatch_cmd_start(cmd);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index dfc3559e7e04..9480432f650b 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -214,8 +214,9 @@ store_shost_state(struct device *dev, struct device_attribute *attr,
 	if (!state)
 		return -EINVAL;
 
-	if (scsi_host_set_state(shost, state))
-		return -EINVAL;
+	scoped_guard(spinlock_irq, shost->host_lock)
+		if (scsi_host_set_state(shost, state))
+			return -EINVAL;
 	return count;
 }
 
@@ -223,7 +224,7 @@ static ssize_t
 show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct Scsi_Host *shost = class_to_shost(dev);
-	const char *name = scsi_host_state_name(shost->shost_state);
+	const char *name = scsi_host_state_name(scsi_get_host_state(shost));
 
 	if (!name)
 		return -EINVAL;
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 2bbe7cb0060b..993628019916 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -729,7 +729,7 @@ struct Scsi_Host {
 	unsigned int  irq;
 	
 
-	enum scsi_host_state shost_state;
+	enum scsi_host_state shost_state __guarded_by(host_lock);
 
 	/* ldm bits */
 	struct device		shost_gendev, shost_dev;
@@ -787,11 +787,18 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
 	return container_of(dev, struct Scsi_Host, shost_gendev);
 }
 
+static inline enum scsi_host_state scsi_get_host_state(struct Scsi_Host *shost)
+{
+	return context_unsafe(READ_ONCE(shost->shost_state));
+}
+
 static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
 {
-	return shost->shost_state == SHOST_RECOVERY ||
-		shost->shost_state == SHOST_CANCEL_RECOVERY ||
-		shost->shost_state == SHOST_DEL_RECOVERY ||
+	enum scsi_host_state state = scsi_get_host_state(shost);
+
+	return state == SHOST_RECOVERY ||
+		state == SHOST_CANCEL_RECOVERY ||
+		state == SHOST_DEL_RECOVERY ||
 		shost->tmf_in_progress;
 }
 
@@ -837,8 +844,9 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
  **/
 static inline int scsi_host_scan_allowed(struct Scsi_Host *shost)
 {
-	return shost->shost_state == SHOST_RUNNING ||
-	       shost->shost_state == SHOST_RECOVERY;
+	enum scsi_host_state state = scsi_get_host_state(shost);
+
+	return state == SHOST_RUNNING || state == SHOST_RECOVERY;
 }
 
 extern void scsi_unblock_requests(struct Scsi_Host *);
@@ -942,6 +950,7 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
 	return shost->prot_guard_type;
 }
 
-extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state);
+int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
+	__must_hold(shost->host_lock);
 
 #endif /* _SCSI_SCSI_HOST_H */

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

* Re: [PATCH v3 19/57] scsi: bnx2fc: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 19/57] scsi: bnx2fc: " Bart Van Assche
@ 2026-07-30 23:01   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:01 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:
- [High] Unconditional evaluation of nested pointer chain in `__assume_ctx_lock()` causes a potential fatal NULL pointer dereference for standard SCSI commands.
--

--- Patch [19]: [PATCH v3 19/57] scsi: bnx2fc: Enable lock context analysis ---
commit 914539bc4256a83053d649d7450d8f075fb16ba8
Author: Bart Van Assche <bvanassche@acm.org>

scsi: bnx2fc: Enable lock context analysis
    
This patch enables context lock analysis by documenting locking requirements
and informing the compiler about lock aliases. It updates functions with
__must_hold() and __assume_ctx_lock() to track context around target locks.
It also standardizes an argument name in bnx2fc_process_seq_cleanup_compl().

> diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> index a5ecb87d5b2d7..a3670c48900ba 100644
> --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> @@ -880,6 +880,9 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe,
>  		return;
>  	}
>  
> +	/* Tell the compiler that there is an alias for tgt->tgt_lock. */
> +	__assume_ctx_lock(&io_req->cb_arg->aborted_io_req->tgt->tgt_lock);

[Severity: High]
Does this unconditionally evaluate io_req->cb_arg?

For standard SCSI commands, io_req->cb_arg is NULL.

Since the kernel is compiled with -fno-delete-null-pointer-checks, computing
the address of tgt_lock requires evaluating the intermediate pointers.

This means the compiler is highly likely to emit a memory load rather than
optimizing away the dead read, since it treats address 0 as valid.

Could this lead to a fatal NULL pointer dereference on every standard IO
completion processed by bnx2fc_process_cq_compl()?

It appears this annotation might belong solely inside the BNX2FC_SEQ_CLEANUP
case where cb_arg is known to be valid.

> +
>  	/* Timestamp IO completion time */
>  	cmd_type = io_req->cmd_type;
>

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

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

* Re: [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis
  2026-07-30 22:44 ` [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-07-30 23:01   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:01 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Medium] The `__context_unsafe(conditional locking)` annotation was applied to `resp_write_same` but missed on `resp_read_dt0` and `resp_write_dt0`, which use identical conditional locking logic.

Pre-existing issues:
- [High] The function `resp_write_same()` leaks a write lock on the data lock (`sip->macc_data_lck`) when `fetch_to_dev_buffer()` fails.
- [High] AB-BA deadlock between `sip->macc_meta_lck` and `sip->macc_data_lck` due to inconsistent lock acquisition order.
--

--- Patch [2]: [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis ---
commit ad9c0fb7632790d874892a1d6261443b39766d7d
Author: Bart Van Assche <bvanassche@acm.org>

scsi: scsi_debug: Prepare for enabling lock context analysis

Suppress lock context analysis for the functions that perform conditional
locking to prevent that the Clang thread-safety analyzer complains about
these functions. Remove incorrect __acquire() and __release() annotations.

> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 4a08f0cfae08d..cb6663e24c225 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c

[ ... ]

> @@ -5193,6 +5185,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
>  
>  static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num,
>  			   u32 ei_lba, bool unmap, bool ndob)
> +	__context_unsafe(conditional locking)
>  {
>  	struct scsi_device *sdp = scp->device;
>  	struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata;

[Severity: Medium]
Should drivers/scsi/scsi_debug.c:resp_read_dt0() and resp_write_dt0() also
get this annotation?

They appear to use the same conditional locking pattern with
meta_data_locked, conditionally acquiring sip->macc_meta_lck.

[Severity: High]
This is a pre-existing issue, but does drivers/scsi/scsi_debug.c:resp_write_same()
leak the sip->macc_data_lck write lock when fetch_to_dev_buffer() fails?

If fetch_to_dev_buffer() returns -1, the code jumps to the out label:

	sdeb_data_write_lock(sip);
	if (ndob) {
		memset(fs1p, 0, lb_size);
		ret = 0;
	} else
		ret = fetch_to_dev_buffer(scp, fs1p, lb_size);

	if (-1 == ret) {
		ret = DID_ERROR << 16;
		goto out;
	}

But the out label only unlocks sip->macc_meta_lck and skips
sdeb_data_write_unlock():

out:
	if (meta_data_locked)
		sdeb_meta_write_unlock(sip);
	return ret;

[Severity: High]
This is also a pre-existing issue, but could drivers/scsi/scsi_debug.c:resp_write_same()
cause a lock ordering deadlock with resp_comp_write()?

In resp_write_same(), the meta lock is acquired first, followed by the
data lock:

	if (sdebug_dev_is_zoned(devip) || scsi_debug_lbp()) {
		sdeb_meta_write_lock(sip);
		meta_data_locked = true;
	}
...
	sdeb_data_write_lock(sip);

However, in resp_comp_write(), the acquisition order is reversed:

	sdeb_data_write_lock(sip);
	sdeb_meta_write_lock(sip);

Could this lead to a deadlock if a compare and write command and a write same
command are processed concurrently on the same store?

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

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

* Re: [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables
  2026-07-30 22:44 ` [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables Bart Van Assche
@ 2026-07-30 23:01   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:01 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:

Pre-existing issues:
- [High] The driver incorrectly uses spin_unlock_irq() and spin_lock_irq() to temporarily drop the host lock in paths protected by spin_lock_irqsave() or inside hardirq handlers, unconditionally enabling local interrupts and violating IRQ context guarantees.
--

--- Patch [5]: [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables ---
commit 0f5e462089dbe7ff33a0eecd6a02a423a0f2c9ec
Author: Bart Van Assche <bvanassche@acm.org>

scsi: BusLogic: Introduce two local variables

The patch introduces two local variables to prepare for enabling lock context
analysis. No functionality has been changed.

> diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
> index 5304d2febd63e..f2a6ed710c770 100644
> --- a/drivers/scsi/BusLogic.c
> +++ b/drivers/scsi/BusLogic.c

[ ... ]

> @@ -2915,9 +2915,9 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
>  	 */
>  	ccb = blogic_alloc_ccb(adapter);
>  	if (ccb == NULL) {
> -		spin_unlock_irq(adapter->scsi_host->host_lock);
> +		spin_unlock_irq(shost->host_lock);

[Severity: High]
This isn't a bug introduced by this patch, but does using spin_unlock_irq()
here unconditionally enable interrupts while we are inside a
spin_lock_irqsave() block?

Since blogic_qcmd_lck() is wrapped by DEF_SCSI_QCMD() which acquires the lock
with spin_lock_irqsave(), it appears dropping the lock with spin_unlock_irq()
will unexpectedly enable local interrupts and corrupt the IRQ state context.

This same pattern also appears to exist in blogic_resetadapter() when called
from the hardirq handler blogic_inthandler() during adapter internal errors.

Could this lead to unexpected nested interrupts or IRQ storms on error paths?

>  		blogic_delay(1);
> -		spin_lock_irq(adapter->scsi_host->host_lock);
> +		spin_lock_irq(shost->host_lock);
>  		ccb = blogic_alloc_ccb(adapter);
>  		if (ccb == NULL) {
>  			command->result = DID_ERROR << 16;

[ ... ]

> @@ -3062,10 +3062,10 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
>  		   be initiated soon.
>  		 */
>  		if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
> -			spin_unlock_irq(adapter->scsi_host->host_lock);
> +			spin_unlock_irq(shost->host_lock);

[Severity: High]
This is also a pre-existing issue, but won't this spin_unlock_irq() call
similarly enable local interrupts unexpectedly for the same reasons as above?

>  			blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter);
>  			blogic_delay(1);
> -			spin_lock_irq(adapter->scsi_host->host_lock);
> +			spin_lock_irq(shost->host_lock);
>  			if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
>  						ccb)) {
>  				blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);

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

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

* Re: [PATCH v3 27/57] scsi: hisi_sas: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 27/57] scsi: hisi_sas: " Bart Van Assche
@ 2026-07-30 23:02   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:02 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:

Pre-existing issues:
- [High] Calling synchronize_irq() inside an irqsave spinlock critical section causes a 'scheduling while atomic' bug.
--

--- Patch [27]: [PATCH v3 27/57] scsi: hisi_sas: Enable lock context analysis ---
commit 289c0dd12dd00005d6efe11e9c29f7fd715a2464
Author: Bart Van Assche <bvanassche@acm.org>

scsi: hisi_sas: Enable lock context analysis

This commit enables lock context analysis for the hisi_sas driver via the
Makefile.

> diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile
> index 742e732cd51d5..8576c78d4afe3 100644
> --- a/drivers/scsi/hisi_sas/Makefile
> +++ b/drivers/scsi/hisi_sas/Makefile
> @@ -1,4 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +
> +CONTEXT_ANALYSIS := y

[Severity: High]
This is a pre-existing issue, but enabling context analysis here might
immediately trigger warnings or panics due to a scheduling while atomic bug.

When hardware timeouts or aborts trigger SCSI error handling, and the
task is already complete, hisi_sas_abort_task() calls hisi_sas_sync_cq()
while holding a spinlock with interrupts disabled:

drivers/scsi/hisi_sas/hisi_sas_main.c:hisi_sas_abort_task() {
    ...
    spin_lock_irqsave(&task->task_state_lock, flags);
    if (task->task_state_flags & SAS_TASK_STATE_DONE) {
        struct hisi_sas_cq *cq;

        if (slot) {
            cq = &hisi_hba->cq[slot->dlvry_queue];
            hisi_sas_sync_cq(cq);
        }
        spin_unlock_irqrestore(&task->task_state_lock, flags);
    ...
}

The hisi_sas_sync_cq() wrapper then directly calls synchronize_irq() for
non-poll queues:

drivers/scsi/hisi_sas/hisi_sas_main.c:hisi_sas_sync_cq() {
    if (hisi_sas_queue_is_poll(cq))
        hisi_sas_sync_poll_cq(cq);
    else
        synchronize_irq(cq->irq_no);
}

Will this cause a panic or deadlock when synchronize_irq() calls
wait_event() and attempts to sleep while the CPU is holding the
task_state_lock spinlock?

> +
>  obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_main.o
>  obj-$(CONFIG_SCSI_HISI_SAS)		+= hisi_sas_v1_hw.o hisi_sas_v2_hw.o
>  obj-$(CONFIG_SCSI_HISI_SAS_PCI)		+= hisi_sas_v3_hw.o

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

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

* Re: [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling lock context analysis
  2026-07-30 22:44 ` [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:04   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:04 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Low] The patch adds the __must_hold() lock context annotation to several task completion handlers but misses be_complete_io() and beiscsi_cleanup_task().

Pre-existing issues:
- [High] Synthesized response PDUs fail to initialize `statsn`, corrupting connection state.
- [Medium] Assignment of a native integer to a `__be16` field without endianness conversion.
--

--- Patch [15]: [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling lock context analysis ---
commit 4a36248898c49dd5d9e82e5e2120d9998eb707c9
Author: Bart Van Assche <bvanassche@acm.org>

scsi: be2iscsi: Prepare for enabling lock context analysis

This commit prepares the be2iscsi driver for lock context analysis. It adds the
__must_hold() macro to document locking requirements on various completion
handlers.

> diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
> index fd18d4d3d219b..289d9d18482c3 100644
> --- a/drivers/scsi/be2iscsi/be_main.c
> +++ b/drivers/scsi/be2iscsi/be_main.c
> @@ -1185,6 +1185,7 @@ static void
>  be_complete_logout(struct beiscsi_conn *beiscsi_conn,
>  		    struct iscsi_task *task,
>  		    struct common_sol_cqe *csol_cqe)
> +	__must_hold(&beiscsi_conn->conn->session->back_lock)

[Severity: Low]
Does this patch miss annotating some other completion handlers?

For example, hwi_complete_cmd() calls be_complete_io() under the exact same
session->back_lock:

hwi_complete_cmd() {
    spin_lock_bh(&session->back_lock);
    ...
    be_complete_io(beiscsi_conn, task, &csol_cqe);
}

Should be_complete_io() and beiscsi_cleanup_task() also receive the
__must_hold() annotation to fully document the locking requirements for the
core I/O completion and cleanup paths?


[Severity: High]
This is a pre-existing issue, but synthesised response PDUs fail to initialize
statsn, which can corrupt the connection state.

In this function, the response PDU is constructed using the memory of the
original request PDU:

be_complete_logout() {
    hdr = (struct iscsi_logout_rsp *)task->hdr;
    hdr->opcode = ISCSI_OP_LOGOUT_RSP;
    ...
    hdr->itt = io_task->libiscsi_itt;
    __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
}

Because statsn in the response overlaps exactly with cmdsn in the request, and
statsn is left uninitialized, the response inherits the request's sequence
number. When libiscsi processes this fake PDU via __iscsi_complete_pdu(), it
updates conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1.

Can this overwrite the target status sequence number with the initiator command
sequence number, leading to immediate connection state corruption and breaking
iSCSI sequence numbering?

This same issue also appears in be_complete_tmf() and be_complete_nopin_resp().


[Severity: Medium]
This is a pre-existing issue, but is a native integer assigned to a __be16
field without endianness conversion here?

be_complete_logout() {
    hdr = (struct iscsi_logout_rsp *)task->hdr;
    ...
    hdr->t2wait = 5;
    ...
}

The driver assigns the native integer 5 to hdr->t2wait (a __be16 field) without
using cpu_to_be16(). On little-endian architectures, this stores 0x05, 0x00.

When iscsid parses this via be16_to_cpu(), it interprets the value as 1280
seconds instead of 5. Can this cause the initiator to wait ~21 minutes before
attempting task reassignment during logout recovery?

>  {
>  	struct iscsi_logout_rsp *hdr;
>  	struct beiscsi_io_task *io_task = task->dd_data;
[ ... ]

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

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

* Re: [PATCH v3 08/57] scsi: aacraid: Prepare for enabling lock context analysis
  2026-07-30 22:44 ` [PATCH v3 08/57] scsi: aacraid: " Bart Van Assche
@ 2026-07-30 23:04   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:04 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Data race on `fibptr->flags` in `aac_hba_send` and `aac_fib_send` can lead to lost flags set by the interrupt handler.
- [High] Permanent leak of `dev->management_fib_count` on early error paths in `aac_fib_send` and `aac_hba_send`.
- [High] Dangling pointer in `dev->sync_fib_list` when `wait_for_completion_interruptible` is interrupted by a signal.
- [High] The `_aac_reset_adapter()` function can sleep while holding a spinlock (`host->host_lock`) and with interrupts disabled.
--

--- Patch [8]: [PATCH v3 08/57] scsi: aacraid: Prepare for enabling lock context analysis ---
commit b24c9703822591fc27fa76398a50df3f082577ac
Author: Bart Van Assche <bvanassche@acm.org>

scsi: aacraid: Prepare for enabling lock context analysis

Document the aac_send_reset_adapter() locking requirements with
__must_hold(). Annotate functions that perform conditional locking with
__no_context_analysis.

> diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
> index c4485629f7923..fb4d78233c6d7 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -475,6 +475,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw
>  int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
>  		int priority, int wait, int reply, fib_callback callback,
>  		void *callback_data)
> +	__context_unsafe(conditional locking)
>  {

[Severity: High]
This isn't a bug introduced by this patch, but does an interrupted wait leave a
dangling pointer in dev->sync_fib_list?

In aac_fib_send(), if dev->sync_mode is enabled and wait is non-zero, fibptr
is appended to dev->sync_fib_list. The code then waits:

    if (wait_for_completion_interruptible(&fibptr->event_wait)) {
        fibptr->flags &= ~FIB_CONTEXT_FLAG_WAIT;
        return -EFAULT;
    }

If interrupted by a signal, it returns -EFAULT without removing fibptr from
dev->sync_fib_list. The caller will free the FIB, adding it to the free list
while it remains on sync_fib_list. Will this lead to a use-after-free when
dev->sync_fib_list is later processed?

[ ... ]

> @@ -698,6 +699,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
>  
>  int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
>  		void *callback_data)
> +	__context_unsafe(conditional locking)
>  {

[Severity: High]
This isn't a bug introduced by this patch, but is it possible that
dev->management_fib_count leaks on early error paths?

In aac_hba_send(), when wait is 1, dev->management_fib_count is incremented.
If aac_adapter_deliver() succeeds, but the PCI device goes offline:

    if (wait) {
        spin_unlock_irqrestore(&fibptr->event_lock, flags);

        if (unlikely(aac_pci_offline(dev)))
            return -EFAULT;

The function returns -EFAULT directly without decrementing the management count.
Because fibptr->done is not set to 2, the interrupt handler will also not
decrement it. A similar leak appears to occur in aac_fib_send().

Will this eventually exhaust the AAC_NUM_MGT_FIB pool and cause future
management commands to fail with -EBUSY?

[Severity: Critical]
This isn't a bug introduced by this patch, but does the lockless update of
fibptr->flags risk losing flags set by the interrupt handler?

In aac_hba_send(), after the command is submitted via aac_adapter_deliver():

    if (wait) {
        ...
        fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;
        if (wait_for_completion_interruptible(&fibptr->event_wait))
            fibptr->done = 2;
        fibptr->flags &= ~(FIB_CONTEXT_FLAG_WAIT);

These bitwise operations are not atomic. Concurrently, the adapter can
complete the command and trigger the interrupt handler aac_intr_normal(),
which locklessly sets flags:

    if (isFastResponse)
        fib->flags |= FIB_CONTEXT_FLAG_FASTRESP;

Can the read-modify-write in aac_hba_send() overwrite and lose the
FIB_CONTEXT_FLAG_FASTRESP flag, causing the completion path to misinterpret
the response?

[ ... ]

> @@ -1466,6 +1468,7 @@ static void aac_schedule_bus_scan(struct aac_dev *aac)
>  }
>  
>  static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
> +	__context_unsafe(conditional locking)
>  {

[Severity: High]
This isn't a bug introduced by this patch, but does _aac_reset_adapter() sleep
while holding a spinlock?

aac_reset_adapter() acquires host->host_lock (a spinlock) and calls
_aac_reset_adapter(). Inside _aac_reset_adapter(), the lock is conditionally
dropped (setting jafo = 1) only if aac->thread is not NULL and the current
thread is not the command thread.

If aac->thread is NULL, or if called by the command thread itself, jafo
remains 0 and the spinlock is never unlocked. The function then proceeds to
call blocking functions like schedule() and ssleep():

    if (is_response_expected || fib->flags & FIB_CONTEXT_FLAG_WAIT) {
        ...
        schedule();
        retval = 0;
    }

    /* Give some extra time for ioctls to complete. */
    if (retval == 0)
        ssleep(2);

Could this lead to a deadlock since the spinlock is held with interrupts
disabled?

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

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

* Re: [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis
  2026-07-30 22:44 ` [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-07-30 23:06   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:06 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [Medium] The lock expressions used in the new `__must_hold` annotations do not syntactically match the lock variables used inside the functions and their callers, causing false positive context imbalance warnings in static analyzers.
- [Low] The patch misses several other functions in the driver that explicitly require the host lock, leaving the lock context annotations incomplete.

Pre-existing issues:
- [High] `spin_unlock_irq()` unconditionally enables interrupts in contexts where they must be preserved (e.g., inside `spin_lock_irqsave()` regions and hard IRQ handlers).
- [High] A failure in DMA mapping triggers a kernel panic via `BUG_ON()` rather than gracefully failing the command.
- [High] Missing memory barrier (`wmb()`) between CCB and Action Code writes in `blogic_write_outbox`.
--

--- Patch [6]: [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis ---
commit 927e16987713b901aca16b28f9b8a4d54db270de
Author: Bart Van Assche <bvanassche@acm.org>

scsi: BusLogic: Prepare for enabling lock context analysis

This commit prepares the BusLogic SCSI driver for lock context analysis.
It adds the __must_hold() macro to document locking requirements for
blogic_qcmd_lck() and blogic_resetadapter().

> diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
> index f2a6ed710c770..dafec8b24e586 100644
> --- a/drivers/scsi/BusLogic.c
> +++ b/drivers/scsi/BusLogic.c
> @@ -2878,6 +2878,7 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt)
>  */
>  
>  static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> +	__must_hold(command->device->host->host_lock)
>  {

[Severity: Medium]
Will this annotation cause false positive context imbalance warnings in static
analyzers like Sparse?

The annotation requires command->device->host->host_lock, but the function
body internally unlocks and locks shost->host_lock:

	spin_unlock_irq(shost->host_lock);
	blogic_delay(1);
	spin_lock_irq(shost->host_lock);

Since Sparse evaluates lock context expressions syntactically, will this
structural mismatch trigger the exact warnings this patch intends to prevent?

[Severity: High]
This isn't a bug introduced by this patch, but doesn't spin_unlock_irq()
unconditionally enable interrupts in contexts where they must be preserved?

Looking at blogic_qcmd_lck() in drivers/scsi/BusLogic.c:

	spin_unlock_irq(shost->host_lock);
	blogic_delay(1);
	spin_lock_irq(shost->host_lock);

Since blogic_qcmd_lck() is called from inside a region protected by
spin_lock_irqsave() via DEF_SCSI_QCMD, does this break the caller's IRQ state
by forcefully enabling interrupts?

[Severity: High]
This is a pre-existing issue, but does a DMA mapping failure here trigger a
kernel panic instead of gracefully failing the command?

drivers/scsi/BusLogic.c:blogic_qcmd_lck() {
    ...
	count = scsi_dma_map(command);
	BUG_ON(count < 0);
    ...
}

Under high memory pressure or extreme fragmentation, could scsi_dma_map()
return a negative error code and cause a Denial of Service?

>  	void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
>  	struct blogic_adapter *adapter =

[ ... ]

> diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
> index 24697a5bedc8b..c152b93fb6ddb 100644
> --- a/drivers/scsi/BusLogic.h
> +++ b/drivers/scsi/BusLogic.h
> @@ -1279,7 +1279,8 @@ static int blogic_sdev_configure(struct scsi_device *,
>  				 struct queue_limits *lim);
>  static void blogic_qcompleted_ccb(struct blogic_ccb *);
>  static irqreturn_t blogic_inthandler(int, void *);
> -static int blogic_resetadapter(struct blogic_adapter *, bool hard_reset);
> +static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
> +	__must_hold(adapter->scsi_host->host_lock);

[Severity: Medium]
Will this syntactic mismatch also cause warnings with static analyzers?

The caller blogic_hostreset() acquires shost->host_lock:

	spin_lock_irq(shost->host_lock);
	blogic_inc_count(&stats->adapter_reset_req);
	rc = blogic_resetadapter(adapter, false);
	spin_unlock_irq(shost->host_lock);

But the annotation requires adapter->scsi_host->host_lock.  Could this
mismatch lead to analysis noise?

[Severity: Low]
Are there other functions in this driver that explicitly require the host
lock but missed this annotation?

Functions like blogic_alloc_ccb() and blogic_write_outbox() have header
comments explicitly stating "The Host Adapter's Lock should already have been
acquired by the caller":

static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)

static bool blogic_write_outbox(struct blogic_adapter *adapter,
		enum blogic_action action, struct blogic_ccb *ccb)

Would adding __must_hold() to these functions complete the static analysis
coverage?

[Severity: High]
This isn't a bug introduced by this patch, but does blogic_resetadapter()
forcefully enable hardware interrupts inside a hardirq context?

The interrupt handler blogic_inthandler() calls blogic_resetadapter() on
errors. Inside blogic_resetadapter():

	spin_unlock_irq(adapter->scsi_host->host_lock);
	blogic_delay(2);
	spin_lock_irq(adapter->scsi_host->host_lock);

Since this drops the lock using spin_unlock_irq() and busy-waits for 2
seconds, can this lead to hard IRQ re-entrancy, stack overflows, or potential
deadlocks?

[Severity: High]
This is a pre-existing issue, but is there a missing memory barrier in
blogic_write_outbox()?

drivers/scsi/BusLogic.c:blogic_write_outbox() {
    ...
		next_outbox->ccb = ccb->dma_handle;
		next_outbox->action = action;
		blogic_execmbox(adapter);
    ...
}

Because these assignments to memory polled by DMA are not protected by a
compiler or memory barrier, can a weakly-ordered CPU reorder the stores to
next_outbox->ccb and next_outbox->action?

If the Host Adapter asynchronously polls and observes the new action code
before the CCB address is fully committed to memory, could this cause the
hardware to execute invalid or stale CCB addresses?

>  static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
>  static int __init blogic_setup(char *);

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

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

* Re: [PATCH v3 38/57] scsi: lpfc: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 38/57] scsi: lpfc: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:09   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:09 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [High] An AB-BA lock inversion exists between `lpfc_cmd->buf_lock` and `phba->hbalock`, which can cause a hard deadlock.
- [High] Race condition in timer callback `lpfc_els_timeout_handler` leading to use-after-free on module unload.
- [High] List corruption due to missing lock protection for SLI ring lists in `lpfc_els_abort` and `lpfc_els_flush_cmd`.
- [High] Concurrent FCP abort requests will hang for the full timeout duration due to unshared wait queues.
--

--- Patch [38]: [PATCH v3 38/57] scsi: lpfc: Prepare for enabling lock context analysis ---
commit 7e811dc5ed08a4e45843970fc90d7859310944e2
Author: Bart Van Assche <bvanassche@acm.org>

scsi: lpfc: Prepare for enabling lock context analysis

Annotate the functions that perform conditional locking with
__context_unsafe().

> diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
> index 52fc5058976d9..45e7f147b1636 100644
> --- a/drivers/scsi/lpfc/lpfc_els.c
> +++ b/drivers/scsi/lpfc/lpfc_els.c
> @@ -9597,6 +9597,7 @@ lpfc_els_timeout(struct timer_list *t)
>   **/
>  void
>  lpfc_els_timeout_handler(struct lpfc_vport *vport)
> +	__context_unsafe(conditional locking)
>  {
>  	struct lpfc_hba  *phba = vport->phba;

[Severity: High]
This isn't a bug introduced by this patch, but is there a race condition
here during module unload? 

Looking at the bottom of lpfc_els_timeout_handler(), the code checks for 
FC_UNLOADING before calling mod_timer():

    if (!test_bit(FC_UNLOADING, &phba->pport->load_flag))
        mod_timer(&vport->els_tmofunc, ...);

If the teardown thread sets the FC_UNLOADING flag immediately after this
check is evaluated, the callback will re-arm the timer. Even if
timer_delete_sync() is used during teardown, the callback re-arms the timer
before exiting, which can cause the timer to fire on freed memory and lead
to a use-after-free crash.

> @@ -9719,6 +9720,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
>   **/
>  void
>  lpfc_els_flush_cmd(struct lpfc_vport *vport)
> +	__context_unsafe(conditional locking)
>  {
>  	LIST_HEAD(abort_list);

[Severity: High]
This is a pre-existing issue, but can list corruption occur here during ELS
command flushes? 

In lpfc_els_flush_cmd(), this code moves piocb->list from txcmplq to
cancel_list:

    spin_lock_irqsave(&phba->hbalock, iflags);
    list_del_init(&piocb->dlist);
    if (mbx_tmo_err || !(phba->sli.sli_flag & LPFC_SLI_ACTIVE))
        list_move_tail(&piocb->list, &cancel_list);

For SLI4, is holding only hbalock sufficient, or does it also require 
pring->ring_lock to safely modify the txcmplq, preventing kernel panics 
during linked list traversal?

> diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
> index 9c449055a55e6..79e5e876c879e 100644
> --- a/drivers/scsi/lpfc/lpfc_nportdisc.c
> +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
> @@ -220,6 +220,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
>   */
>  void
>  lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
> +	__context_unsafe(conditional locking)
>  {
>  	LIST_HEAD(abort_list);

[Severity: High]
This isn't a bug introduced by this patch, but does this list modification
lack lock protection? 

In lpfc_els_abort(), list_del_init() modifies the active txcmplq without
holding any locks:

    if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) {
        list_del_init(&iocb->list);
        list_add_tail(&iocb->list, &drv_cmpl_list);
    }

Could this lead to list corruption during error recovery scenarios?

> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
> index f2cab134af7f1..6c3fd3c33c535 100644
> --- a/drivers/scsi/lpfc/lpfc_scsi.c
> +++ b/drivers/scsi/lpfc/lpfc_scsi.c
> @@ -5520,6 +5520,7 @@ void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport)
>   **/
>  static int
>  lpfc_abort_handler(struct scsi_cmnd *cmnd)
> +	__context_unsafe(conditional locking)
>  {
>  	struct Scsi_Host  *shost = cmnd->device->host;

[Severity: High]
This is a pre-existing issue, but does this locking order create an AB-BA
deadlock? 

In lpfc_abort_handler(), lpfc_cmd->buf_lock is acquired followed by 
phba->hbalock:

    spin_lock_irqsave(&lpfc_cmd->buf_lock, flags);
    spin_lock(&phba->hbalock);

In lpfc_sli_abort_taskmgmt(), the thread acquires phba->hbalock first, 
iterates over commands, and attempts to acquire lpfc_cmd->buf_lock. Could 
concurrent SCSI aborts and device resets freeze storage operations?

[Severity: High]
This is also a pre-existing issue, but can concurrent FCP abort requests
hang here?

In lpfc_abort_handler(), if a second thread attempts to abort the same 
command, it detects LPFC_DRIVER_ABORTED and jumps to wait_for_cmpl:

wait_for_cmpl:
    wait_event_timeout(waitq, (lpfc_cmd->pCmd != cmnd),
                       secs_to_jiffies(2*vport->cfg_devloss_tmo));

It then sleeps on its private, on-stack waitq. Because the completion 
handler only knows about the first thread's wait queue, won't the second 
thread block unconditionally for the full duration of the timeout?

> diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
> index 62a30a92b7927..c76d62e8907c1 100644
> --- a/drivers/scsi/lpfc/lpfc_sli.c
> +++ b/drivers/scsi/lpfc/lpfc_sli.c

[ ... ]

> @@ -12871,6 +12872,7 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id,
>  int
>  lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
>  			uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd cmd)
> +	__context_unsafe(conditional locking)
>  {
>  	struct lpfc_hba *phba = vport->phba;

[Severity: High]
This isn't a bug introduced by this patch, but as mentioned above, does this
lock ordering conflict with lpfc_abort_handler()? 

In lpfc_sli_abort_taskmgmt(), phba->hbalock is acquired before
lpfc_cmd->buf_lock:

    spin_lock_irqsave(&phba->hbalock, iflags);
    ...
    lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
    spin_lock(&lpfc_cmd->buf_lock);

This is the reverse of the order in lpfc_abort_handler(). Can this lead to 
a hard deadlock during concurrent I/O timeouts?

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

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

* Re: [PATCH v3 26/57] scsi: fnic: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 26/57] scsi: fnic: " Bart Van Assche
@ 2026-07-30 23:11   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:11 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] IRQ state corruption due to mixed use of shared and local variables for spinlock IRQ flags.
- [High] Use-After-Free when iterating over tport lists with list_for_each_entry_safe() and dropping the lock.
--

--- Patch [26]: [PATCH v3 26/57] scsi: fnic: Enable lock context analysis ---
commit b5089a03ad2ecce02a0412b046877b7375670d2d
Author: Bart Van Assche <bvanassche@acm.org>

scsi: fnic: Enable lock context analysis

This commit documents locking requirements across the fnic driver by adding
__must_hold(), __acquire(), and __release() annotations. This allows static
analysis tools to verify that spinlocks and mutexes are held in the required
contexts, suppressing false positives.

> diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c
> --- a/drivers/scsi/fnic/fdls_disc.c
> +++ b/drivers/scsi/fnic/fdls_disc.c
> @@ -425,8 +426,8 @@ void fnic_del_fabric_timer_sync(struct fnic *fnic)
>  	fnic->iport.fabric.del_timer_inprogress = 0;
>  }
>  
> -void fnic_del_tport_timer_sync(struct fnic *fnic,
> -						struct fnic_tport_s *tport)
> +void fnic_del_tport_timer_sync(struct fnic *fnic, struct fnic_tport_s *tport)
> +	__must_hold(&fnic->fnic_lock)
>  {
>  	tport->del_timer_inprogress = 1;
>  	spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);

[Severity: High]
This is a pre-existing issue, but does this pattern risk corrupting the IRQ
state?

Functions like fdls_tport_timer_callback() and fnic_tport_event_handler()
acquire the lock using a local stack variable:

    spin_lock_irqsave(&fnic->fnic_lock, flags);

If they subsequently call down into fnic_del_tport_timer_sync() (which drops
the lock using the shared fnic->lock_flags), it restores a stale IRQ state
belonging to a completely different thread, since the local acquisition never
updated the shared fnic->lock_flags. Could this erroneously enable or
disable IRQs prematurely?

[ ... ]

> @@ -1322,6 +1334,7 @@ fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
>  }
>  
>  bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport)
> +	__must_hold(&iport->fnic->fnic_lock)
>  {
>  	struct fnic_tport_event_s *tport_del_evt;
>  	struct fnic *fnic = iport->fnic;

[Severity: High]
This isn't a bug introduced by this patch, but does dropping the lock in this
function expose the driver to a Use-After-Free during list iteration?

Functions such as fdls_process_gpn_ft_tgt_list() iterate over the
iport->tport_list using list_for_each_entry_safe(tport, next, ...):

    list_for_each_entry_safe(tport, next, &iport->tport_list, links) {
        ...
        fdls_delete_tport(iport, tport);
    }

Inside fdls_delete_tport(), the fnic_lock is temporarily dropped to call
functions like fnic_rport_exch_reset(). While the lock is dropped, a
concurrent thread (like an incoming ELS frame reject or a workqueue event)
can acquire the lock and free the exact tport pointed to by the cached
next pointer. When the original loop reacquires the lock and proceeds to
the next iteration, wouldn't it dereference the freed next pointer?

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

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

* Re: [PATCH v3 39/57] scsi: megaraid_sas: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 39/57] scsi: megaraid_sas: " Bart Van Assche
@ 2026-07-30 23:15   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:15 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] Incorrect `__must_hold` annotations misrepresent API contracts and mask missing lock acquisitions
--

--- Patch [39]: [PATCH v3 39/57] scsi: megaraid_sas: Prepare for enabling lock context analysis ---
commit e0b92da41c18eebd6dc6b3dd8f685d565a0c3f5f
Author: Bart Van Assche <bvanassche@acm.org>

scsi: megaraid_sas: Prepare for enabling lock context analysis
    
This commit prepares the megaraid_sas driver for lock context analysis
by documenting locking requirements with __must_hold().

> diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
> index 8ee2bfe475715..67713173793a3 100644
> --- a/drivers/scsi/megaraid/megaraid_sas.h
> +++ b/drivers/scsi/megaraid/megaraid_sas.h
> @@ -2696,15 +2696,18 @@ __le16 get_updated_dev_handle(struct megasas_instance *instance,
>  			      struct MR_DRV_RAID_MAP_ALL *drv_map);
>  void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
>  	struct LD_LOAD_BALANCE_INFO *lbInfo);
> -int megasas_get_ctrl_info(struct megasas_instance *instance);
> +int megasas_get_ctrl_info(struct megasas_instance *instance)
> +	__must_hold(&instance->reset_mutex);

[Severity: Medium]
Is this annotation accurate for all callers?

megasas_get_ctrl_info() is called by un-annotated and unprotected paths 
like megasas_init_fw(). Adding __must_hold() here implies the caller is 
responsible for holding the lock, but the caller doesn't currently acquire 
it. Will this cause false positive warnings when lock context analysis is 
enabled?

[ ... ]

> diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
> index ecd365d78ae3c..ccefe5841a17b 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_base.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_base.c
[ ... ]
> @@ -7789,6 +7796,7 @@ megasas_suspend(struct device *dev)
>   */
>  static int __maybe_unused
>  megasas_resume(struct device *dev)
> +	__must_hold(&((struct megasas_instance *)dev_get_drvdata(dev))->reset_mutex)
>  {
>  	int rval;
>  	struct Scsi_Host *host;

[Severity: Medium]
Does the generic PM core actually hold this driver-private mutex when
invoking the resume callback?

Since megasas_resume() is used as a device power management callback, its
callers outside the driver do not know about or hold reset_mutex. Will
this annotation lead to static analysis errors on the PM core invocation
path?

[ ... ]

> diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> index 056cbe50e19ed..a55094a31c829 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> @@ -1792,6 +1792,7 @@ static inline void megasas_free_ioc_init_cmd(struct megasas_instance *instance)
>   */
>  static u32
>  megasas_init_adapter_fusion(struct megasas_instance *instance)
> +	__must_hold(&instance->reset_mutex)
>  {
>  	struct fusion_context *fusion;
>  	u32 scratch_pad_1;

[Severity: Medium]
Will this annotation trigger analysis errors during adapter initialization?

megasas_init_adapter_fusion() is invoked via the init_adapter function
pointer in megasas_init_fw(). The caller does not appear to hold reset_mutex
before invoking the pointer. Should the lock acquisition be added to the 
callers, or is this annotation overly strict here?

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

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

* Re: [PATCH v3 40/57] scsi: megaraid: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 40/57] scsi: megaraid: Enable " Bart Van Assche
@ 2026-07-30 23:15   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:15 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] Incorrect `__must_hold` annotations hide lockless execution paths for `reset_mutex` and defeat lock context analysis.
--

--- Patch [40]: [PATCH v3 40/57] scsi: megaraid: Enable lock context analysis ---
commit 40d3b019568a4b229e7033f10c3257b3f094d748
Author: Bart Van Assche <bvanassche@acm.org>

scsi: megaraid: Enable lock context analysis

This commit enables lock context analysis for the megaraid driver by
setting CONTEXT_ANALYSIS to y in the Makefile.

> diff --git a/drivers/scsi/megaraid/Makefile b/drivers/scsi/megaraid/Makefile
> index 12177e4cae653..9a6976a4dc22b 100644
> --- a/drivers/scsi/megaraid/Makefile
> +++ b/drivers/scsi/megaraid/Makefile
> @@ -1,4 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0
> +
> +CONTEXT_ANALYSIS := y
> +

[Severity: Medium]
Will enabling context analysis here be effective given the current
annotations on the driver's lifecycle functions?

The megasas_resume() function is annotated as holding the lock:

drivers/scsi/megaraid/megaraid_sas_base.c:
    static int __maybe_unused
    megasas_resume(struct device *dev)
        __must_hold(&((struct megasas_instance *)dev_get_drvdata(dev))->reset_mutex)

However, the PM core invokes this resume callback without holding
reset_mutex.

Similarly, during driver probe, megasas_init_adapter_mfi() and
megasas_init_adapter_fusion() are called via the init_adapter function
pointer without reset_mutex held, but they are also annotated as
requiring it:

drivers/scsi/megaraid/megaraid_sas_fusion.c:
    static u32
    megasas_init_adapter_fusion(struct megasas_instance *instance)
        __must_hold(&instance->reset_mutex)

Could these __must_hold annotations suppress valid static analysis
warnings for these execution paths, defeating the lock context analysis
being enabled here?

>  obj-$(CONFIG_MEGARAID_MM)	+= megaraid_mm.o
[ ... ]

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

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

* Re: [PATCH v3 31/57] scsi: ipr: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 31/57] scsi: ipr: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:15   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:15 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:

Pre-existing issues:
- [High] Command timers are cancelled asynchronously during adapter removal, which can lead to a use-after-free if the timer callback executes concurrently while the underlying memory is freed.
--

--- Patch [31]: [PATCH v3 31/57] scsi: ipr: Prepare for enabling lock context analysis ---
commit 2f00fc44ee9f9f3037991b9e96f4f40f0505e35f
Author: Bart Van Assche <bvanassche@acm.org>

scsi: ipr: Prepare for enabling lock context analysis

Document locking requirements with __must_hold().

> diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
> index d207e5e81afe0..51092834876cb 100644
> --- a/drivers/scsi/ipr.c
> +++ b/drivers/scsi/ipr.c
> @@ -1016,6 +1016,7 @@ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
>  static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd,
>  				  void (*timeout_func) (struct timer_list *),
>  				  u32 timeout)
> +	__must_hold(ipr_cmd->ioa_cfg->host->host_lock)
>  {
>  	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;

[Severity: High]
This is a pre-existing issue, but can the asynchronous timer cancellation
during adapter removal lead to a use-after-free?

In drivers/scsi/ipr.c:ipr_fail_all_ops(), pending command timers are cancelled
using timer_delete():

drivers/scsi/ipr.c:ipr_fail_all_ops() {
    ...
    timer_delete(&ipr_cmd->timer);
    ...
}

Since this is non-synchronous, if a timer callback like ipr_timeout() is
already running on another CPU, it will spin waiting for the lock:

ioa_cfg->host->host_lock

Meanwhile, the removal path in __ipr_remove() initiates the bringdown and
eventually calls ipr_free_all_resources(). This frees the command blocks via
dma_pool_free() in ipr_free_cmd_blks().

When the delayed timer callback finally acquires the lock, could it
dereference the freed ipr_cmd and ioa_cfg structures?

[ ... ]

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

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

* Re: [PATCH v3 32/57] scsi: ips: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 32/57] scsi: ips: " Bart Van Assche
@ 2026-07-30 23:15   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:15 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

Pre-existing issues:
- [High] Calling scsi_done() before unmapping DMA causes a potential use-after-free of the scsi_cmnd structure.
- [High] Incorrect waitlist traversal causes premature loop termination and a potential use-after-free on `struct scsi_cmnd` if command submission fails.
- [High] Memory allocations use GFP_KERNEL in atomic contexts (while holding a spinlock or in a hardirq handler), which can sleep and cause a kernel panic.
- [High] Process-context functions acquire the SCSI host_lock using spin_lock() instead of spin_lock_irqsave(), leaving them vulnerable to deadlocks from the interrupt handler.
- [High] ips_wait() busy-waits with udelay(1000) for up to 60 seconds with hardware interrupts disabled, leading to a hard lockup.
- [High] Using BUG_ON() for scsi_dma_map() failures causes an unnecessary kernel panic.
--

--- Patch [32]: [PATCH v3 32/57] scsi: ips: Prepare for enabling lock context analysis ---
commit 3f51682bbdf047060a964b17e4ca87b13e0de2ad
Author: Bart Van Assche <bvanassche@acm.org>
scsi: ips: Prepare for enabling lock context analysis

This commit annotates ips_next() with __context_unsafe to indicate it
performs conditional locking. This prepares the driver for context lock
analysis.

> diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
> index 41ed73966a48c..5ef70f058ecd6 100644
> --- a/drivers/scsi/ips.c
> +++ b/drivers/scsi/ips.c
> @@ -2506,6 +2506,7 @@ ips_hainit(ips_ha_t * ha)
>  /****************************************************************************/
>  static void
>  ips_next(ips_ha_t * ha, int intr)
> +	__context_unsafe(conditional locking)
>  {
>  	ips_scb_t *scb;

[Severity: High]
This isn't a bug introduced by this patch, but does calling scsi_done()
before unmapping the DMA cause a potential use-after-free?

In ips_next() and ips_done(), the command is completed before the SCB is
freed:

drivers/scsi/ips.c:ips_next() {
    ...
    case IPS_FAILURE:
        if (scb->scsi_cmd) {
            scb->scsi_cmd->result = DID_ERROR << 16;
            scsi_done(scb->scsi_cmd);
        }

        ips_freescb(ha, scb);
        break;
    ...
}

Because scsi_done() hands ownership of the command to the block layer,
the block layer might asynchronously complete and free or recycle the
struct scsi_cmnd. Could ips_freescb() then dereference a freed pointer
when it subsequently calls scsi_dma_unmap(scb->scsi_cmd)?


[Severity: High]
This is a pre-existing issue, but does the waitlist traversal in
ips_next() prematurely terminate the loop and risk a use-after-free?

The list linkage is destroyed by explicitly clearing host_scribble:

drivers/scsi/ips.c:ips_next() {
    ...
    SC = ips_removeq_wait(&ha->scb_waitlist, q);
    ...
    SC->host_scribble = NULL;
    ...
}

If command submission fails or completes synchronously, scsi_done() is
invoked on the command, passing ownership of the command (aliased by p)
to the block layer. Could the loop then execute the following iteration
step using potentially freed memory?

drivers/scsi/ips.c:ips_next() {
    ...
    p = (struct scsi_cmnd *) p->host_scribble;
    ...
}

Furthermore, since host_scribble was set to NULL, would p become NULL
and terminate the dispatch loop early, starving any remaining queued
commands?


[Severity: High]
This isn't a bug introduced by this patch, but do the memory allocations
use GFP_KERNEL in atomic contexts?

When ips_next() processes passthru commands, it holds the host_lock
spinlock. If called from ips_queue_lck via IPS_INTR_IORL, it runs with
interrupts disabled and the lock is not dropped.

During this path, functions like ips_alloc_passthru_buffer() and
ips_flash_copperhead() perform allocations using GFP_KERNEL:

drivers/scsi/ips.c:ips_alloc_passthru_buffer() {
    ...
    bigger_buf = dma_alloc_coherent(&ha->pcidev->dev, length,
                                    &dma_busaddr, GFP_KERNEL);
    ...
}

Since GFP_KERNEL allows blocking, can this sleep in an atomic context
and trigger a kernel panic?


[Severity: High]
This is a pre-existing issue, but is there a deadlock vulnerability
between process-context functions and the interrupt handler?

The hardware interrupt handler do_ipsintr() runs in hardirq context and
acquires the lock using spin_lock(). Meanwhile, process-context
functions like ips_eh_abort() also acquire it without disabling local
interrupts:

drivers/scsi/ips.c:ips_eh_abort() {
    ...
    spin_lock(host->host_lock);
    ...
}

If an interrupt fires on the same CPU while the scsi_eh thread holds the
lock, will the interrupt handler attempt to acquire the lock and cause
an AB-BA self-deadlock?


[Severity: High]
This isn't a bug introduced by this patch, but does ips_wait()
busy-wait for too long with hardware interrupts disabled?

In ips_eh_reset(), hardware interrupts are completely disabled on the
local CPU:

drivers/scsi/ips.c:ips_eh_reset() {
    ...
    spin_lock_irq(SC->device->host->host_lock);
    rc = __ips_eh_reset(SC);
    ...
}

This triggers a flush that eventually falls back to a polling loop in
ips_wait(), which calls udelay(1000) up to 60,000 times:

drivers/scsi/ips.c:ips_wait() {
    ...
    /* This looks like a very evil loop, but it only does this during start-up */
    udelay(1000);
    time--;
    ...
}

Could looping for up to 60 seconds with interrupts disabled violate
latency requirements and trigger the kernel's hard lockup watchdog?


[Severity: High]
This is a pre-existing issue, but does using BUG_ON() for DMA mapping
failures cause an unnecessary kernel panic?

In ips_next(), a mapping failure triggers a system panic:

drivers/scsi/ips.c:ips_next() {
    ...
    scb->sg_count = scsi_dma_map(SC);
    BUG_ON(scb->sg_count < 0);
    ...
}

Since scsi_dma_map() can return negative values like -ENOMEM when IOMMU
mappings or DMA resources are exhausted, would it be better to gracefully
fail the command or propagate the error rather than intentionally crashing
the system?

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

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

* Re: [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:17   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:17 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [Low] Missing __must_hold() annotations for core locking functions.
- [Low] Missing __must_hold annotation on __iscsi_complete_pdu() definition.

Pre-existing issues:
- [High] Deadlock due to `iscsi_complete_pdu()` acquiring `session->frwd_lock` without disabling softirqs.
- [High] Hard deadlock due to `qla4xxx` acquiring `session->back_lock` in a hardware interrupt context while `libiscsi` core leaves hardirqs enabled.
--

--- Patch [35]: [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling lock context analysis ---
commit 052b7ed83fc5a572597a78bb52886b250ac80aa2
Author: Bart Van Assche <bvanassche@acm.org>

scsi: libiscsi: Prepare for enabling lock context analysis
    
This commit prepares libiscsi for lock context analysis by documenting
locking requirements using __must_hold().

> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
[ ... ]
> @@ -1962,6 +1965,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
>   * Fail commands. session frwd lock held and xmit thread flushed.
>   */
>  static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error)
> +	__must_hold(&conn->session->frwd_lock)
>  {

[Severity: Low]
Should we also add these annotations to the core locking functions like
fail_scsi_task(), __fail_scsi_task(), and iscsi_send_nopout()?

Functions like __fail_scsi_task() manipulate sequence numbers and queues
that explicitly require both back_lock and frwd_lock to be held. Similarly,
iscsi_send_nopout() requires frwd_lock. Leaving these unannotated leaves
portions of the subsystem's logic unanalyzed by the context checker.

[ ... ]
> diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
> --- a/include/scsi/libiscsi.h
> +++ b/include/scsi/libiscsi.h
> @@ -474,8 +474,9 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
>  				char *, uint32_t);
>  extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
>  			      char *, int);
> -extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
> -				char *, int);
> +extern int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *,
> +				char *, int)
> +		__must_hold(&conn->session->back_lock);

[Severity: Low]
Does the function definition in drivers/scsi/libiscsi.c also need this
annotation?

The __must_hold() attribute was added to the declaration here in the header,
but it seems omitted from the definition:

int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                         char *data, int datalen)
{
    ...

While some static analyzers inherit attributes from the header, ensuring
locking annotations on declarations mirror their definitions provides
local consistency across translation units.

[Severity: High]
This isn't a bug introduced by this patch, but is there a potential softirq
deadlock when acquiring frwd_lock during pdu completion?

The generic API iscsi_complete_pdu() uses spin_lock() to acquire the
back_lock, which leaves softirqs enabled. Inside __iscsi_complete_pdu(),
processing an ISCSI_OP_NOOP_IN temporarily drops back_lock and acquires
frwd_lock using spin_lock():

__iscsi_complete_pdu()
    spin_unlock(&session->back_lock);
    spin_lock(&session->frwd_lock);
    iscsi_send_nopout(conn, (struct iscsi_nopin*)hdr);

When called from a process context, such as a workqueue handler, softirqs
remain enabled:

qla4xxx_task_work()
  -> iscsi_complete_pdu()
     spin_lock(&conn->session->back_lock);

If a timer softirq interrupts this process and attempts to acquire frwd_lock,
it could spin forever waiting for the interrupted process to release it.

[Severity: High]
This is a pre-existing issue, but could this back_lock usage lead to a
hardirq deadlock with the qla4xxx driver?

The libiscsi core routinely acquires back_lock using spin_lock_bh() or
spin_lock() in functions like fail_scsi_tasks(), leaving hardware interrupts
enabled:

fail_scsi_tasks()
    spin_lock_bh(&session->back_lock);

However, the qla4xxx driver acquires back_lock from a hardware interrupt
context:

qla4_83xx_interrupt_service_routine()
  -> qla4xxx_process_response_queue()
    -> qla4xxx_passthru_status_entry()
       spin_lock(&conn->session->back_lock);

If a hardware interrupt fires on a CPU currently executing a libiscsi core
function that is holding back_lock, the interrupt handler will attempt to
acquire the lock and cause a hard deadlock.

>  extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
>  extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t);
>  extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);

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

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

* Re: [PATCH v3 46/57] scsi: qedi: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 46/57] scsi: qedi: " Bart Van Assche
@ 2026-07-30 23:17   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:17 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:

Pre-existing issues:
- [High] Deadlock vulnerability due to acquiring `session->back_lock` without disabling softirqs in CQE processing paths.
--

--- Patch [46]: [PATCH v3 46/57] scsi: qedi: Enable lock context analysis ---
commit c592a3970ebc316b3aad74beecefeffd2a24b31b
Author: Bart Van Assche <bvanassche@acm.org>

scsi: qedi: Enable lock context analysis

Annotate qedi_cleanup_all_io() with __no_context_analysis since it
performs conditional locking.

[ ... ]

> diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
> index 854efa4f61d87..e162061ca49c9 100644
> --- a/drivers/scsi/qedi/qedi_fw.c
> +++ b/drivers/scsi/qedi/qedi_fw.c
> @@ -1134,6 +1134,7 @@ int qedi_send_iscsi_logout(struct qedi_conn *qedi_conn,
>  
>  int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn,
>  			struct iscsi_task *task, bool in_recovery)
> +	__context_unsafe(conditional locking)
>  {
>  	int rval;
>  	struct iscsi_task *ctask;

[Severity: High]
This is a pre-existing issue, but could the locking elsewhere in this file
lead to a deadlock?

Looking at qedi_process_tmf_resp() (and similar response handlers like
qedi_process_text_resp(), qedi_process_logout_resp(), and
qedi_process_login_resp()), they acquire session->back_lock without
disabling softirqs:

qedi_process_tmf_resp()
    spin_lock(&session->back_lock);

These handlers execute asynchronously in a kernel thread
(qedi_percpu_io_thread) with softirqs enabled.

If a timer interrupt fires on the same CPU while this lock is held, the
libiscsi transport timer (iscsi_check_transport_timeouts) could preempt
the thread in TIMER_SOFTIRQ context.

If that timer logic attempts to send a ping (iscsi_send_nopout()) and
fails due to an allocation failure or full queue, its cleanup path calls
iscsi_put_task().

iscsi_put_task() unconditionally attempts to acquire the lock using
spin_lock_bh(&session->back_lock).

Would this cause a softirq-preemption deadlock where the timer spins forever
waiting for the preempted thread to release session->back_lock? Should these
CQE processing paths use spin_lock_bh() instead?

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

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

* Re: [PATCH v3 42/57] scsi: mvsas: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 42/57] scsi: mvsas: " Bart Van Assche
@ 2026-07-30 23:18   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:18 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Dropping the spinlock inside a `list_for_each_entry_safe` loop in `mvs_do_release_task` allows list modification, causing an infinite loop.
- [Critical] Dropping the spinlock inside `mvs_int_rx` allows concurrent execution, causing double-completion of tasks and potential Use-After-Free.
- [High] The function `mvs_port_notify_deformed` fails to acquire `mvi->lock` and was missed by the new locking annotations, causing a lock imbalance.
- [High] Using a global PHY index instead of a local PHY index to write to hardware registers in `mvs_port_notify_formed`.
--

--- Patch [42]: [PATCH v3 42/57] scsi: mvsas: Enable lock context analysis ---
commit c111f35a79c7e4e1741700306a7a9dfd2b59f919
Author: Bart Van Assche <bvanassche@acm.org>

scsi: mvsas: Enable lock context analysis

Document locking requirements with __must_hold(). Annotate functions
that perform conditional locking with __no_context_analysis.

> diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
> index 359226e80eae8..f63e0dc1abd23 100644
> --- a/drivers/scsi/mvsas/mv_sas.c
> +++ b/drivers/scsi/mvsas/mv_sas.c
> @@ -1055,6 +1055,7 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st)
>  }
>  
>  static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock)
> +	__context_unsafe(conditional locking)
>  {
>  	struct sas_ha_struct *sas_ha = sas_phy->ha;
>  	struct mvs_info *mvi = NULL; int i = 0, hi;

[Severity: High]
This is a pre-existing issue, but does mvs_port_notify_formed() write to the
wrong hardware offset when multiple HBAs are present?

It uses the global index i instead of the local PHY index sas_phy->id:

drivers/scsi/mvsas/mv_sas.c:mvs_port_notify_formed() {
    ...
    if (phy->att_dev_info & PORT_SSP_TRGT_MASK) {
        MVS_CHIP_DISP->write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
        MVS_CHIP_DISP->write_port_cfg_data(mvi, i, 0x04);
    }
    ...
}

When the global index is greater than or equal to mvi->chip->n_phy, could
passing it to write_port_cfg_addr() cause out-of-bounds memory-mapped IO
writes?

[ ... ]

> @@ -1644,6 +1647,7 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
>  
>  void mvs_do_release_task(struct mvs_info *mvi,
>  		int phy_no, struct domain_device *dev)
> +	__must_hold(&mvi->lock)
>  {
>  	u32 slot_idx;
>  	struct mvs_phy *phy;

[Severity: Critical]
This is a pre-existing issue, but is it safe to use list_for_each_entry_safe()
here if the lock is dropped inside mvs_slot_complete()?

mvs_do_release_task() loops over the port list:

drivers/scsi/mvsas/mv_sas.c:mvs_do_release_task() {
    ...
    list_for_each_entry_safe(slot, slot2, &port->list, entry) {
        ...
        mvs_slot_complete(mvi, slot_idx, 1);
    }
    ...
}

When mvs_slot_complete() temporarily releases mvi->lock, a concurrent
interrupt could complete the cached next element (slot2) and remove it from
the list. 

Would this leave slot2->entry.next pointing to itself, causing
mvs_do_release_task() to spin forever in an infinite loop when it resumes?

[Severity: High]
Also a pre-existing issue, but with the new __must_hold annotation here, what
happens when this is called from mvs_port_notify_deformed()?

mvs_port_notify_deformed() ignores its lock parameter and directly calls
mvs_do_release_task() without holding mvi->lock:

drivers/scsi/mvsas/mv_sas.c:mvs_port_notify_deformed() {
    ...
    list_for_each_entry(dev, &port->dev_list, dev_list_node)
        mvs_do_release_task(phy->mvi, phy_no, dev);
    ...
}

Will this cause a lock imbalance when the downstream mvs_slot_complete()
call unconditionally executes spin_unlock(&mvi->lock)?

[ ... ]

> @@ -1862,6 +1868,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events)
>  }
>  
>  int mvs_int_rx(struct mvs_info *mvi, bool self_clear)
> +	__must_hold(&mvi->lock)
>  {
>  	u32 rx_prod_idx, rx_desc;
>  	bool attn = false;

[Severity: Critical]
This is a pre-existing issue, but does dropping the lock inside mvs_int_rx()
expose mvi->rx_cons to concurrent modification?

mvs_int_rx() loops while evaluating the shared mvi->rx_cons:

drivers/scsi/mvsas/mv_sas.c:mvs_int_rx() {
    ...
    while (mvi->rx_cons != rx_prod_idx) {
        ...
        if (likely(rx_desc & RXQ_DONE))
            mvs_slot_complete(mvi, rx_desc, 0);
        ...
    }
    ...
}

Inside the loop, mvs_slot_complete() drops mvi->lock. If a concurrent
interrupt on another CPU acquires the lock, processes the ring, and frees
the tasks, could the first CPU wake up, read old descriptors based on the
updated mvi->rx_cons, and erroneously complete new reused tasks?

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

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

* Re: [PATCH v3 10/57] scsi: aha152x: Prepare for enabling lock context analysis
  2026-07-30 22:44 ` [PATCH v3 10/57] scsi: aha152x: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:18   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:18 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

Pre-existing issues:
- [High] Preexisting list corruption vulnerability due to unlocked accesses to DISCONNECTED_SC.
- [High] Possible NULL pointer dereference in SCSI phase handlers if CURRENT_SC is NULL due to unexpected target behavior.
- [High] Calling INIT_WORK dynamically in an interrupt handler for a global work_struct corrupts the workqueue.
- [High] The global `aha152x_host_list` is modified and traversed concurrently without any locking.
- [High] The driver fails to cancel the global workqueue during device release or module unload.
--

--- Patch [10]: [PATCH v3 10/57] scsi: aha152x: Prepare for enabling lock context analysis ---
commit 4e1483c06dfed36c67b1da76d5119c68317479aa
Author: Bart Van Assche <bvanassche@acm.org>

scsi: aha152x: Prepare for enabling lock context analysis

Annotate is_complete() with __context_unsafe() because it performs
conditional locking.

> diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
> index e3ccb6bb62c00..c16dcb9274eb8 100644
> --- a/drivers/scsi/aha152x.c
> +++ b/drivers/scsi/aha152x.c
> @@ -2319,6 +2319,7 @@ static void rsti_run(struct Scsi_Host *shpnt)
>   *
>   */
>  static void is_complete(struct Scsi_Host *shpnt)
> +	__context_unsafe(conditional locking)
>  {
>  	int dataphase;
>  	unsigned long flags;

[Severity: High]
This is a pre-existing issue, but is there a risk of list corruption when
accessing DISCONNECTED_SC?

In is_complete(), the host lock is dropped before calling phase handlers
such as busfree_run():

	DO_UNLOCK(flags);
	...
	if(states[STATE].run)
		states[STATE].run(shpnt);

Then busfree_run() mutates the list without holding the QLOCK:

	append_SC(&DISCONNECTED_SC, CURRENT_SC);

Concurrently, SCSI error handler callbacks like aha152x_abort() modify the
exact same list while holding the lock:

	disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);

Can this concurrent modification lead to list corruption?

[Severity: High]
This is a pre-existing issue, but could there be a NULL pointer dereference
if a target behaves unexpectedly?

In is_complete(), the state machine transitions to phases like status or cmd
based on hardware bus signals via update_state():

	switch(GETPORT(SCSISIG) & P_MASK) {
	case P_MSGI:    STATE=msgi;    break;
	...

This occurs without verifying if a command is currently active. The state
handlers then unconditionally dereference CURRENT_SC:

status_run():
	aha152x_priv(CURRENT_SC)->status = GETPORT(SCSIDAT);

cmd_init():
	if (aha152x_priv(CURRENT_SC)->sent_command) {

If the hardware reports a phase while no command is active, would this crash
the kernel?

[Severity: High]
This is a pre-existing issue, but does dynamically initializing the global
work item in the interrupt handler corrupt the workqueue?

The interrupt handler intr() calls INIT_WORK() before schedule_work():

	INIT_WORK(&aha152x_tq, run);
	schedule_work(&aha152x_tq);

Since aha152x_tq is a global variable, if a second SCSI host adapter
triggers an interrupt while the work is already queued by the first adapter,
would INIT_WORK() overwrite the list pointers of the pending work?

[Severity: High]
This is a pre-existing issue, but is it safe to traverse and modify the
global aha152x_host_list locklessly?

Nodes are added and removed from the list locklessly:

aha152x_probe_one():
	list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);

aha152x_release():
	list_del(&HOSTDATA(shpnt)->host_list);

Concurrently, the workqueue callback run() iterates over the list locklessly:

	list_for_each_entry(hd, &aha152x_host_list, host_list) {

If aha152x_release() removes a host while the workqueue thread is traversing
the list, could this lead to following invalid pointers and a use-after-free?

[Severity: High]
This is a pre-existing issue, but could pending work items execute after
the module is unloaded or devices are freed?

Neither aha152x_release() nor aha152x_exit() appears to cancel the global
workqueue:

aha152x_release():
	void aha152x_release(struct Scsi_Host *shpnt)

aha152x_exit():
	static void __exit aha152x_exit(void)

If an interrupt schedules the work and the module is immediately unloaded,
will the kernel attempt to execute run() after the module's code segment
has been unmapped?

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

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

* Re: [PATCH v3 50/57] scsi: ufs: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 50/57] scsi: ufs: " Bart Van Assche
@ 2026-07-30 23:19   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:19 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:

Pre-existing issues:
- [High] ufshcd_wait_for_pending_cmds() uses io_schedule_timeout() without setting current->state, causing a busy loop instead of sleeping.
--

--- Patch [50]: [PATCH v3 50/57] scsi: ufs: Enable lock context analysis ---
commit 8185dd4bd8104528b9c4d31b079a63ef3f632638
Author: Bart Van Assche <bvanassche@acm.org>

scsi: ufs: Enable lock context analysis

This commit annotates functions that modify the state of a synchronization
object to enable lock context analysis. It also removes struct semaphore
annotations because lock context annotations are not supported for
semaphores.

> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index f85582287d14d..22a5f8e9af913 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -1353,6 +1353,8 @@ static int ufshcd_wait_for_pending_cmds(struct ufs_hba *hba,

[Severity: High]
This is a pre-existing issue, but does ufshcd_wait_for_pending_cmds()
busy loop here instead of sleeping?

Looking at ufshcd_wait_for_pending_cmds(), it calls io_schedule_timeout()
without first setting the task state to TASK_UNINTERRUPTIBLE:

drivers/ufs/core/ufshcd.c:ufshcd_wait_for_pending_cmds() {
	...
	do {
		tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
		tr_pending = ufshcd_pending_cmds(hba);
		if (!tm_doorbell && !tr_pending) {
			timeout = false;
			break;
		} else if (do_last_check) {
			break;
		}

		io_schedule_timeout(msecs_to_jiffies(20));
		if (ktime_to_us(ktime_sub(ktime_get(), start)) >
		    wait_timeout_us) {
	...
}

Because the task state remains TASK_RUNNING, does the underlying
schedule_timeout() function return immediately without yielding the CPU? 

Could this cause severe performance degradation by hogging 100% of a CPU
core and aggressively polling MMIO registers for up to 1 second during
operations like UFS hardware clock scaling?

>   * On failure, all acquired locks are released and the tagset is unquiesced.
>   */
>  int ufshcd_pause_command_processing(struct ufs_hba *hba, u64 timeout_us)
> +	__cond_acquires(0, &hba->host->scan_mutex)
> +	__cond_acquires(0, &hba->clk_scaling_lock)
>  {
>  	int ret = 0;

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

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

* Re: [PATCH v3 22/57] scsi: csiostor: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 22/57] scsi: csiostor: " Bart Van Assche
@ 2026-07-30 23:19   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:19 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [Low] The lock context analysis annotations are incomplete and inconsistent, which will trigger false-positive lock warnings during compilation with CONTEXT_ANALYSIS := y.

Pre-existing issues:
- [Critical] I/O request structs (`ioreq`) are returned to the freelist on abort timeout, leading to use-after-free and data corruption if the firmware later completes the aborted I/O.
- [High] Unsafe use of list_for_each_safe over shared queues across lock drops, leading to infinite loops or use-after-free if an interrupt completes the 'next' I/O.
- [High] Self-deadlock in management request cleanup due to locking assumptions exposed by the newly added annotations.
- [High] Iterating over rnodes with `list_for_each_safe` while triggering state machine changes that drop the lock allows concurrent modification of the rnode list, invalidating the iterator.
--

--- Patch [22]: [PATCH v3 22/57] scsi: csiostor: Enable lock context analysis ---
commit 46f9827cf6cee915a530068e489202f662954317
Author: Bart Van Assche <bvanassche@acm.org>

scsi: csiostor: Enable lock context analysis

This commit enables lock context analysis for the csiostor driver. It applies
the __must_hold() annotation to various hardware, logical node, remote node,
and SCSI functions that require specific locks to be held by the caller.

> diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
> index df9f81f299505..4b4d3c42667fa 100644
> --- a/drivers/scsi/csiostor/csio_hw.c
> +++ b/drivers/scsi/csiostor/csio_hw.c

[ ... ]

> @@ -3883,6 +3893,7 @@ csio_free_evt(struct csio_hw *hw, struct csio_evt_msg *evt_entry)
>  
>  void
>  csio_evtq_flush(struct csio_hw *hw)
> +	__must_hold(&hw->lock)
>  {

[Severity: Low]
Does adding this annotation cause static analysis warnings for unannotated
callers? For example, csio_hws_ready() is not annotated but calls this
function, which might trigger warnings when CONTEXT_ANALYSIS := y is enabled.

>  	uint32_t count;
>  	count = 30;

[ ... ]

> @@ -4142,6 +4153,7 @@ csio_mgmt_tmo_handler(struct timer_list *t)
>  
>  static void
>  csio_mgmtm_cleanup(struct csio_mgmtm *mgmtm)
> +	__must_hold(&mgmtm->hw->lock)
>  {

[Severity: High]
This is a pre-existing issue, but could this management request cleanup
lead to a self-deadlock?

When csio_mgmtm_cleanup() iterates over mgmtm->active_q:

list_for_each(tmp, &mgmtm->active_q) {
        ...
        if (io_req->io_cbfn) {
                io_req->wr_status = -ETIMEDOUT;
                io_req->io_cbfn(mgmtm->hw, io_req);
        }

It invokes the completion callback with hw->lock held. If the callback is
csio_ln_fdmi_rhba_cbfn(), it unconditionally attempts to acquire hw->lock:

spin_lock_irqsave(&hw->lock, flags);
if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_rhba_cbfn,

Will this cause the CPU to deadlock on the same lock?

>  	struct csio_hw *hw = mgmtm->hw;
>  	struct csio_ioreq *io_req;

[ ... ]

> diff --git a/drivers/scsi/csiostor/csio_rnode.c b/drivers/scsi/csiostor/csio_rnode.c
> index 713e13adf4dcc..74ef1e858cf39 100644
> --- a/drivers/scsi/csiostor/csio_rnode.c
> +++ b/drivers/scsi/csiostor/csio_rnode.c

[ ... ]

> @@ -563,6 +564,7 @@ __csio_reg_rnode(struct csio_rnode *rn)
>  
>  static void
>  __csio_unreg_rnode(struct csio_rnode *rn)
> +	__must_hold(&csio_lnode_to_hw(csio_rnode_to_lnode(rn))->lock)
>  {

[Severity: Low]
Will this trigger a static analysis failure due to unresolved pointer
aliasing? The lock being asserted here is
csio_lnode_to_hw(csio_rnode_to_lnode(rn))->lock, but this function calls
csio_scsi_cleanup_io_q() which expects scm->hw->lock. Does this need an
__assume_ctx_lock() workaround to prove they are the same lock?

[Severity: High]
This is a pre-existing issue, but does dropping the lock in this function
invalidate iterators in higher-level state machine handlers?

For example, csio_post_event_rns() iterates over rnodes using
list_for_each_safe(). If an event like CSIO_RNFE_DOWN causes the state
machine to call __csio_unreg_rnode(), the lock is temporarily dropped here:

spin_unlock_irq(&hw->lock);
csio_unreg_rnode(rn);
spin_lock_irq(&hw->lock);

During this window, if an incoming firmware event on another CPU (like a
LOGO) transitions the 'next' rnode to an uninitialized state and frees its
memory via csio_put_rnode(), will the list_for_each_safe() loop in
csio_post_event_rns() access the freed 'next' pointer when it resumes?

>  	struct csio_lnode *ln = csio_rnode_to_lnode(rn);
>  	struct csio_hw *hw = csio_lnode_to_hw(ln);

[ ... ]

> diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
> index b1de615cf3162..b74fed463640e 100644
> --- a/drivers/scsi/csiostor/csio_scsi.c
> +++ b/drivers/scsi/csiostor/csio_scsi.c
> @@ -1157,6 +1157,7 @@ csio_scsi_cmpl_handler(struct csio_hw *hw, void *wr, uint32_t len,
>   */
>  void
>  csio_scsi_cleanup_io_q(struct csio_scsim *scm, struct list_head *q)
> +	__must_hold(&scm->hw->lock)
>  {

[Severity: High]
This is a pre-existing issue, but can the list_for_each_safe() loop in this
function lead to an infinite loop or use-after-free?

When iterating over the queue:

list_for_each_safe(tmp, next, q) {
        ioreq = (struct csio_ioreq *)tmp;
        csio_scsi_drvcleanup(ioreq);
        list_del_init(&ioreq->sm.sm_list);
        scmnd = csio_scsi_cmnd(ioreq);
        spin_unlock_irq(&hw->lock);

If a firmware completion interrupt occurs while hw->lock is dropped,
can the ISR process the 'next' I/O request, remove it, and return it to
the freelist, causing the loop to resume iterating through the freelist?

>  	struct csio_hw *hw = scm->hw;
>  	struct csio_ioreq *ioreq;

[ ... ]

> @@ -1316,6 +1319,7 @@ csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
>   */
>  int
>  csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln)
> +	__must_hold(&scm->hw->lock)
>  {

[Severity: Critical]
This is a pre-existing issue, but does cleaning up I/O queues after an
abort timeout risk memory corruption and use-after-free?

If csio_scsi_abort_io_q() times out, it falls back to cleaning up:

rv = csio_scsi_abort_io_q(scm, &ln->cmpl_q, 30000);
if (rv != 0) {
        csio_dbg(hw, "Some I/O aborts timed out, cleaning up..\n");
        csio_scsi_cleanup_io_q(scm, &ln->cmpl_q);
}

This returns the pending ioreq structures to the driver's freelist. If the
firmware later completes the aborted I/O, the ISR extracts the old ioreq
pointer and overwrites its status:

ioreq = (struct csio_ioreq *)((uintptr_t)
                 (((struct fw_scsi_read_wr *)tempwr)->cookie));
ioreq->wr_status = status;

Could this overwrite memory if the ioreq was reallocated for a new SCSI
command since generation counters do not appear to be validated?

>  	struct csio_hw *hw = scm->hw;
>  	struct csio_scsi_level_data sld;

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

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

* Re: [PATCH v3 34/57] scsi: libfc: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 34/57] scsi: libfc: " Bart Van Assche
@ 2026-07-30 23:19   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:19 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:
- [Low] Incomplete lock context annotations for intermediate and explicitly locked functions, triggering static analysis warnings.
--

--- Patch [34]: [PATCH v3 34/57] scsi: libfc: Enable lock context analysis ---
commit 713891d004459388a5a60d9452963a9f124605ff
Author: Bart Van Assche <bvanassche@acm.org>

scsi: libfc: Enable lock context analysis

Document locking requirements with __must_hold().

> diff --git a/drivers/scsi/libfc/Makefile b/drivers/scsi/libfc/Makefile
> --- a/drivers/scsi/libfc/Makefile
> +++ b/drivers/scsi/libfc/Makefile
> @@ -1,6 +1,8 @@
>  # SPDX-License-Identifier: GPL-2.0
>  # $Id: Makefile
>  
> +CONTEXT_ANALYSIS := y
> +

[Severity: Low]
Does enabling context analysis here trigger compiler warnings for other
functions that are missing annotations?

For example, shouldn't fc_disc_stop_rports() and fc_exch_done_locked() be
annotated? They both explicitly require locks but appear to be missing the
__must_hold() annotations:

drivers/scsi/libfc/fc_disc.c:fc_disc_stop_rports() {
    ...
    lockdep_assert_held(&disc->disc_mutex);
    ...
}

[ ... ]

> diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
> --- a/drivers/scsi/libfc/fc_disc.c
> +++ b/drivers/scsi/libfc/fc_disc.c
> @@ -200,6 +200,7 @@ static void fc_disc_recv_req(struct fc_lport *lport, struct fc_frame *fp)
>   * @disc: The discovery object to be restarted
>   */
>  static void fc_disc_restart(struct fc_disc *disc)
> +	__must_hold(&disc->disc_mutex)
>  {

[Severity: Low]
Does fc_disc_recv_rscn_req() also need the __must_hold() annotation?

It calls this newly annotated fc_disc_restart() function, so without its own
annotation, could it break the analysis chain for its callers?

[ ... ]

> diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
> --- a/drivers/scsi/libfc/fc_fcp.c
> +++ b/drivers/scsi/libfc/fc_fcp.c
> @@ -1950,6 +1953,7 @@ EXPORT_SYMBOL(fc_queuecommand);
>   * The fcp packet lock must be held when calling.
>   */
>  static void fc_io_compl(struct fc_fcp_pkt *fsp)
> +	__must_hold(&fsp->scsi_pkt_lock)
>  {

[Severity: Low]
Does fc_fcp_complete_locked() also need to be annotated?

It calls fc_io_compl(), so lacking a __must_hold() annotation might cause a
context imbalance warning during analysis.

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

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

* Re: [PATCH v3 47/57] scsi: qla1280: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 47/57] scsi: qla1280: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:19   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:19 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [Medium] Incomplete `__must_hold` annotations on intermediate functions calling `qla1280_mailbox_command`.

Pre-existing issues:
- [High] Lost wakeups and stack pointer leak in `qla1280_poll()`.
--

--- Patch [47]: [PATCH v3 47/57] scsi: qla1280: Prepare for enabling lock context analysis ---
commit 1c9b404ec1f5e106acf48d1ff8e578d2279ecab4
Author: Bart Van Assche <bvanassche@acm.org>

scsi: qla1280: Prepare for enabling lock context analysis
    
Document locking requirements with __must_hold().

> diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
> index cdd6fe002c324..ebc878068684b 100644
> --- a/drivers/scsi/qla1280.c
> +++ b/drivers/scsi/qla1280.c

[ ... ]

> @@ -2413,6 +2425,7 @@ qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
>   */
>  static int
>  qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
> +	__must_hold(ha->host->host_lock)
>  {

[Severity: Medium]
Will static analysis tools emit false-positive lock context warnings for other
functions that call qla1280_mailbox_command() but lack the __must_hold()
annotation?

For example, intermediate functions like qla1280_set_target_parameters(),
qla1280_chip_diag(), qla1280_start_firmware(), qla1280_init_rings(), and
qla1280_nvram_config() call qla1280_mailbox_command() while the lock is
already held, but they are missing the annotation added to other callers
in this patch.

[ ... ]

> @@ -2538,6 +2551,7 @@ qla1280_poll(struct scsi_qla_host *ha)

[Severity: High]
This is a pre-existing issue, but does qla1280_poll() leak completed
SCSI commands on its stack-allocated done_q?

Looking at the qla1280_poll() implementation nearby, it allocates a local
list:

qla1280_poll(struct scsi_qla_host *ha)
{
    LIST_HEAD(done_q);
    ...
    if (data & RISC_INT)
        qla1280_isr(ha, &done_q);

    if (!list_empty(&done_q))
        qla1280_done(ha);
}

If qla1280_isr() populates this local done_q with completed commands, they
appear to be ignored when qla1280_done() is called, because qla1280_done()
only processes ha->done_q. When qla1280_poll() returns, the stack frame is
destroyed, permanently leaking these commands and leaving their list node
pointers aimed at invalid stack memory.

>   */
>  static int
>  qla1280_bus_reset(struct scsi_qla_host *ha, int bus)
> +	__must_hold(ha->host->host_lock)
>  {

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

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

* Re: [PATCH v3 52/57] scsi: smartpqi: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 52/57] scsi: smartpqi: Enable " Bart Van Assche
@ 2026-07-30 23:22   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:22 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [Medium] The patch introduces fake `__acquire()` directives to artificially balance the static analyzer's lock count, and the commit message incorrectly claims to use `__must_hold()` and `__no_context_analysis()` which are entirely absent.

Pre-existing issues:
- [High] The driver violates strict `struct mutex` ownership rules by acquiring mutexes in one execution context and releasing them in another, resulting in cross-task unlock violations.
- [High] Error paths in `pqi_resume_or_restore` return early without releasing `scan_mutex` and `lun_reset_mutex`, causing a permanent lock leak.
- [High] Blindly unlocking `ofa_mutex` during an OFA cancellation event in `pqi_ofa_process_event()` without verifying it is held causes undefined behavior.
--

--- Patch [52]: [PATCH v3 52/57] scsi: smartpqi: Enable lock context analysis ---
Please note that due to recitation restrictions, this review uses a free-form
summary format rather than quoting the original patch diff directly.

commit 8564515b7a0cc93357264da233ee9448ed603eee
Author: Bart Van Assche <bvanassche@acm.org>
scsi: smartpqi: Enable lock context analysis

This patch aims to document locking requirements in the smartpqi driver using
sparse annotations like __acquires() and __releases() to enable lock context
analysis.

[Severity: Medium]
The commit message states that this patch annotates functions with
__must_hold() and __no_context_analysis, but neither of those seem to be
used in the actual code.

Additionally, in functions like pqi_process_soft_reset() and
pqi_update_device_list(), the patch adds fake __acquire() directives with
comments asking what guarantees the mutexes are held. Does this misuse
the sparse annotations by artificially balancing the lock count just to
suppress warnings, instead of fixing or properly documenting the locking
design?

[Severity: High]
This isn't a bug introduced by this patch, but the driver appears to
violate strict struct mutex ownership rules. For example,
pqi_ofa_memory_alloc_worker() acquires the ofa_mutex, but the lock is later
released by a completely different worker thread in pqi_ofa_quiesce_worker()
(via pqi_process_soft_reset()). 

Similarly, pqi_suspend_or_freeze() locks scan_mutex and lun_reset_mutex
prior to sleep, which are then released by resume operations, potentially
across different async PM threads.

Since struct mutex requires the locking task to be the one that unlocks it,
could this lead to DEBUG_LOCKS_WARN_ON, workqueue lock leak warnings, and
potential internal mutex state corruption during firmware events or system PM
operations?

[Severity: High]
This is a pre-existing issue, but in pqi_resume_or_restore(), if the driver
encounters a disconnected device (ctrl_removal_state != PQI_CTRL_PRESENT) or
if pqi_resume_ctrl() fails, the function returns early. 

Since it returns without calling pqi_ctrl_unblock_device_reset() and
pqi_ctrl_unblock_scan(), does this cause a permanent resource leak of
scan_mutex and lun_reset_mutex? This could leave the driver deadlocked for
any future operations requiring these locks. The patch seems to legitimize
this leak to sparse by adding __cond_releases() annotations.

[Severity: High]
This is a pre-existing issue, but in pqi_ofa_process_event(), when handling
the PQI_EVENT_OFA_CANCELED event, the code calls pqi_ctrl_ofa_done() which
blindly unlocks ofa_mutex.

If a cancellation event is received from the controller firmware when no OFA
memory allocation is in progress, or before the worker thread has had a
chance to acquire the mutex, wouldn't unlocking an unheld mutex trigger a
DEBUG_LOCKS_WARN_ON and corrupt the mutex state?

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

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

* Re: [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly
  2026-07-30 22:45 ` [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly Bart Van Assche
@ 2026-07-30 23:22   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:22 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:
- [Low] The kernel-doc block for `scsi_report_lun_scan()` was not updated to document the newly added `shost` parameter.
--

--- Patch [55]: [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly ---
commit 843d3f98c1bc1414a3f6276906221ddaef557d90
Author: Bart Van Assche <bvanassche@acm.org>

scsi: core: Pass the SCSI host pointer directly

In several SCSI scanning functions, the SCSI host pointer is derived from
the SCSI target pointer. This patch updates these functions to pass the
SCSI host pointer directly, preparing for lock context analysis. No
functionality is changed.

> diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
> index e27da038603a2..a8994c07d4154 100644
> --- a/drivers/scsi/scsi_scan.c
> +++ b/drivers/scsi/scsi_scan.c

[ ... ]

> @@ -1438,8 +1440,9 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
>   *     0: scan completed (or no memory, so further scanning is futile)
>   *     1: could not scan with REPORT LUN
>   **/
> -static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflags,
> -				enum scsi_scan_mode rescan)
> +static int scsi_report_lun_scan(struct Scsi_Host *shost,
> +			struct scsi_target *starget, blist_flags_t bflags,
> +			enum scsi_scan_mode rescan)

[Severity: Low]
Should the kernel-doc block for scsi_report_lun_scan() be updated to include
the new @shost parameter?

It looks like the parameter was added to the function signature, but unlike
scsi_probe_and_add_lun() and scsi_sequential_lun_scan(), the documentation
wasn't updated here.

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

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

* Re: [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:23   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:23 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Dropping a lock without holding a reference allows concurrent teardown to free the connection object, leading to a Use-After-Free.
- [High] Pre-existing memory leak of `iscsi_endpoint` if userspace sends `ISCSI_UEVENT_STOP_CONN` before `ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT` during connection recovery.
--

--- Patch [51]: [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling lock context analysis ---
commit f51c8db89420b5a402dacd38c1b68b13f9794c32
Author: Bart Van Assche <bvanassche@acm.org>

scsi: iSCSI transport: Prepare for enabling lock context analysis

Document locking requirements with __must_hold().

> diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
> index 8aa76f813bcdb..ade69c7b65b47 100644
> --- a/drivers/scsi/scsi_transport_iscsi.c
> +++ b/drivers/scsi/scsi_transport_iscsi.c
> @@ -2243,6 +2243,7 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active)
>  static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn,
>  					 struct iscsi_endpoint *ep,
>  					 bool is_active)
> +	__must_hold(&conn->ep_mutex)

[Severity: High]
This isn't a bug introduced by this patch, but could this lead to a memory leak
of the iscsi_endpoint?

If userspace sends ISCSI_UEVENT_STOP_CONN during connection recovery,
iscsi_if_stop_conn() unconditionally clears ISCSI_CLS_CONN_BIT_CLEANUP:

drivers/scsi/scsi_transport_iscsi.c:iscsi_if_stop_conn()
    ...
    clear_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags);
    ...

Then, when ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT is handled here in
iscsi_if_disconnect_bound_ep(), the bit check fails:

drivers/scsi/scsi_transport_iscsi.c:iscsi_if_disconnect_bound_ep()
    ...
    if (!test_bit(ISCSI_CLS_CONN_BIT_CLEANUP, &conn->flags)) {
        spin_unlock_irq(&conn->lock);
        iscsi_ep_disconnect(conn, is_active);
    } else {
    ...

This bypasses the iscsi_put_endpoint() call in the else block, which appears
to permanently leak the endpoint if the cleanup work previously took a
reference.


[Severity: Critical]
This is a pre-existing issue, but does dropping this mutex allow a
use-after-free of the connection object?

When the else block is taken in this function:

drivers/scsi/scsi_transport_iscsi.c:iscsi_if_disconnect_bound_ep()
    ...
    } else {
        spin_unlock_irq(&conn->lock);
        ISCSI_DBG_TRANS_CONN(conn, "flush kernel conn cleanup.\n");
        mutex_unlock(&conn->ep_mutex);

        flush_work(&conn->cleanup_work);
        /* ... */
        iscsi_put_endpoint(ep);
        mutex_lock(&conn->ep_mutex);
    }

iscsi_if_ep_disconnect() does not take a reference on conn (which is not
refcounted by the endpoint). If a concurrent hardware teardown destroys the
connection and drops its last reference during flush_work(), wouldn't
mutex_lock(&conn->ep_mutex) re-acquire the lock on freed memory?

>  {
>  	/* Check if this was a conn error and the kernel took ownership */
>  	spin_lock_irq(&conn->lock);

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

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

* Re: [PATCH v3 49/57] scsi: qla4xxx: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 49/57] scsi: qla4xxx: " Bart Van Assche
@ 2026-07-30 23:25   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:25 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [High] The return value of the hardware semaphore lock acquisition qla4_82xx_crb_win_lock() is completely ignored, leading to unprotected concurrent modification of the CRB window.
- [High] A potentially 16-minute long busy-wait loop in qla4_82xx_crb_win_lock() runs with local IRQs disabled, leading to a hard lockup panic.
- [High] The driver fails to check for timeout errors when acquiring hardware semaphore locks via qla4_82xx_rom_lock() and qla4_82xx_idc_lock().
- [High] The hardware window register is modified, but the protective hardware lock is dropped before performing I/O against the window, opening a TOCTOU race condition.
--

--- Patch [49]: [PATCH v3 49/57] scsi: qla4xxx: Enable lock context analysis ---
commit f4615e07e950d925c6341ed2210c4fa827b136dc
Author: Bart Van Assche <bvanassche@acm.org>

scsi: qla4xxx: Enable lock context analysis
    
This commit annotates the functions that perform conditional locking
with __no_context_analysis.

> diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
> --- a/drivers/scsi/qla4xxx/ql4_nx.c
> +++ b/drivers/scsi/qla4xxx/ql4_nx.c
> @@ -406,6 +406,7 @@ void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha)
>  
>  void
>  qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
> +	__context_unsafe(conditional locking)
>  {
>  	unsigned long flags = 0;
>  	int rv;

[Severity: High]
This isn't a bug introduced by this patch, but while reviewing the locking
in this function, I noticed that the return value of qla4_82xx_crb_win_lock()
is completely ignored:

	write_lock_irqsave(&ha->hw_lock, flags);
	qla4_82xx_crb_win_lock(ha);
	qla4_82xx_pci_set_crbwindow_2M(ha, &off);

If another PCI function holds the hardware semaphore and the lock request
times out, qla4_82xx_crb_win_lock() returns -1. Does unconditionally
proceeding to reprogram the shared hardware CRB window defeat the mutual
exclusion mechanism and lead to uncoordinated window switching and hardware
state corruption?

[Severity: High]
This is also a pre-existing issue on this same path, but is there a risk
of a hard lockup panic here?

The write_lock_irqsave() call disables local interrupts just prior to entering
qla4_82xx_crb_win_lock(). Inside the lock acquisition routine, a spinloop
bounded by CRB_WIN_LOCK_TIMEOUT (100,000,000 iterations) calls udelay(10):

drivers/scsi/qla4xxx/ql4_nx.c:qla4_82xx_crb_win_lock() {
	...
		if (timeout >= CRB_WIN_LOCK_TIMEOUT)
			return -1;

		timeout++;
		udelay(10);
	...
}

If the hardware is unresponsive or highly contended, this massive spin loop
could run with IRQs disabled for up to 1,000 seconds. Will this invariably
trigger the kernel's hard lockup detector (NMI watchdog) and crash the system?

> @@ -429,6 +430,7 @@ qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
>  }
>  
>  uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
> +	__context_unsafe(conditional locking)
>  {
>  	unsigned long flags = 0;
>  	int rv;

[Severity: High]
This isn't a bug introduced by this patch, but while looking at the locking
primitives in this file, I noticed other places where hardware lock timeouts
are ignored.

For example, in qla4_82xx_pinit_from_rom():

	/* Halt all the indiviual PEGs and other blocks of the ISP */
	qla4_82xx_rom_lock(ha);

	/* disable all I2Q */
	qla4_82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);

And similarly in qla4_82xx_isp_reset():

	qla4_82xx_idc_lock(ha);
	dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);

If the lock is legitimately held by another host or PCI function and times
out, does blindly proceeding to execute hardware halt and reset operations
risk severe hardware state corruption?

[Severity: High]
This is another pre-existing issue in the same file's lock handling, but
is there a TOCTOU race condition when the hardware lock is temporarily dropped?

In qla4_82xx_pci_mem_read_direct() and qla4_82xx_pci_mem_write_direct(),
the protective hardware lock is dropped before performing I/O:

	addr = qla4_8xxx_pci_base_offsetfset(ha, start);
	if (!addr) {
		write_unlock_irqrestore(&ha->hw_lock, flags);
		mem_base = pci_resource_start(ha->pdev, 0);

While the lock is dropped, could another thread concurrently acquire
ha->hw_lock and reprogram the hardware window to a completely different
address? When the original thread re-acquires the lock and proceeds to
execute the I/O using the PCI pointer, will the hardware device forward
the access to the newly modified window, resulting in corrupted read/writes?

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

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

* Re: [PATCH v3 30/57] scsi: ibmvscsi_tgt: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 30/57] scsi: ibmvscsi_tgt: " Bart Van Assche
@ 2026-07-30 23:27   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:27 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [Low] Incomplete implementation of `__must_hold` locking annotations.

Pre-existing issues:
- [High] Race condition during queue teardown leading to interrupt storm and `h_free_crq` collision.
--

--- Patch [30]: [PATCH v3 30/57] scsi: ibmvscsi_tgt: Enable lock context analysis ---
commit 3c00251f51d9e551b9d5359138425cfc65cd2cef
Author: Bart Van Assche <bvanassche@acm.org>

scsi: ibmvscsi_tgt: Enable lock context analysis

This commit enables lock context analysis for the ibmvscsi_tgt driver. It
documents locking requirements by adding the __must_hold() annotation to
several functions.

> diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> index 61f6828007654..8e532a195bf95 100644
> --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> @@ -251,6 +251,7 @@ static void ibmvscsis_delete_client_info(struct scsi_info *vscsi,
>   *	Process level, interrupt lock is held
>   */
>  static long ibmvscsis_free_command_q(struct scsi_info *vscsi)
> +	__must_hold(&vscsi->intr_lock)
>  {

[Severity: High]
This is a pre-existing issue, but could this sequence lead to an interrupt
storm or hypervisor faults due to concurrent CRQ access?

Looking at ibmvscsis_free_command_q(), it disables hardware interrupts and
then drops the lock:

    vio_disable_interrupts(vscsi->dma_dev);
    // ...
    spin_unlock_bh(&vscsi->intr_lock);
    rc = ibmvscsis_unregister_command_q(vscsi);
    spin_lock_bh(&vscsi->intr_lock);

If a pending ibmvscsis_handle_crq() tasklet on another CPU acquires the lock
while it is dropped, it evaluates TARGET_STOP(vscsi) as true and
unconditionally re-enables interrupts:

    if (TARGET_STOP(vscsi)) {
        vio_enable_interrupts(vscsi->dma_dev);
        // ...
        spin_unlock_bh(&vscsi->intr_lock);
        return;
    }

Would this cause ibmvscsis_unregister_command_q() to execute concurrently
with hardware interrupts actively firing?

[Severity: Low]
Are there other functions that explicitly require the interrupt lock but
were missed by this commit?

The commit message claims to "Document locking requirements with
__must_hold()", but several other functions in this file contain explicit
comments stating they must be called with the lock held, yet lack the
__must_hold() annotation.

For example, ibmvscsis_establish_new_q():

    /*
     * Must be called with interrupt lock held.
     */
    static long ibmvscsis_establish_new_q(struct scsi_info *vscsi)

And ibmvscsis_post_disconnect():

    /*
     * PRECONDITION:
     * interrupt lock is held
     */
    static void ibmvscsis_post_disconnect(struct scsi_info *vscsi,
                                          uint new_state, uint flag_bits)

Could these also be updated to ensure complete static analysis coverage?

>  	int bytes;
>  	u32 flags_under_lock;

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

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

* Re: [PATCH v3 28/57] scsi: hpsa: Prepare for enabling lock context analysis
  2026-07-30 22:45 ` [PATCH v3 28/57] scsi: hpsa: Prepare for enabling " Bart Van Assche
@ 2026-07-30 23:27   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:27 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] If `hpsa_send_reset` fails with a SCSI error after being submitted to the hardware, `dev->commands_outstanding` is leaked.
- [High] Concurrent device reset requests cause premature clearing of mutual exclusion flags (`reset_in_progress` and `in_reset`), leaving the controller vulnerable to rescans and new OS commands while a reset is actively in progress.
--

--- Patch [28]: [PATCH v3 28/57] scsi: hpsa: Prepare for enabling lock context analysis ---
commit 9b4522a3e2cfce6e65e269b286bd08359ef94086
Author: Bart Van Assche <bvanassche@acm.org>

scsi: hpsa: Prepare for enabling lock context analysis

mutex_lock_interruptible() returns a negative value upon failure or zero
upon success. Since the Clang thread-safety analyzer only supports == 0
and != 0 tests for functions that perform conditional locking, change
the == -EINTR test into != 0. This change does not modify the behavior
of hpsa_do_reset().

> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index 8edad1830abe4..3f38030d6a8d1 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -3163,7 +3163,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
>  	int rc = 0;
>  
>  	/* We can really only handle one reset at a time */
> -	if (mutex_lock_interruptible(&h->reset_mutex) == -EINTR) {
> +	if (mutex_lock_interruptible(&h->reset_mutex)) {

[Severity: High]
This is a pre-existing issue, but concurrent device reset requests cause
premature clearing of mutual exclusion flags (reset_in_progress and in_reset),
leaving the controller vulnerable to rescans and new OS commands while a reset
is actively in progress.

If Thread 1 is performing a reset and Thread 2 is blocked on
mutex_lock_interruptible(&h->reset_mutex), interrupting Thread 2 (e.g., via
Ctrl-C) causes it to exit hpsa_do_reset() and unconditionally clear
h->reset_in_progress and dev->in_reset in hpsa_eh_device_reset_handler():

drivers/scsi/hpsa.c:hpsa_eh_device_reset_handler() {
    ...
return_reset_status:
	spin_lock_irqsave(&h->reset_lock, flags);
	h->reset_in_progress = 0;
	if (dev)
		dev->in_reset = false;
	spin_unlock_irqrestore(&h->reset_lock, flags);
}

Does this strip the mutual exclusion protection from Thread 1, exposing the
hardware to concurrent commands?

[Severity: High]
This isn't a bug introduced by this patch, but if hpsa_send_reset() fails with
a SCSI error after being submitted to the hardware, does it leak
dev->commands_outstanding?

If hpsa_send_reset() successfully enqueues the command (incrementing the
counter) but the hardware later fails the command (e.g., CMD_TARGET_STATUS),
hpsa_send_reset() returns a non-zero error code. 

hpsa_do_reset() sees this non-zero rc and skips
atomic_dec(&dev->commands_outstanding):

drivers/scsi/hpsa.c:hpsa_do_reset() {
    ...
	rc = hpsa_send_reset(h, dev, reset_type, reply_queue);
	if (!rc) {
		/* incremented by sending the reset request */
		atomic_dec(&dev->commands_outstanding);
    ...
}

Because CMD_IOCTL_PEND commands do not decrement this counter in their
interrupt completion handler, finish_cmd():

drivers/scsi/hpsa.c:finish_cmd() {
    ...
	else if (c->cmd_type == CMD_IOCTL_PEND || c->cmd_type == IOACCEL2_TMF)
		complete(c->waiting);
    ...
}

Is the count permanently leaked, causing an infinite hang on the next reset
attempt for the device because wait_event() will block forever?

>  		dev_warn(&h->pdev->dev, "concurrent reset wait interrupted.\n");
>  		return -EINTR;
>  	}

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

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

* Re: [PATCH v3 54/57] scsi: sym53c8xx_2: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 54/57] scsi: sym53c8xx_2: " Bart Van Assche
@ 2026-07-30 23:27   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:27 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:
- [High] Unconditional NULL pointer dereference (Undefined Behavior) in bnx2fc_process_cq_compl due to __assume_ctx_lock on uninitialized cb_arg pointer.
--

--- Patch [54]: [PATCH v3 54/57] scsi: sym53c8xx_2: Enable lock context analysis ---
commit 914539bc4256a83053d649d7450d8f075fb16ba8
Author: Bart Van Assche <bvanassche@acm.org>

scsi: bnx2fc: Enable lock context analysis

This commit adds lock context analysis to the bnx2fc driver. It documents
locking requirements using __must_hold() and informs the compiler about
aliases for synchronization objects with __assume_ctx_lock().

> diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> index a5ecb87d5b2d7..a3670c48900ba 100644
> --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
> @@ -880,6 +880,9 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe,
>  		return;
>  	}
>  
> +	/* Tell the compiler that there is an alias for tgt->tgt_lock. */
> +	__assume_ctx_lock(&io_req->cb_arg->aborted_io_req->tgt->tgt_lock);

[Severity: High]
Does this code trigger a NULL pointer dereference for standard SCSI
completions?

Looking at bnx2fc_process_cq_compl(), io_req->cb_arg is only allocated for ELS
or sequence cleanup commands. For standard FCoE SCSI completions
(BNX2FC_SCSI_CMD), io_req->cb_arg is NULL.

Since __assume_ctx_lock evaluates its argument to a pointer, evaluating this
nested pointer chain requires fetching the aborted_io_req pointer from the
memory addressed by cb_arg. Because cb_arg is NULL, this forces an invalid
memory read.

Can this be unconditionally reached on every SCSI completion, causing a hard
crash or triggering UndefinedBehaviorSanitizer warnings during normal I/O?

> +
>  	/* Timestamp IO completion time */
>  	cmd_type = io_req->cmd_type;

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

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

* Re: [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis Bart Van Assche
@ 2026-07-30 23:29   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:29 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] bnx2i_cleanup_task() calls wait_for_completion_timeout() while libiscsi holds session->frwd_lock, causing a scheduling while atomic bug.
- [High] Unbounded copy in bnx2i_process_reject_mesg allows a malicious iSCSI target to cause a kernel heap buffer overflow.
- [High] Missing bounds check in bnx2i_process_login_resp and bnx2i_process_text_resp leads to out-of-bounds writes of padding zeros.
--

--- Patch [21]: [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis ---
commit ba1d4ba847bd9f8639c38b0ed041d30d68619de6
Author: Bart Van Assche <bvanassche@acm.org>

scsi: bnx2i: Enable lock context analysis

Document locking requirements with __must_hold(). Use
__assume_ctx_lock() to inform the compiler about aliases for
synchronization objects.

> diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
> index 4fb68ec8e9b08..5d927880d2971 100644
> --- a/drivers/scsi/bnx2i/bnx2i_hwi.c
> +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
[ ... ]
> @@ -1443,6 +1444,7 @@ static int bnx2i_process_login_resp(struct iscsi_session *session,
>  
>  	login = (struct bnx2i_login_response *) cqe;
>  	spin_lock(&session->back_lock);
> +	__assume_ctx_lock(&conn->session->back_lock);
>  	task = iscsi_itt_to_task(conn,
>  				 login->itt & ISCSI_LOGIN_RESPONSE_INDEX);
>  	if (!task)

[Severity: High]
This isn't a bug introduced by this patch, but there appears to be a missing
bounds check when processing login responses.

In bnx2i_process_login_resp(), the payload length is added to resp_buf to
compute resp_wr_ptr:

	bnx2i_conn->gen_pdu.resp_wr_ptr =
					bnx2i_conn->gen_pdu.resp_buf + pld_len;

Could an untrusted iSCSI target send an oversized LOGIN response PDU where
pld_len exceeds the 8192 byte capacity of gen_pdu.resp_buf? If so, could this
loop write out-of-bounds padding zeros?

	if (pad_len) {
		int i = 0;
		for (i = 0; i < pad_len; i++) {
			bnx2i_conn->gen_pdu.resp_wr_ptr[0] = 0;
			bnx2i_conn->gen_pdu.resp_wr_ptr++;
		}
	}

[ ... ]
> @@ -1511,6 +1513,7 @@ static int bnx2i_process_text_resp(struct iscsi_session *session,
>  
>  	text = (struct bnx2i_text_response *) cqe;
>  	spin_lock(&session->back_lock);
> +	__assume_ctx_lock(&conn->session->back_lock);
>  	task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX);
>  	if (!task)
>  		goto done;

[Severity: High]
This is a pre-existing issue, but similar to the login response processing,
there seems to be a missing bounds check here in bnx2i_process_text_resp().

If the payload length exceeds the buffer size, could the padding logic write
past the buffer?

	bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf +
					  pld_len;
[ ... ]
	if (pad_len) {
		int i = 0;
		for (i = 0; i < pad_len; i++) {
			bnx2i_conn->gen_pdu.resp_wr_ptr[0] = 0;
			bnx2i_conn->gen_pdu.resp_wr_ptr++;
		}
	}

[ ... ]
> @@ -1803,6 +1810,7 @@ static void bnx2i_process_reject_mesg(struct iscsi_session *session,
>  		bnx2i_unsol_pdu_adjust_rq(bnx2i_conn);
>  
>  	spin_lock(&session->back_lock);
> +	__assume_ctx_lock(&conn->session->back_lock);
>  	hdr = (struct iscsi_reject *) &bnx2i_conn->gen_pdu.resp_hdr;
>  	memset(hdr, 0, sizeof(struct iscsi_hdr));
>  	hdr->opcode = reject->op_code;

[Severity: High]
This is a pre-existing issue, but is there a risk of a kernel heap buffer
overflow in bnx2i_process_reject_mesg()?

When receiving an iSCSI REJECT message, the CQE's data_length is passed
directly to bnx2i_get_rq_buf():

	if (reject->data_length) {
		bnx2i_get_rq_buf(bnx2i_conn, conn->data, reject->data_length);
		bnx2i_put_rq_buf(bnx2i_conn, 1);
	}

In bnx2i_get_rq_buf(), this executes a memcpy into the statically sized
conn->data buffer:

	memcpy(ptr, (u8 *) bnx2i_conn->ep->qp.rq_cons_qe, len);

If an untrusted iSCSI target sends an oversized REJECT PDU, will this write
past the bounds of the 8192 byte buffer?

> diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
> index 6c80e5b514fda..c868eada72c3e 100644
> --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
> +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
> @@ -1154,6 +1154,7 @@ static void bnx2i_cpy_scsi_cdb(struct scsi_cmnd *sc, struct bnx2i_cmd *cmd)
>  }
>  
>  static void bnx2i_cleanup_task(struct iscsi_task *task)
> +	__must_hold(&task->conn->session->back_lock)
>  {
>  	struct iscsi_conn *conn = task->conn;
>  	struct bnx2i_conn *bnx2i_conn = conn->dd_data;

[Severity: High]
This isn't a bug introduced by this patch, but does bnx2i_cleanup_task() sleep
while atomic?

During error handling, such as in iscsi_conn_stop() or iscsi_eh_device_reset(),
libiscsi acquires the session->frwd_lock and calls fail_scsi_tasks().

If fail_scsi_tasks() drops the task reference count to 0 via
__iscsi_put_task(), it synchronously invokes iscsi_free_task(), which calls
bnx2i_cleanup_task().

While bnx2i_cleanup_task() drops the back_lock, the implicitly held frwd_lock
remains locked when it waits for the completion:

	if (task->state == ISCSI_TASK_ABRT_TMF) {
		bnx2i_send_cmd_cleanup_req(hba, task->dd_data);

		spin_unlock_bh(&conn->session->back_lock);
		wait_for_completion_timeout(&bnx2i_conn->cmd_cleanup_cmpl,
				msecs_to_jiffies(ISCSI_CMD_CLEANUP_TIMEOUT));
		spin_lock_bh(&conn->session->back_lock);
	}

Could this cause a scheduling while atomic bug when wait_for_completion_timeout
is called with frwd_lock still held?

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

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

* Re: [PATCH v3 44/57] scsi: pm8001: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 44/57] scsi: pm8001: " Bart Van Assche
@ 2026-07-30 23:31   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:31 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:

Pre-existing issues:
- [High] Early returns in `mpi_sata_completion` for internal tasks bypass the `SAS_TASK_STATE_ABORTED` check, leading to a Use-After-Free if the task was concurrently aborted.
--

--- Patch [44]: [PATCH v3 44/57] scsi: pm8001: Enable lock context analysis ---
commit 33ee7fcaec7784e599b990132a4a4b4063d0bddb
Author: Bart Van Assche <bvanassche@acm.org>

scsi: pm8001: Enable lock context analysis

This commit enables lock context analysis for the pm8001 driver. It also
documents locking requirements with __must_hold() for mpi_sata_completion()
and process_one_iomb().

> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 2c0fa7ab33d22..11f6fa5c9771e 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -2294,6 +2294,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  static void
>  mpi_sata_completion(struct pm8001_hba_info *pm8001_ha,
>  		struct outbound_queue_table *circularQ, void *piomb)
> +	__must_hold(&circularQ->oq_lock)
>  {
>  	struct sas_task *t;
>  	struct pm8001_ccb_info *ccb;

[Severity: High]
This is a pre-existing issue, but does this function have a use-after-free
if an internal task is concurrently aborted?

If a SATA internal task (where !t->uldd_task) times out, the libsas EH
handler can set SAS_TASK_STATE_ABORTED under the task_state_lock, complete
the task, and free it.

If the device concurrently completes the task with an error,
mpi_sata_completion() checks !t->uldd_task and returns early after calling
pm8001_ccb_task_free_done().

This early return bypasses the task_state_lock synchronization and the check
for SAS_TASK_STATE_ABORTED at the end of the function, which blindly executes
task->task_done(task) on a potentially freed task.

This issue also appears to exist in mpi_sata_completion() in
drivers/scsi/pm8001/pm8001_hwi.c.

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

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

* Re: [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock
  2026-07-30 22:45 ` [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock Bart Van Assche
@ 2026-07-30 23:32   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:32 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] The patch missed converting a direct read of `shost_state` in the `mpi3mr` driver to the new `scsi_get_host_state()` API.
- [Medium] Double initialization of `host_lock` via the `spinlock_init` guard overwrites the correct lockdep class name.
- [Medium] `scsi_host_set_state()` performs a plain write to `shost_state`, which races with the newly introduced `READ_ONCE()` lockless readers.
--

--- Patch [57]: [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock ---
commit b02669cdb0e82751599147d300ebcdc8db8d8734
Author: Bart Van Assche <bvanassche@acm.org>

scsi: core: Protect host state changes with the host lock

Some but not all SCSI host state changes are protected with the SCSI
host lock. Annotate the SCSI host state with __guarded_by(host_lock),
protect all SCSI host state changes with the SCSI host lock and use
READ_ONCE() for all SCSI host state reads. This patch prevents that
KCSAN complains about data races when accessing the SCSI host state.

Reported-by: Jianzhou Zhao <luckd0g@163.com>
Closes: https://lore.kernel.org/all/36d59d0e.6db0.19cdbeee01b.Coremail.luckd0g@163.com/
Signed-off-by: Bart Van Assche <bvanassche@acm.org>

> diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
> index 08ec144f7bf77..222baa7e10680 100644
> --- a/drivers/scsi/hosts.c
> +++ b/drivers/scsi/hosts.c
[ ... ]
> @@ -413,7 +415,8 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
>  
>  	shost->host_lock = &shost->default_lock;
>  	spin_lock_init(shost->host_lock);
> -	shost->shost_state = SHOST_CREATED;
> +	scoped_guard(spinlock_init, shost->host_lock)
> +		shost->shost_state = SHOST_CREATED;

[Severity: Medium]
Will this double-initialize the host_lock and overwrite the lockdep class name?

The previous line explicitly calls spin_lock_init(shost->host_lock) which
assigns the correct static lockdep key. Using scoped_guard(spinlock_init, ...)
immediately after calls the initialization macro again internally, overwriting
the lockdep class with a generic macro variable name (_T->lock).

[ ... ]
> diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
> index c5f85af4ba072..d0eefefdc0be8 100644
> --- a/include/scsi/scsi_host.h
> +++ b/include/scsi/scsi_host.h
[ ... ]
> @@ -790,11 +790,18 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
>  	return container_of(dev, struct Scsi_Host, shost_gendev);
>  }
>  
> +static inline enum scsi_host_state scsi_get_host_state(struct Scsi_Host *shost)
> +{
> +	return context_unsafe(READ_ONCE(shost->shost_state));
> +}
> +

[Severity: Medium]
Does the plain write in scsi_host_set_state() need to be updated to
WRITE_ONCE() to match this new READ_ONCE()?

Since scsi_host_set_state() performs a plain write to shost->shost_state,
concurrent lockless READ_ONCE() readers could still cause KCSAN to flag data
races due to compiler tearing on the writer side. The LKMM requires
WRITE_ONCE() on the writer side when there are concurrent lockless
READ_ONCE() readers.

[ ... ]
> @@ -945,6 +953,7 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
>  	return shost->prot_guard_type;
>  }
>  
> -extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state);
> +int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
> +	__must_hold(shost->host_lock);
>  
>  #endif /* _SCSI_SCSI_HOST_H */

[Severity: Medium]
Was the mpi3mr driver missed during the tree-wide conversion to the new
scsi_get_host_state() API?

It looks like mpi3mr_qcmd() in drivers/scsi/mpi3mr/mpi3mr_os.c still checks
scmd->device->host->shost_state == SHOST_RECOVERY directly without using
scsi_get_host_state() or holding the host_lock.

Will this trigger a new Sparse warning due to the newly added
__guarded_by(host_lock) annotation on shost_state?

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

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

* Re: [PATCH v3 56/57] scsi: core: Enable lock context analysis
  2026-07-30 22:45 ` [PATCH v3 56/57] scsi: core: Enable lock context analysis Bart Van Assche
@ 2026-07-30 23:36   ` sashiko-bot
  0 siblings, 0 replies; 90+ messages in thread
From: sashiko-bot @ 2026-07-30 23:36 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Unconditional evaluation of `io_req->cb_arg->aborted_io_req->tgt->tgt_lock` causes a NULL pointer dereference for standard SCSI commands.
- [Medium] Falsely adding `__acquire()` macros to trick the static analyzer instead of correctly annotating the function contract.
--

--- Patch [56]: [PATCH v3 56/57] scsi: core: Enable lock context analysis ---
commit 107a7992c0ed289ceb2e27bff45ba1eb5b8101fd
Author: Bart Van Assche <bvanassche@acm.org>

scsi: core: Enable lock context analysis

Document which functions expect that shost->scan_mutex is held. Inform
the compiler about synchronization object aliases with __assume_ctx_lock().
Enable lock context analysis for the SCSI core and also for all drivers
in the drivers/scsi/ directory.

> diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
> index 842c254bb2269..a1fbdf4b0705a 100644
> --- a/drivers/scsi/Makefile
> +++ b/drivers/scsi/Makefile
> @@ -14,6 +14,7 @@
>  # satisfy certain initialization assumptions in the SCSI layer.
>  # *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
>  
> +CONTEXT_ANALYSIS := y

[Severity: High]
Does enabling context analysis here cause a NULL pointer dereference in
bnx2fc_process_cq_compl()?

When context analysis is enabled, __assume_ctx_lock() forces the compiler
to evaluate its argument. For standard SCSI commands where io_req->cb_arg
is NULL, this expression in drivers/scsi/bnx2fc/bnx2fc_hwi.c will
dereference a NULL pointer on the CQ completion fast path:

	/* Tell the compiler that there is an alias for tgt->tgt_lock. */
	__assume_ctx_lock(&io_req->cb_arg->aborted_io_req->tgt->tgt_lock);


[Severity: Medium]
Are the __acquire() annotations in pqi_process_soft_reset() masking an
unbalanced unlock from the static analyzer?

By enabling context analysis, it looks like this exposes a mismatch in the
contract for pqi_ofa_quiesce_worker() in drivers/scsi/smartpqi/smartpqi_init.c.

The worker is incorrectly annotated as returning with the scan_mutex and
lun_reset_mutex held:

static void pqi_ofa_quiesce_worker(struct work_struct *work)
	__acquires(&quiesce_work_to_ctrl_info(work)->scan_mutex)
	__acquires(&quiesce_work_to_ctrl_info(work)->lun_reset_mutex)

However, the worker calls pqi_process_soft_reset(), which unconditionally
drops these locks in all execution paths.

It looks like fake __acquire() macros were added to pqi_process_soft_reset()
to trick the analyzer into ignoring the unbalanced unlocks:

	/* What guarantees that these mutexes are held here? */
	__acquire(&ctrl_info->lun_reset_mutex);
	__acquire(&ctrl_info->ofa_mutex);
	__acquire(&ctrl_info->scan_mutex);
	pqi_ctrl_ofa_done(ctrl_info);
	pqi_ofa_ctrl_unquiesce(ctrl_info);

Does this intentionally hide the dynamic lock release pattern from the static
analyzer instead of correctly annotating the function contract?

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

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

end of thread, other threads:[~2026-07-30 23:36 UTC | newest]

Thread overview: 90+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 22:44 [PATCH v3 00/57] Enable lock context analysis for the SCSI subsystem Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 01/57] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 02/57] scsi: scsi_debug: Prepare for enabling lock context analysis Bart Van Assche
2026-07-30 23:01   ` sashiko-bot
2026-07-30 22:44 ` [PATCH v3 03/57] scsi: sg: " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 04/57] scsi: st: " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 05/57] scsi: BusLogic: Introduce two local variables Bart Van Assche
2026-07-30 23:01   ` sashiko-bot
2026-07-30 22:44 ` [PATCH v3 06/57] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
2026-07-30 23:06   ` sashiko-bot
2026-07-30 22:44 ` [PATCH v3 07/57] scsi: NCR5380: " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 08/57] scsi: aacraid: " Bart Van Assche
2026-07-30 23:04   ` sashiko-bot
2026-07-30 22:44 ` [PATCH v3 09/57] scsi: aic7xxx: Enable " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 10/57] scsi: aha152x: Prepare for enabling " Bart Van Assche
2026-07-30 23:18   ` sashiko-bot
2026-07-30 22:44 ` [PATCH v3 11/57] scsi: aic7xxx: " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 12/57] scsi: aic94xx: Enable " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 13/57] scsi: arcmsr: " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 14/57] scsi: arm: " Bart Van Assche
2026-07-30 22:44 ` [PATCH v3 15/57] scsi: be2iscsi: Prepare for enabling " Bart Van Assche
2026-07-30 23:04   ` sashiko-bot
2026-07-30 22:44 ` [PATCH v3 16/57] scsi: be2iscsi: Enable " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 17/57] scsi: cxgbi: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 18/57] scsi: bfa: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 19/57] scsi: bnx2fc: " Bart Van Assche
2026-07-30 23:01   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 20/57] scsi: bnx2i: Introduce a local variable Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 21/57] scsi: bnx2i: Enable lock context analysis Bart Van Assche
2026-07-30 23:29   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 22/57] scsi: csiostor: " Bart Van Assche
2026-07-30 23:19   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 23/57] scsi: elx: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 24/57] scsi: esas2r: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 25/57] scsi: fcoe: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 26/57] scsi: fnic: " Bart Van Assche
2026-07-30 23:11   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 27/57] scsi: hisi_sas: " Bart Van Assche
2026-07-30 23:02   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 28/57] scsi: hpsa: Prepare for enabling " Bart Van Assche
2026-07-30 23:27   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 29/57] scsi: ibmvscsi: Enable " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 30/57] scsi: ibmvscsi_tgt: " Bart Van Assche
2026-07-30 23:27   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 31/57] scsi: ipr: Prepare for enabling " Bart Van Assche
2026-07-30 23:15   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 32/57] scsi: ips: " Bart Van Assche
2026-07-30 23:15   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 33/57] scsi: isci: Enable " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 34/57] scsi: libfc: " Bart Van Assche
2026-07-30 23:19   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 35/57] scsi: libiscsi: Prepare for enabling " Bart Van Assche
2026-07-30 23:17   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 36/57] scsi: libsas: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 37/57] scsi: libsas: Enable " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 38/57] scsi: lpfc: Prepare for enabling " Bart Van Assche
2026-07-30 23:09   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 39/57] scsi: megaraid_sas: " Bart Van Assche
2026-07-30 23:15   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 40/57] scsi: megaraid: Enable " Bart Van Assche
2026-07-30 23:15   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 41/57] scsi: mpt3sas: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 42/57] scsi: mvsas: " Bart Van Assche
2026-07-30 23:18   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 43/57] scsi: pcmcia: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 44/57] scsi: pm8001: " Bart Van Assche
2026-07-30 23:31   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 45/57] scsi: qedf: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 46/57] scsi: qedi: " Bart Van Assche
2026-07-30 23:17   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 47/57] scsi: qla1280: Prepare for enabling " Bart Van Assche
2026-07-30 23:19   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 48/57] scsi: qla2xxx: Enable " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 49/57] scsi: qla4xxx: " Bart Van Assche
2026-07-30 23:25   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 50/57] scsi: ufs: " Bart Van Assche
2026-07-30 23:19   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 51/57] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
2026-07-30 23:23   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 52/57] scsi: smartpqi: Enable " Bart Van Assche
2026-07-30 23:22   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 53/57] scsi: snic: " Bart Van Assche
2026-07-30 22:45 ` [PATCH v3 54/57] scsi: sym53c8xx_2: " Bart Van Assche
2026-07-30 23:27   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 55/57] scsi: core: Pass the SCSI host pointer directly Bart Van Assche
2026-07-30 23:22   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 56/57] scsi: core: Enable lock context analysis Bart Van Assche
2026-07-30 23:36   ` sashiko-bot
2026-07-30 22:45 ` [PATCH v3 57/57] scsi: core: Protect host state changes with the host lock Bart Van Assche
2026-07-30 23:32   ` sashiko-bot

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