* [PATCH v4 00/54] scsi: Enable context analysis for most drivers
@ 2026-09-25 18:25 Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 01/54] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
` (53 more replies)
0 siblings, 54 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen; +Cc: linux-scsi, Bart Van Assche
This patch series enables lock context analysis for all SCSI drivers in the
drivers/scsi/ directory except scsi_debug. 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'.
Please consider this patch series for the next merge window.
Thanks,
Bart.
Changes compared to v3:
- Dropped the SCSI core and UFS patches (merged upstream in Linux 7.3).
- Replaced __no_context_analysis with __context_unsafe(/*reason*/) across
drivers with conditional locking (aacraid, ips, libfc, lpfc, mvsas, qedi,
qla2xxx, qla4xxx).
- Passed struct pointers directly to functions called with locks held instead
of dereferencing or using __assume_ctx_lock():
* BusLogic: Pass struct Scsi_Host * directly to multiple functions.
* libiscsi: Pass struct iscsi_session * directly to functions requiring
session locks and update callers in be2iscsi, bnx2i, cxgbi, libiscsi,
libiscsi_tcp, qedi, qla4xxx, and iser.
* bnx2fc: Pass tgt directly to several functions.
* csiostor: Pass struct csio_hw * directly to cleanup and abort functions.
* fnic: Pass struct fnic_iport_s * and struct fnic * directly.
* ipr: Pass struct Scsi_Host * directly to error handling functions.
* qla1280: Pass struct Scsi_Host * directly to wait/error functions.
* NCR5380: Pass struct NCR5380_hostdata * directly to NCR5380_select()
and NCR5380_information_transfer().
* fcoe: Pass struct fcoe_ctlr * directly to functions called with locks
held.
- scsi: ipr: Added patch to simplify ipr_eh_abort() by deriving the host
pointer once (detected by Sashiko).
- scsi: smartpqi: Fixed missing ampersands (&ctrl_info->...), documented
locking requirements with __acquires(), __releases(), and __cond_releases(),
and suppressed complaints with __acquire() where mutex usage is irregular.
- scsi: cxgbi: Added __assume_ctx_lock(&conn->session->back_lock) with a
TODO comment documenting missing locking around iscsi_itt_to_ctask().
- scsi: libfc: Added __must_hold annotations for discovery and FCP functions.
- scsi: ibmvscsi_tgt: Added __must_hold(&vscsi->intr_lock) annotations.
- scsi: pm8001: Added Acked-by from Jack Wang.
- Consolidated preparation and enabling patches for aic7xxx, be2iscsi, and
bnx2i.
- Moved the scsi_debug changes into a separate patch series.
- Dropped megaraid / megaraid_sas patches from this series. These will be
reposted later.
- Added patch "scsi: drivers: Enable lock context analysis" as the final patch
to enable CONTEXT_ANALYSIS := y in drivers/scsi/Makefile (excluding
scsi_debug).
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 (54):
PCI: Convert to_pci_dev() into an inline function
scsi: sg: Prepare for enabling lock context analysis
scsi: st: Prepare for enabling lock context analysis
scsi: BusLogic: Pass the host pointer directly to several functions
scsi: BusLogic: Prepare for enabling lock context analysis
scsi: NCR5380: Prepare for enabling lock context analysis
scsi: aacraid: Enable lock context analysis
scsi: aha152x: Prepare for enabling lock context analysis
scsi: aic7xxx: Enable lock context analysis
scsi: aic94xx: Enable lock context analysis
scsi: arcmsr: Enable lock context analysis
scsi: libiscsi: Pass the session pointer directly to several functions
scsi: libiscsi: 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: Pass tgt directly to several functions
scsi: bnx2fc: Enable lock context analysis
scsi: bnx2i: Enable lock context analysis
scsi: csiostor: Pass the hw pointer directly to several functions
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: Pass pointers directly to several functions
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: Simplify ipr_eh_abort()
scsi: ipr: Pass the host pointer directly to several functions
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: libsas: Prepare for enabling lock context analysis
scsi: libsas: Enable lock context analysis
scsi: lpfc: Prepare for enabling 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: Pass the host pointer directly to several functions
scsi: qla1280: Prepare for enabling lock context analysis
scsi: qla2xxx: Enable lock context analysis
scsi: qla4xxx: 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: drivers: Enable lock context analysis
drivers/infiniband/ulp/iser/iser_initiator.c | 3 +-
drivers/scsi/BusLogic.c | 99 ++++---
drivers/scsi/BusLogic.h | 3 +-
drivers/scsi/Makefile | 25 +-
drivers/scsi/NCR5380.c | 19 +-
drivers/scsi/NCR5380.h | 5 +-
drivers/scsi/aacraid/Makefile | 2 +
drivers/scsi/aacraid/commctrl.c | 1 +
drivers/scsi/aacraid/commsup.c | 3 +
drivers/scsi/aha152x.c | 4 +-
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/be2iscsi/Makefile | 2 +
drivers/scsi/be2iscsi/be_main.c | 18 +-
drivers/scsi/bfa/Makefile | 3 +
drivers/scsi/bnx2fc/Makefile | 3 +
drivers/scsi/bnx2fc/bnx2fc.h | 9 +-
drivers/scsi/bnx2fc/bnx2fc_els.c | 27 +-
drivers/scsi/bnx2fc/bnx2fc_hwi.c | 2 +-
drivers/scsi/bnx2fc/bnx2fc_io.c | 15 +-
drivers/scsi/bnx2fc/bnx2fc_tgt.c | 2 +-
drivers/scsi/bnx2i/Makefile | 3 +
drivers/scsi/bnx2i/bnx2i_hwi.c | 45 ++--
drivers/scsi/bnx2i/bnx2i_iscsi.c | 1 +
drivers/scsi/csiostor/Makefile | 2 +
drivers/scsi/csiostor/csio_attr.c | 4 +-
drivers/scsi/csiostor/csio_hw.c | 20 +-
drivers/scsi/csiostor/csio_lnode.c | 3 +
drivers/scsi/csiostor/csio_rnode.c | 9 +-
drivers/scsi/csiostor/csio_scsi.c | 42 +--
drivers/scsi/csiostor/csio_scsi.h | 7 +-
drivers/scsi/cxgbi/Makefile | 3 +
drivers/scsi/cxgbi/libcxgbi.c | 13 +-
drivers/scsi/elx/Makefile | 1 +
drivers/scsi/esas2r/Makefile | 3 +
drivers/scsi/fcoe/Makefile | 3 +
drivers/scsi/fcoe/fcoe_ctlr.c | 50 +++-
drivers/scsi/fnic/Makefile | 3 +
drivers/scsi/fnic/fdls_disc.c | 57 +++-
drivers/scsi/fnic/fip.c | 2 +
drivers/scsi/fnic/fnic_fcs.c | 21 +-
drivers/scsi/fnic/fnic_fdls.h | 7 +-
drivers/scsi/fnic/fnic_scsi.c | 4 +
drivers/scsi/hisi_sas/Makefile | 3 +
drivers/scsi/hpsa.c | 2 +-
drivers/scsi/ibmvscsi/Makefile | 3 +
drivers/scsi/ibmvscsi_tgt/Makefile | 3 +
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 34 ++-
drivers/scsi/ipr.c | 46 ++--
drivers/scsi/ips.c | 1 +
drivers/scsi/isci/Makefile | 3 +
drivers/scsi/libfc/Makefile | 2 +
drivers/scsi/libfc/fc_disc.c | 7 +-
drivers/scsi/libfc/fc_exch.c | 6 +
drivers/scsi/libfc/fc_fcp.c | 17 +-
drivers/scsi/libiscsi.c | 258 +++++++++++--------
drivers/scsi/libiscsi_tcp.c | 17 +-
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/mpt3sas/Makefile | 3 +
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 | 35 +--
drivers/scsi/qla1280.c | 57 ++--
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_isr.c | 8 +-
drivers/scsi/qla4xxx/ql4_nx.c | 2 +
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 +
include/linux/pci.h | 5 +-
include/scsi/libiscsi.h | 23 +-
92 files changed, 834 insertions(+), 405 deletions(-)
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH v4 01/54] PCI: Convert to_pci_dev() into an inline function
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 02/54] scsi: sg: Prepare for enabling lock context analysis Bart Van Assche
` (52 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: 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 d31a8d107b1e..68166c9f8158 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -611,7 +611,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] 64+ messages in thread
* [PATCH v4 02/54] scsi: sg: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 01/54] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 03/54] scsi: st: " Bart Van Assche
` (51 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Doug Gilbert, James E.J. Bottomley,
Martin K. Petersen
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 5408f002e6c0..714ae6f0cf18 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] 64+ messages in thread
* [PATCH v4 03/54] scsi: st: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 01/54] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 02/54] scsi: sg: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions Bart Van Assche
` (50 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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 1ca9753cb734..8827b487de9d 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3538,6 +3538,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] 64+ messages in thread
* [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (2 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 03/54] scsi: st: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-26 20:02 ` Khalid Aziz
2026-09-25 18:25 ` [PATCH v4 05/54] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
` (49 subsequent siblings)
53 siblings, 1 reply; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Khalid Aziz, James E.J. Bottomley,
Martin K. Petersen
Pass the struct Scsi_Host pointer directly to multiple functions. This
prepares the BusLogic driver for enabling compiler-based 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 | 93 +++++++++++++++++++++++------------------
drivers/scsi/BusLogic.h | 2 +-
2 files changed, 54 insertions(+), 41 deletions(-)
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 27b446c0c5d0..75aaf35383a9 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -276,8 +276,9 @@ static void blogic_create_addlccbs(struct blogic_adapter *adapter,
Lock should already have been acquired by the caller.
*/
-static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
+static struct blogic_ccb *blogic_alloc_ccb(struct Scsi_Host *host)
{
+ struct blogic_adapter *adapter = (void *)host->hostdata;
static unsigned long serial;
struct blogic_ccb *ccb;
ccb = adapter->free_ccbs;
@@ -307,7 +308,8 @@ static struct blogic_ccb *blogic_alloc_ccb(struct blogic_adapter *adapter)
caller.
*/
-static void blogic_dealloc_ccb(struct blogic_ccb *ccb, int dma_unmap)
+static void blogic_dealloc_ccb(struct Scsi_Host *host, struct blogic_ccb *ccb,
+ int dma_unmap)
{
struct blogic_adapter *adapter = ccb->adapter;
@@ -2596,8 +2598,10 @@ static void blogic_scan_inbox(struct blogic_adapter *adapter)
should already have been acquired by the caller.
*/
-static void blogic_process_ccbs(struct blogic_adapter *adapter)
+static void blogic_process_ccbs(struct Scsi_Host *host)
{
+ struct blogic_adapter *adapter = (void *)host->hostdata;
+
if (adapter->processing_ccbs)
return;
adapter->processing_ccbs = true;
@@ -2621,7 +2625,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
/*
Place CCB back on the Host Adapter's free list.
*/
- blogic_dealloc_ccb(ccb, 1);
+ blogic_dealloc_ccb(host, ccb, 1);
#if 0 /* this needs to be redone different for new EH */
/*
Bus Device Reset CCBs have the command field
@@ -2650,7 +2654,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
if (ccb->status == BLOGIC_CCB_RESET &&
ccb->tgt_id == tgt_id) {
command = ccb->command;
- blogic_dealloc_ccb(ccb, 1);
+ blogic_dealloc_ccb(host, ccb, 1);
adapter->active_cmds[tgt_id]--;
command->result = DID_RESET << 16;
scsi_done(command);
@@ -2721,7 +2725,7 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
/*
Place CCB back on the Host Adapter's free list.
*/
- blogic_dealloc_ccb(ccb, 1);
+ blogic_dealloc_ccb(host, ccb, 1);
/*
Call the SCSI Command Completion Routine.
*/
@@ -2740,11 +2744,12 @@ static void blogic_process_ccbs(struct blogic_adapter *adapter)
static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
{
struct blogic_adapter *adapter = (struct blogic_adapter *) devid;
+ struct Scsi_Host *host = adapter->scsi_host;
unsigned long processor_flag;
/*
Acquire exclusive access to Host Adapter.
*/
- spin_lock_irqsave(&adapter->scsi_host->host_lock, processor_flag);
+ spin_lock_irqsave(&host->host_lock, processor_flag);
/*
Handle Interrupts appropriately for each Host Adapter type.
*/
@@ -2794,25 +2799,25 @@ static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
Process any completed CCBs.
*/
if (adapter->firstccb != NULL)
- blogic_process_ccbs(adapter);
+ blogic_process_ccbs(host);
/*
Reset the Host Adapter if requested.
*/
if (adapter->adapter_extreset) {
blogic_warn("Resetting %s due to External SCSI Bus Reset\n", adapter, adapter->full_model);
blogic_inc_count(&adapter->ext_resets);
- blogic_resetadapter(adapter, false);
+ blogic_resetadapter(host, false);
adapter->adapter_extreset = false;
} else if (adapter->adapter_intern_err) {
blogic_warn("Resetting %s due to Host Adapter Internal Error\n", adapter, adapter->full_model);
blogic_inc_count(&adapter->adapter_intern_errors);
- blogic_resetadapter(adapter, true);
+ blogic_resetadapter(host, true);
adapter->adapter_intern_err = false;
}
/*
Release exclusive access to Host Adapter.
*/
- spin_unlock_irqrestore(&adapter->scsi_host->host_lock, processor_flag);
+ spin_unlock_irqrestore(&host->host_lock, processor_flag);
return IRQ_HANDLED;
}
@@ -2823,9 +2828,10 @@ static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
already have been acquired by the caller.
*/
-static bool blogic_write_outbox(struct blogic_adapter *adapter,
+static bool blogic_write_outbox(struct Scsi_Host *host,
enum blogic_action action, struct blogic_ccb *ccb)
{
+ struct blogic_adapter *adapter = (void *)host->hostdata;
struct blogic_outbox *next_outbox;
next_outbox = adapter->next_outbox;
@@ -2859,17 +2865,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(shost, false);
+ spin_unlock_irq(&shost->host_lock);
- rc = blogic_resetadapter(adapter, false);
- spin_unlock_irq(&SCpnt->device->host->host_lock);
return rc;
}
@@ -2878,11 +2883,11 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt)
Outgoing Mailbox for execution by the associated Host Adapter.
*/
-static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
+static enum scsi_qc_status blogic_qcmd_lck(struct Scsi_Host *shost, struct scsi_cmnd *command)
{
void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
struct blogic_adapter *adapter =
- (struct blogic_adapter *) command->device->host->hostdata;
+ (struct blogic_adapter *) shost->hostdata;
struct blogic_tgt_flags *tgt_flags =
&adapter->tgt_flags[command->device->id];
struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
@@ -2913,12 +2918,12 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
probably hung so signal an error as a Host Adapter Hard Reset
should be initiated soon.
*/
- ccb = blogic_alloc_ccb(adapter);
+ ccb = blogic_alloc_ccb(shost);
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);
- ccb = blogic_alloc_ccb(adapter);
+ spin_lock_irq(&shost->host_lock);
+ ccb = blogic_alloc_ccb(shost);
if (ccb == NULL) {
command->result = DID_ERROR << 16;
comp_cb(command);
@@ -3046,7 +3051,7 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
blogic_err("DMA mapping for sense data buffer failed\n",
adapter);
- blogic_dealloc_ccb(ccb, 0);
+ blogic_dealloc_ccb(shost, ccb, 0);
return SCSI_MLQUEUE_HOST_BUSY;
}
ccb->sensedata = sense_buf;
@@ -3061,15 +3066,15 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
so signal an error as a Host Adapter Hard Reset should
be initiated soon.
*/
- if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
- spin_unlock_irq(&adapter->scsi_host->host_lock);
+ if (!blogic_write_outbox(shost, BLOGIC_MBOX_START, ccb)) {
+ 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);
- if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
+ spin_lock_irq(&shost->host_lock);
+ if (!blogic_write_outbox(shost, BLOGIC_MBOX_START,
ccb)) {
blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);
- blogic_dealloc_ccb(ccb, 1);
+ blogic_dealloc_ccb(shost, ccb, 1);
command->result = DID_ERROR << 16;
scsi_done(command);
}
@@ -3089,12 +3094,20 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
pending.
*/
if (ccb->status == BLOGIC_CCB_COMPLETE)
- blogic_process_ccbs(adapter);
+ blogic_process_ccbs(shost);
}
return 0;
}
-static DEF_SCSI_QCMD(blogic_qcmd)
+static enum scsi_qc_status blogic_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
+{
+ enum scsi_qc_status rc;
+
+ spin_lock_irq(&shost->host_lock);
+ rc = blogic_qcmd_lck(shost, cmd);
+ spin_unlock_irq(&shost->host_lock);
+ return rc;
+}
#if 0
/*
@@ -3103,9 +3116,8 @@ static DEF_SCSI_QCMD(blogic_qcmd)
static int blogic_abort(struct scsi_cmnd *command)
{
- struct blogic_adapter *adapter =
- (struct blogic_adapter *) command->device->host->hostdata;
-
+ struct Scsi_Host *const shost = command->device->host;
+ struct blogic_adapter *adapter = (void *) shost->hostdata;
int tgt_id = command->device->id;
struct blogic_ccb *ccb;
blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
@@ -3144,7 +3156,7 @@ static int blogic_abort(struct scsi_cmnd *command)
adapter->fw_ver[0] < '5') {
blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
return FAILURE;
- } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
+ } else if (blogic_write_outbox(shost, BLOGIC_MBOX_ABORT,
ccb)) {
blogic_warn("Aborting CCB #%ld to Target %d\n",
adapter, ccb->serial, tgt_id);
@@ -3169,7 +3181,7 @@ static int blogic_abort(struct scsi_cmnd *command)
may still be pending.
*/
if (ccb->status == BLOGIC_CCB_COMPLETE)
- blogic_process_ccbs(adapter);
+ blogic_process_ccbs(shost);
return SUCCESS;
}
return SUCCESS;
@@ -3181,8 +3193,9 @@ static int blogic_abort(struct scsi_cmnd *command)
currently executing SCSI Commands as having been Reset.
*/
-static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
+static int blogic_resetadapter(struct Scsi_Host *host, bool hard_reset)
{
+ struct blogic_adapter *adapter = (void *)host->hostdata;
struct blogic_ccb *ccb;
int tgt_id;
@@ -3203,7 +3216,7 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
if (ccb->status == BLOGIC_CCB_ACTIVE)
- blogic_dealloc_ccb(ccb, 1);
+ blogic_dealloc_ccb(host, ccb, 1);
/*
* Wait a few seconds between the Host Adapter Hard Reset which
* initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
@@ -3212,9 +3225,9 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
*/
if (hard_reset) {
- spin_unlock_irq(&adapter->scsi_host->host_lock);
+ spin_unlock_irq(&host->host_lock);
blogic_delay(adapter->bus_settle_time);
- spin_lock_irq(&adapter->scsi_host->host_lock);
+ spin_lock_irq(&host->host_lock);
}
for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
index 24697a5bedc8..6ace3c307a90 100644
--- a/drivers/scsi/BusLogic.h
+++ b/drivers/scsi/BusLogic.h
@@ -1279,7 +1279,7 @@ 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 Scsi_Host *host, bool hard_reset);
static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
static int __init blogic_setup(char *);
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 05/54] scsi: BusLogic: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (3 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 06/54] scsi: NCR5380: " Bart Van Assche
` (48 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Khalid Aziz, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements with __must_hold() annotations to
prepare the BusLogic driver for enabling compiler-based lock context
analysis.
Cc: Khalid Aziz <khalid@gonehiking.org>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/BusLogic.c | 6 ++++++
drivers/scsi/BusLogic.h | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 75aaf35383a9..4179f29b3066 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -277,6 +277,7 @@ static void blogic_create_addlccbs(struct blogic_adapter *adapter,
*/
static struct blogic_ccb *blogic_alloc_ccb(struct Scsi_Host *host)
+ __must_hold(&host->host_lock)
{
struct blogic_adapter *adapter = (void *)host->hostdata;
static unsigned long serial;
@@ -310,6 +311,7 @@ static struct blogic_ccb *blogic_alloc_ccb(struct Scsi_Host *host)
static void blogic_dealloc_ccb(struct Scsi_Host *host, struct blogic_ccb *ccb,
int dma_unmap)
+ __must_hold(&host->host_lock)
{
struct blogic_adapter *adapter = ccb->adapter;
@@ -2599,6 +2601,7 @@ static void blogic_scan_inbox(struct blogic_adapter *adapter)
*/
static void blogic_process_ccbs(struct Scsi_Host *host)
+ __must_hold(&host->host_lock)
{
struct blogic_adapter *adapter = (void *)host->hostdata;
@@ -2830,6 +2833,7 @@ static irqreturn_t blogic_inthandler(int irq_ch, void *devid)
static bool blogic_write_outbox(struct Scsi_Host *host,
enum blogic_action action, struct blogic_ccb *ccb)
+ __must_hold(&host->host_lock)
{
struct blogic_adapter *adapter = (void *)host->hostdata;
struct blogic_outbox *next_outbox;
@@ -2884,6 +2888,7 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt)
*/
static enum scsi_qc_status blogic_qcmd_lck(struct Scsi_Host *shost, struct scsi_cmnd *command)
+ __must_hold(&shost->host_lock)
{
void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
struct blogic_adapter *adapter =
@@ -3194,6 +3199,7 @@ static int blogic_abort(struct scsi_cmnd *command)
*/
static int blogic_resetadapter(struct Scsi_Host *host, bool hard_reset)
+ __must_hold(&host->host_lock)
{
struct blogic_adapter *adapter = (void *)host->hostdata;
struct blogic_ccb *ccb;
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
index 6ace3c307a90..455d442525f6 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 Scsi_Host *host, bool hard_reset);
+static int blogic_resetadapter(struct Scsi_Host *host, bool hard_reset)
+ __must_hold(&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] 64+ messages in thread
* [PATCH v4 06/54] scsi: NCR5380: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (4 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 05/54] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-26 0:42 ` Finn Thain
2026-09-25 18:25 ` [PATCH v4 07/54] scsi: aacraid: Enable " Bart Van Assche
` (47 subsequent siblings)
53 siblings, 1 reply; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Finn Thain, Michael Schmitz,
James E.J. Bottomley, Martin K. Petersen
Pass the struct NCR5380_hostdata pointer directly to NCR5380_select()
and NCR5380_information_transfer() instead of the struct Scsi_Host
pointer. This ensures that the lock context annotations
(__releases(&hostdata->lock) and __acquires(&hostdata->lock)) refer to
a function argument. Update callers and function prototypes accordingly.
Cc: Finn Thain <fthain@linux-m68k.org>
Cc: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/NCR5380.c | 19 ++++++++++---------
drivers/scsi/NCR5380.h | 5 +++--
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 006dcf981218..6afbd5936892 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -718,7 +718,7 @@ static void NCR5380_main(struct work_struct *work)
* entire unit.
*/
- if (!NCR5380_select(instance, cmd)) {
+ if (!NCR5380_select(hostdata, cmd)) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
} else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
@@ -728,7 +728,7 @@ static void NCR5380_main(struct work_struct *work)
}
if (hostdata->connected && !hostdata->dma_len) {
dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
- NCR5380_information_transfer(instance);
+ NCR5380_information_transfer(hostdata);
done = 0;
}
if (!hostdata->connected) {
@@ -937,7 +937,7 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
/**
* NCR5380_select - attempt arbitration and selection for a given command
- * @instance: the Scsi_Host instance
+ * @hostdata: host private data
* @cmd: the scsi_cmnd to execute
*
* This routine establishes an I_T_L nexus for a SCSI command. This involves
@@ -960,10 +960,11 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
* cmd->result host byte set to DID_BAD_TARGET.
*/
-static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+static bool NCR5380_select(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *cmd)
__releases(&hostdata->lock) __acquires(&hostdata->lock)
{
- struct NCR5380_hostdata *hostdata = shost_priv(instance);
+ struct Scsi_Host *instance = hostdata->host;
unsigned char tmp[3], phase;
unsigned char *data;
int len;
@@ -1643,23 +1644,23 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
}
/*
- * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
+ * Function : NCR5380_information_transfer(struct NCR5380_hostdata *hostdata)
*
* Purpose : run through the various SCSI phases and do as the target
* directs us to. Operates on the currently connected command,
* instance->connected.
*
- * Inputs : instance, instance for which we are doing commands
+ * Inputs : hostdata, the private host data
*
* Side effects : SCSI things happen, the disconnected queue will be
* modified if a command disconnects, *instance->connected will
* change.
*/
-static void NCR5380_information_transfer(struct Scsi_Host *instance)
+static void NCR5380_information_transfer(struct NCR5380_hostdata *hostdata)
__releases(&hostdata->lock) __acquires(&hostdata->lock)
{
- struct NCR5380_hostdata *hostdata = shost_priv(instance);
+ struct Scsi_Host *instance = hostdata->host;
unsigned char msgout = NOP;
int sink = 0;
int len;
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index d402d4bffcb2..450b08da5858 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -278,12 +278,13 @@ static void NCR5380_print(struct Scsi_Host *instance);
static int NCR5380_init(struct Scsi_Host *instance, int flags);
static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
static void NCR5380_exit(struct Scsi_Host *instance);
-static void NCR5380_information_transfer(struct Scsi_Host *instance);
+static void NCR5380_information_transfer(struct NCR5380_hostdata *hostdata);
static irqreturn_t NCR5380_intr(int irq, void *dev_id);
static void NCR5380_main(struct work_struct *work);
static const char *NCR5380_info(struct Scsi_Host *instance);
static void NCR5380_reselect(struct Scsi_Host *instance);
-static bool NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
+static bool NCR5380_select(struct NCR5380_hostdata *hostdata,
+ struct scsi_cmnd *);
static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
static void NCR5380_transfer_pio(struct Scsi_Host *instance,
unsigned char *phase, int *count,
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 07/54] scsi: aacraid: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (5 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 06/54] scsi: NCR5380: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 08/54] scsi: aha152x: Prepare for enabling " Bart Van Assche
` (46 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Adaptec OEM Raid Solutions,
James E.J. Bottomley, Martin K. Petersen
Document the aac_send_reset_adapter() locking requirements with
__must_hold(). Annotate functions that perform conditional locking with
__context_unsafe(). Enable lock 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 347d480a39b0..0dba4406494a 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] 64+ messages in thread
* [PATCH v4 08/54] scsi: aha152x: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (6 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 07/54] scsi: aacraid: Enable " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 09/54] scsi: aic7xxx: Enable " Bart Van Assche
` (45 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Juergen E. Fischer,
James E.J. Bottomley, Martin K. Petersen
Annotate aha152x_error() with __noreturn. This suppresses a lock context
analysis compiler warning if lock context analysis is enabled.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/aha152x.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index e3ccb6bb62c0..d751dc8093cc 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -636,7 +636,7 @@ static struct {
/* setup & interrupt */
static irqreturn_t intr(int irq, void *dev_id);
static void reset_ports(struct Scsi_Host *shpnt);
-static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
+static void __noreturn aha152x_error(struct Scsi_Host *shpnt, char *msg);
static void done(struct Scsi_Host *shpnt, unsigned char status_byte,
unsigned char host_byte);
@@ -2441,7 +2441,7 @@ static void is_complete(struct Scsi_Host *shpnt)
/*
* Dump the current driver status and panic
*/
-static void aha152x_error(struct Scsi_Host *shpnt, char *msg)
+static void __noreturn aha152x_error(struct Scsi_Host *shpnt, char *msg)
{
shost_printk(KERN_EMERG, shpnt, "%s\n", msg);
show_queues(shpnt);
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 09/54] scsi: aic7xxx: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (7 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 08/54] scsi: aha152x: Prepare for enabling " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 10/54] scsi: aic94xx: " Bart Van Assche
` (44 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Hannes Reinecke,
James E.J. Bottomley, Martin K. Petersen
Annotate ahd_lock() and ahc_lock() with __acquires() and ahd_unlock() and
ahc_unlock() with __releases(). Enable lock context analysis for the
aic7xxx driver by setting CONTEXT_ANALYSIS in the Makefile.
Cc: Hannes Reinecke <hare@suse.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/aic7xxx/Makefile | 2 ++
drivers/scsi/aic7xxx/aic79xx_osm.h | 2 ++
drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 ++
3 files changed, 6 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
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] 64+ messages in thread
* [PATCH v4 10/54] scsi: aic94xx: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (8 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 09/54] scsi: aic7xxx: Enable " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 11/54] scsi: arcmsr: " Bart Van Assche
` (43 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 11/54] scsi: arcmsr: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (9 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 10/54] scsi: aic94xx: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 12/54] scsi: libiscsi: Pass the session pointer directly to several functions Bart Van Assche
` (42 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 12/54] scsi: libiscsi: Pass the session pointer directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (10 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 11/54] scsi: arcmsr: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 13/54] scsi: libiscsi: Prepare for enabling lock context analysis Bart Van Assche
` (41 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Lee Duncan, Chris Leech,
Mike Christie, Sagi Grimberg, Max Gurtovoy, Jason Gunthorpe,
Leon Romanovsky, Ketan Mukadam, James E.J. Bottomley,
Martin K. Petersen, Nilesh Javali, Manish Rangankar,
GR-QLogic-Storage-Upstream, Kees Cook
Pass the struct iscsi_session pointer directly to all functions that must
be called with an iscsi_session synchronization object held.
Update the callers of the modified functions in the iSER, be2iscsi, bnx2i,
cxgbi, libiscsi, qedi and qla4xxx drivers.
This patch prepares for enabling compile-time lock context analysis in
libiscsi. No functionality has been changed.
Cc: Lee Duncan <lduncan@suse.com>
Cc: Chris Leech <cleech@redhat.com>
Cc: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/infiniband/ulp/iser/iser_initiator.c | 3 +-
drivers/scsi/be2iscsi/be_main.c | 13 +-
drivers/scsi/bnx2i/bnx2i_hwi.c | 40 ++--
drivers/scsi/cxgbi/libcxgbi.c | 8 +-
drivers/scsi/libiscsi.c | 237 ++++++++++---------
drivers/scsi/libiscsi_tcp.c | 17 +-
drivers/scsi/qedi/qedi_fw.c | 34 +--
drivers/scsi/qla4xxx/ql4_isr.c | 8 +-
include/scsi/libiscsi.h | 16 +-
9 files changed, 204 insertions(+), 172 deletions(-)
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index 12a2d12fef07..d8e732425e77 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -604,7 +604,8 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
return -EPROTO;
}
- task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt);
+ task = iscsi_itt_to_ctask(iser_conn->iscsi_conn->session,
+ iser_conn->iscsi_conn, hdr->itt);
if (likely(task)) {
struct iscsi_iser_task *iser_task = task->dd_data;
struct iser_fr_desc *desc;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index fd18d4d3d219..c8ee0473a1dd 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1178,7 +1178,7 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
scsi_dma_unmap(io_task->scsi_cmnd);
io_task->scsi_cmnd = NULL;
}
- iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
+ iscsi_complete_scsi_task(conn->session, task, exp_cmdsn, max_cmdsn);
}
static void
@@ -1205,7 +1205,7 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn,
hdr->dlength[2] = 0;
hdr->hlength = 0;
hdr->itt = io_task->libiscsi_itt;
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
+ __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)hdr, NULL, 0);
}
static void
@@ -1226,7 +1226,7 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
csol_cqe->cmd_wnd - 1);
hdr->itt = io_task->libiscsi_itt;
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
+ __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)hdr, NULL, 0);
}
static void
@@ -1260,7 +1260,7 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
spin_lock_bh(&session->back_lock);
task = pwrb_handle->pio_handle;
if (task)
- __iscsi_put_task(task);
+ __iscsi_put_task(session, task);
spin_unlock_bh(&session->back_lock);
}
@@ -1281,7 +1281,7 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
hdr->opcode = ISCSI_OP_NOOP_IN;
hdr->itt = io_task->libiscsi_itt;
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
+ __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)hdr, NULL, 0);
}
static void adapter_get_sol_cqe(struct beiscsi_hba *phba,
@@ -1460,7 +1460,8 @@ beiscsi_complete_pdu(struct beiscsi_conn *beiscsi_conn,
code);
return 1;
}
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)phdr, pdata, dlen);
+ __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)phdr, pdata,
+ dlen);
return 0;
}
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index d24cc2c795d6..4d4eca23d471 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -383,6 +383,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
struct iscsi_task *mtask)
{
struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data;
+ struct iscsi_session *session = conn->session;
struct iscsi_tm *tmfabort_hdr;
struct scsi_cmnd *ref_sc;
struct iscsi_task *ctask;
@@ -404,7 +405,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
switch (tmfabort_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) {
case ISCSI_TM_FUNC_ABORT_TASK:
case ISCSI_TM_FUNC_TASK_REASSIGN:
- ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt);
+ ctask = iscsi_itt_to_task(session, conn, tmfabort_hdr->rtt);
if (!ctask || !ctask->sc)
/*
* the iscsi layer must have completed the cmd while
@@ -1347,7 +1348,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session,
resp_cqe = (struct bnx2i_cmd_response *)cqe;
spin_lock_bh(&session->back_lock);
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
resp_cqe->itt & ISCSI_CMD_RESPONSE_INDEX);
if (!task)
goto fail;
@@ -1414,7 +1415,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session,
}
done:
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr,
conn->data, datalen);
fail:
spin_unlock_bh(&session->back_lock);
@@ -1443,7 +1444,7 @@ static int bnx2i_process_login_resp(struct iscsi_session *session,
login = (struct bnx2i_login_response *) cqe;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
login->itt & ISCSI_LOGIN_RESPONSE_INDEX);
if (!task)
goto done;
@@ -1481,7 +1482,7 @@ static int bnx2i_process_login_resp(struct iscsi_session *session,
}
}
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr,
bnx2i_conn->gen_pdu.resp_buf,
bnx2i_conn->gen_pdu.resp_wr_ptr - bnx2i_conn->gen_pdu.resp_buf);
done:
@@ -1511,7 +1512,8 @@ static int bnx2i_process_text_resp(struct iscsi_session *session,
text = (struct bnx2i_text_response *) cqe;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX);
+ task = iscsi_itt_to_task(session, conn,
+ text->itt & ISCSI_LOGIN_RESPONSE_INDEX);
if (!task)
goto done;
@@ -1541,7 +1543,7 @@ static int bnx2i_process_text_resp(struct iscsi_session *session,
bnx2i_conn->gen_pdu.resp_wr_ptr++;
}
}
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr,
bnx2i_conn->gen_pdu.resp_buf,
bnx2i_conn->gen_pdu.resp_wr_ptr -
bnx2i_conn->gen_pdu.resp_buf);
@@ -1570,7 +1572,7 @@ static int bnx2i_process_tmf_resp(struct iscsi_session *session,
tmf_cqe = (struct bnx2i_tmf_response *)cqe;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
tmf_cqe->itt & ISCSI_TMF_RESPONSE_INDEX);
if (!task)
goto done;
@@ -1583,7 +1585,7 @@ static int bnx2i_process_tmf_resp(struct iscsi_session *session,
resp_hdr->itt = task->hdr->itt;
resp_hdr->response = tmf_cqe->response;
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
done:
spin_unlock(&session->back_lock);
return 0;
@@ -1609,7 +1611,7 @@ static int bnx2i_process_logout_resp(struct iscsi_session *session,
logout = (struct bnx2i_logout_response *) cqe;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
logout->itt & ISCSI_LOGOUT_RESPONSE_INDEX);
if (!task)
goto done;
@@ -1628,7 +1630,7 @@ static int bnx2i_process_logout_resp(struct iscsi_session *session,
resp_hdr->t2wait = cpu_to_be32(logout->time_to_wait);
resp_hdr->t2retain = cpu_to_be32(logout->time_to_retain);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD;
done:
@@ -1654,10 +1656,10 @@ static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session,
nop_in = (struct bnx2i_nop_in_msg *)cqe;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
nop_in->itt & ISCSI_NOP_IN_MSG_INDEX);
if (task)
- __iscsi_put_task(task);
+ __iscsi_put_task(session, task);
spin_unlock(&session->back_lock);
}
@@ -1713,7 +1715,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
}
/* this is a response to one of our nop-outs */
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
(itt_t) (nop_in->itt & ISCSI_NOP_IN_MSG_INDEX));
if (task) {
hdr->flags = ISCSI_FLAG_CMD_FINAL;
@@ -1722,7 +1724,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session,
memcpy(&hdr->lun, nop_in->lun, 8);
}
done:
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, NULL, 0);
spin_unlock(&session->back_lock);
return tgt_async_nop;
@@ -1773,7 +1775,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,
+ __iscsi_complete_pdu(session, bnx2i_conn->cls_conn->dd_data,
(struct iscsi_hdr *)resp_hdr, NULL, 0);
spin_unlock(&session->back_lock);
}
@@ -1811,7 +1813,7 @@ static void bnx2i_process_reject_mesg(struct iscsi_session *session,
hdr->max_cmdsn = cpu_to_be32(reject->max_cmd_sn);
hdr->exp_cmdsn = cpu_to_be32(reject->exp_cmd_sn);
hdr->ffffffff = cpu_to_be32(RESERVED_ITT);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, conn->data,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, conn->data,
reject->data_length);
spin_unlock(&session->back_lock);
}
@@ -1834,7 +1836,7 @@ static void bnx2i_process_cmd_cleanup_resp(struct iscsi_session *session,
cmd_clean_rsp = (struct bnx2i_cleanup_response *)cqe;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(conn,
+ task = iscsi_itt_to_task(session, conn,
cmd_clean_rsp->itt & ISCSI_CLEANUP_RESPONSE_INDEX);
if (!task)
printk(KERN_ALERT "bnx2i: cmd clean ITT %x not active\n",
@@ -1908,7 +1910,7 @@ static int bnx2i_queue_scsi_cmd_resp(struct iscsi_session *session,
int rc = 0;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_task(bnx2i_conn->cls_conn->dd_data,
+ task = iscsi_itt_to_task(session, bnx2i_conn->cls_conn->dd_data,
cqe->itt & ISCSI_CMD_RESPONSE_INDEX);
if (!task || !task->sc) {
spin_unlock(&session->back_lock);
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index ea9631bfe2e2..d73a6578b461 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1537,9 +1537,11 @@ skb_read_pdu_bhs(struct cxgbi_sock *csk, struct iscsi_conn *conn,
* for the last pdu of a sequence.
*/
itt_t itt = ((struct iscsi_data *)skb->data)->itt;
- struct iscsi_task *task = iscsi_itt_to_ctask(conn, itt);
- u32 data_sn = be32_to_cpu(((struct iscsi_data *)
- skb->data)->datasn);
+ struct iscsi_task *task;
+ u32 data_sn;
+
+ task = iscsi_itt_to_ctask(conn->session, conn, itt);
+ data_sn = be32_to_cpu(((struct iscsi_data *)skb->data)->datasn);
if (task && task->sc) {
struct iscsi_tcp_task *tcp_task = task->dd_data;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 7637aacd6037..179de08ca515 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -445,16 +445,17 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
/**
* iscsi_free_task - free a task
+ * @session: iscsi session
* @task: iscsi cmd task
*
* Must be called with session back_lock.
* This function returns the scsi command to scsi-ml or cleans
* up mgmt tasks then returns the task to the pool.
*/
-static void iscsi_free_task(struct iscsi_task *task)
+static void iscsi_free_task(struct iscsi_session *session,
+ struct iscsi_task *task)
{
struct iscsi_conn *conn = task->conn;
- struct iscsi_session *session = conn->session;
struct scsi_cmnd *sc = task->sc;
int oldstate = task->state;
@@ -492,14 +493,15 @@ EXPORT_SYMBOL_GPL(iscsi_get_task);
/**
* __iscsi_put_task - drop the refcount on a task
+ * @session: iscsi session
* @task: iscsi_task to drop the refcount on
*
* The back_lock must be held when calling in case it frees the task.
*/
-void __iscsi_put_task(struct iscsi_task *task)
+void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task)
{
if (refcount_dec_and_test(&task->refcount))
- iscsi_free_task(task);
+ iscsi_free_task(session, task);
}
EXPORT_SYMBOL_GPL(__iscsi_put_task);
@@ -509,7 +511,7 @@ void iscsi_put_task(struct iscsi_task *task)
if (refcount_dec_and_test(&task->refcount)) {
spin_lock_bh(&session->back_lock);
- iscsi_free_task(task);
+ iscsi_free_task(session, task);
spin_unlock_bh(&session->back_lock);
}
}
@@ -517,17 +519,18 @@ EXPORT_SYMBOL_GPL(iscsi_put_task);
/**
* iscsi_complete_task - finish a task
+ * @session: iscsi session
* @task: iscsi cmd task
* @state: state to complete task with
*
* Must be called with session back_lock.
*/
-static void iscsi_complete_task(struct iscsi_task *task, int state)
+static void iscsi_complete_task(struct iscsi_session *session,
+ struct iscsi_task *task, int state)
{
struct iscsi_conn *conn = task->conn;
- ISCSI_DBG_SESSION(conn->session,
- "complete task itt 0x%x state %d sc %p\n",
+ ISCSI_DBG_SESSION(session, "complete task itt 0x%x state %d sc %p\n",
task->itt, task->state, task->sc);
if (task->state == ISCSI_TASK_COMPLETED ||
task->state == ISCSI_TASK_ABRT_TMF ||
@@ -541,11 +544,12 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
WRITE_ONCE(conn->ping_task, NULL);
/* release get from queueing */
- __iscsi_put_task(task);
+ __iscsi_put_task(session, task);
}
/**
* iscsi_complete_scsi_task - finish scsi task normally
+ * @session: iscsi session
* @task: iscsi task for scsi cmd
* @exp_cmdsn: expected cmd sn in cpu format
* @max_cmdsn: max cmd sn in cpu format
@@ -555,23 +559,25 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
*
* Called with session back_lock
*/
-void iscsi_complete_scsi_task(struct iscsi_task *task,
+void iscsi_complete_scsi_task(struct iscsi_session *session,
+ struct iscsi_task *task,
uint32_t exp_cmdsn, uint32_t max_cmdsn)
{
struct iscsi_conn *conn = task->conn;
- ISCSI_DBG_SESSION(conn->session, "[itt 0x%x]\n", task->itt);
+ ISCSI_DBG_SESSION(session, "[itt 0x%x]\n", task->itt);
conn->last_recv = jiffies;
- __iscsi_update_cmdsn(conn->session, exp_cmdsn, max_cmdsn);
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ __iscsi_update_cmdsn(session, exp_cmdsn, max_cmdsn);
+ iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED);
}
EXPORT_SYMBOL_GPL(iscsi_complete_scsi_task);
/*
* Must be called with back and frwd lock
*/
-static bool cleanup_queued_task(struct iscsi_task *task)
+static bool cleanup_queued_task(struct iscsi_session *session,
+ struct iscsi_task *task)
{
struct iscsi_conn *conn = task->conn;
bool early_complete = false;
@@ -592,17 +598,17 @@ static bool cleanup_queued_task(struct iscsi_task *task)
*/
if (task->state == ISCSI_TASK_RUNNING ||
task->state == ISCSI_TASK_COMPLETED)
- __iscsi_put_task(task);
+ __iscsi_put_task(session, task);
}
- if (conn->session->running_aborted_task == task) {
- conn->session->running_aborted_task = NULL;
- __iscsi_put_task(task);
+ if (session->running_aborted_task == task) {
+ session->running_aborted_task = NULL;
+ __iscsi_put_task(session, task);
}
if (conn->task == task) {
conn->task = NULL;
- __iscsi_put_task(task);
+ __iscsi_put_task(session, task);
}
return early_complete;
@@ -612,13 +618,13 @@ static bool cleanup_queued_task(struct iscsi_task *task)
* session back and frwd lock must be held and if not called for a task that
* is still pending or from the xmit thread, then xmit thread must be suspended
*/
-static void __fail_scsi_task(struct iscsi_task *task, int err)
+static void __fail_scsi_task(struct iscsi_session *session,
+ struct iscsi_task *task, int err)
{
- struct iscsi_conn *conn = task->conn;
struct scsi_cmnd *sc;
int state;
- if (cleanup_queued_task(task))
+ if (cleanup_queued_task(session, task))
return;
if (task->state == ISCSI_TASK_PENDING) {
@@ -626,7 +632,7 @@ static void __fail_scsi_task(struct iscsi_task *task, int err)
* cmd never made it to the xmit thread, so we should not count
* the cmd in the sequencing
*/
- conn->session->queued_cmdsn--;
+ session->queued_cmdsn--;
/* it was never sent so just complete like normal */
state = ISCSI_TASK_COMPLETED;
} else if (err == DID_TRANSPORT_DISRUPTED)
@@ -637,15 +643,14 @@ static void __fail_scsi_task(struct iscsi_task *task, int err)
sc = task->sc;
sc->result = err << 16;
scsi_set_resid(sc, scsi_bufflen(sc));
- iscsi_complete_task(task, state);
+ iscsi_complete_task(session, task, state);
}
-static void fail_scsi_task(struct iscsi_task *task, int err)
+static void fail_scsi_task(struct iscsi_session *session,
+ struct iscsi_task *task, int err)
{
- struct iscsi_session *session = task->conn->session;
-
spin_lock_bh(&session->back_lock);
- __fail_scsi_task(task, err);
+ __fail_scsi_task(session, task, err);
spin_unlock_bh(&session->back_lock);
}
@@ -857,6 +862,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
/**
* iscsi_scsi_cmd_rsp - SCSI Command Response processing
+ * @session: iscsi session
* @conn: iscsi connection
* @hdr: iscsi header
* @task: scsi command task
@@ -866,12 +872,12 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
* iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and
* then completes the command and task. called under back_lock
**/
-static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+static void iscsi_scsi_cmd_rsp(struct iscsi_session *session,
+ struct iscsi_conn *conn, struct iscsi_hdr *hdr,
struct iscsi_task *task, char *data,
int datalen)
{
struct iscsi_scsi_rsp *rhdr = (struct iscsi_scsi_rsp *)hdr;
- struct iscsi_session *session = conn->session;
struct scsi_cmnd *sc = task->sc;
iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
@@ -950,11 +956,12 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
ISCSI_DBG_SESSION(session, "cmd rsp done [sc %p res %d itt 0x%x]\n",
sc, sc->result, task->itt);
conn->scsirsp_pdus_cnt++;
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED);
}
/**
* iscsi_data_in_rsp - SCSI Data-In Response processing
+ * @session: iscsi session
* @conn: iscsi connection
* @hdr: iscsi pdu
* @task: scsi command task
@@ -963,8 +970,8 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
* then completes the command and task. called under back_lock
**/
static void
-iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
- struct iscsi_task *task)
+iscsi_data_in_rsp(struct iscsi_session *session, struct iscsi_conn *conn,
+ struct iscsi_hdr *hdr, struct iscsi_task *task)
{
struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr;
struct scsi_cmnd *sc = task->sc;
@@ -972,7 +979,7 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS))
return;
- iscsi_update_cmdsn(conn->session, (struct iscsi_nopin *)hdr);
+ iscsi_update_cmdsn(session, (struct iscsi_nopin *)hdr);
sc->result = (DID_OK << 16) | rhdr->cmd_status;
conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW |
@@ -987,11 +994,11 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
}
- ISCSI_DBG_SESSION(conn->session, "data in with status done "
+ ISCSI_DBG_SESSION(session, "data in with status done "
"[sc %p res %d itt 0x%x]\n",
sc, sc->result, task->itt);
conn->scsirsp_pdus_cnt++;
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED);
}
static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
@@ -1059,6 +1066,7 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
/**
* iscsi_nop_out_rsp - SCSI NOP Response processing
+ * @session: iscsi session
* @task: scsi command task
* @nop: the nop structure
* @data: where to put the data
@@ -1067,7 +1075,8 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
* iscsi_nop_out_rsp handles nop response from use or
* from user space. called under back_lock
**/
-static int iscsi_nop_out_rsp(struct iscsi_task *task,
+static int iscsi_nop_out_rsp(struct iscsi_session *session,
+ struct iscsi_task *task,
struct iscsi_nopin *nop, char *data, int datalen)
{
struct iscsi_conn *conn = task->conn;
@@ -1083,11 +1092,12 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
rc = ISCSI_ERR_CONN_FAILED;
} else
mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout);
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED);
return rc;
}
-static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+static int iscsi_handle_reject(struct iscsi_session *session,
+ struct iscsi_conn *conn, struct iscsi_hdr *hdr,
char *data, int datalen)
{
struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
@@ -1136,26 +1146,27 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
* Just resend.
*/
/* In RX path we are under back lock */
- spin_unlock(&conn->session->back_lock);
- spin_lock(&conn->session->frwd_lock);
+ spin_unlock(&session->back_lock);
+ spin_lock(&session->frwd_lock);
iscsi_send_nopout(conn,
(struct iscsi_nopin*)&rejected_pdu);
- spin_unlock(&conn->session->frwd_lock);
- spin_lock(&conn->session->back_lock);
+ spin_unlock(&session->frwd_lock);
+ spin_lock(&session->back_lock);
} else {
struct iscsi_task *task;
/*
* Our nop as ping got dropped. We know the target
* and transport are ok so just clean up
*/
- task = iscsi_itt_to_task(conn, rejected_pdu.itt);
+ task = iscsi_itt_to_task(session, conn,
+ rejected_pdu.itt);
if (!task) {
iscsi_conn_printk(KERN_ERR, conn,
"Invalid pdu reject. Could "
"not lookup rejected task.\n");
rc = ISCSI_ERR_BAD_ITT;
} else
- rc = iscsi_nop_out_rsp(task,
+ rc = iscsi_nop_out_rsp(session, task,
(struct iscsi_nopin*)&rejected_pdu,
NULL, 0);
}
@@ -1172,6 +1183,7 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
/**
* iscsi_itt_to_task - look up task by itt
+ * @session: iscsi session
* @conn: iscsi connection
* @itt: itt
*
@@ -1180,9 +1192,9 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
*
* The session back_lock must be held.
*/
-struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt)
+struct iscsi_task *iscsi_itt_to_task(struct iscsi_session *session,
+ struct iscsi_conn *conn, itt_t itt)
{
- struct iscsi_session *session = conn->session;
int i;
if (itt == RESERVED_ITT)
@@ -1201,6 +1213,7 @@ EXPORT_SYMBOL_GPL(iscsi_itt_to_task);
/**
* __iscsi_complete_pdu - complete pdu
+ * @session: iscsi session
* @conn: iscsi conn
* @hdr: iscsi header
* @data: data buffer
@@ -1210,10 +1223,9 @@ EXPORT_SYMBOL_GPL(iscsi_itt_to_task);
* queuecommand or send generic. session back_lock must be held and verify
* itt must have been called.
*/
-int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
- char *data, int datalen)
+int __iscsi_complete_pdu(struct iscsi_session *session, struct iscsi_conn *conn,
+ struct iscsi_hdr *hdr, char *data, int datalen)
{
- struct iscsi_session *session = conn->session;
int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0;
struct iscsi_task *task;
uint32_t itt;
@@ -1252,7 +1264,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
spin_lock(&session->back_lock);
break;
case ISCSI_OP_REJECT:
- rc = iscsi_handle_reject(conn, hdr, data, datalen);
+ rc = iscsi_handle_reject(session, conn, hdr, data, datalen);
break;
case ISCSI_OP_ASYNC_EVENT:
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
@@ -1269,7 +1281,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
switch(opcode) {
case ISCSI_OP_SCSI_CMD_RSP:
case ISCSI_OP_SCSI_DATA_IN:
- task = iscsi_itt_to_ctask(conn, hdr->itt);
+ task = iscsi_itt_to_ctask(session, conn, hdr->itt);
if (!task)
return ISCSI_ERR_BAD_ITT;
task->last_xfer = jiffies;
@@ -1284,7 +1296,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
case ISCSI_OP_TEXT_RSP:
case ISCSI_OP_SCSI_TMFUNC_RSP:
case ISCSI_OP_NOOP_IN:
- task = iscsi_itt_to_task(conn, hdr->itt);
+ task = iscsi_itt_to_task(session, conn, hdr->itt);
if (!task)
return ISCSI_ERR_BAD_ITT;
break;
@@ -1294,10 +1306,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
switch(opcode) {
case ISCSI_OP_SCSI_CMD_RSP:
- iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen);
+ iscsi_scsi_cmd_rsp(session, conn, hdr, task, data, datalen);
break;
case ISCSI_OP_SCSI_DATA_IN:
- iscsi_data_in_rsp(conn, hdr, task);
+ iscsi_data_in_rsp(session, conn, hdr, task);
break;
case ISCSI_OP_LOGOUT_RSP:
iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
@@ -1323,7 +1335,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
}
iscsi_tmf_rsp(conn, hdr);
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED);
break;
case ISCSI_OP_NOOP_IN:
iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
@@ -1333,7 +1345,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
}
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
- rc = iscsi_nop_out_rsp(task, (struct iscsi_nopin*)hdr,
+ rc = iscsi_nop_out_rsp(session, task, (struct iscsi_nopin*)hdr,
data, datalen);
break;
default:
@@ -1346,7 +1358,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
recv_pdu:
if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
rc = ISCSI_ERR_CONN_FAILED;
- iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+ iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED);
return rc;
}
EXPORT_SYMBOL_GPL(__iscsi_complete_pdu);
@@ -1354,11 +1366,12 @@ EXPORT_SYMBOL_GPL(__iscsi_complete_pdu);
int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
char *data, int datalen)
{
+ struct iscsi_session *session = conn->session;
int rc;
- spin_lock(&conn->session->back_lock);
- rc = __iscsi_complete_pdu(conn, hdr, data, datalen);
- spin_unlock(&conn->session->back_lock);
+ spin_lock(&session->back_lock);
+ rc = __iscsi_complete_pdu(session, conn, hdr, data, datalen);
+ spin_unlock(&session->back_lock);
return rc;
}
EXPORT_SYMBOL_GPL(iscsi_complete_pdu);
@@ -1397,6 +1410,7 @@ EXPORT_SYMBOL_GPL(iscsi_verify_itt);
/**
* iscsi_itt_to_ctask - look up ctask by itt
+ * @session: iscsi session
* @conn: iscsi connection
* @itt: itt
*
@@ -1404,21 +1418,22 @@ EXPORT_SYMBOL_GPL(iscsi_verify_itt);
*
* The session back_lock must be held.
*/
-struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
+struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_session *session,
+ struct iscsi_conn *conn, itt_t itt)
{
struct iscsi_task *task;
if (iscsi_verify_itt(conn, itt))
return NULL;
- task = iscsi_itt_to_task(conn, itt);
+ task = iscsi_itt_to_task(session, conn, itt);
if (!task || !task->sc)
return NULL;
- if (iscsi_cmd(task->sc)->age != conn->session->age) {
- iscsi_session_printk(KERN_ERR, conn->session,
+ if (iscsi_cmd(task->sc)->age != session->age) {
+ iscsi_session_printk(KERN_ERR, session,
"task's session age %d, expected %d\n",
- iscsi_cmd(task->sc)->age, conn->session->age);
+ iscsi_cmd(task->sc)->age, session->age);
return NULL;
}
@@ -1482,10 +1497,9 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
}
EXPORT_SYMBOL_GPL(iscsi_conn_failure);
-static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
+static int iscsi_check_cmdsn_window_closed(struct iscsi_session *session,
+ struct iscsi_conn *conn)
{
- struct iscsi_session *session = conn->session;
-
/*
* Check for iSCSI window and take care of CmdSN wrap-around
*/
@@ -1499,8 +1513,8 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
return 0;
}
-static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
- bool was_requeue)
+static int iscsi_xmit_task(struct iscsi_session *session, struct iscsi_conn *conn,
+ struct iscsi_task *task, bool was_requeue)
{
int rc;
@@ -1540,9 +1554,9 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task,
return -ENODATA;
}
- spin_unlock_bh(&conn->session->frwd_lock);
- rc = conn->session->tt->xmit_task(task);
- spin_lock_bh(&conn->session->frwd_lock);
+ spin_unlock_bh(&session->frwd_lock);
+ rc = session->tt->xmit_task(task);
+ spin_lock_bh(&session->frwd_lock);
if (!rc) {
/* done with this task */
task->last_xfer = jiffies;
@@ -1599,18 +1613,19 @@ EXPORT_SYMBOL_GPL(iscsi_requeue_task);
**/
static int iscsi_data_xmit(struct iscsi_conn *conn)
{
+ struct iscsi_session *session = conn->session;
struct iscsi_task *task;
int rc = 0;
- spin_lock_bh(&conn->session->frwd_lock);
+ spin_lock_bh(&session->frwd_lock);
if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags)) {
- ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
- spin_unlock_bh(&conn->session->frwd_lock);
+ ISCSI_DBG_SESSION(session, "Tx suspended!\n");
+ spin_unlock_bh(&session->frwd_lock);
return -ENODATA;
}
if (conn->task) {
- rc = iscsi_xmit_task(conn, conn->task, false);
+ rc = iscsi_xmit_task(session, conn, conn->task, false);
if (rc)
goto done;
}
@@ -1627,12 +1642,12 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
list_del_init(&task->running);
if (iscsi_prep_mgmt_task(conn, task)) {
/* regular RX path uses back_lock */
- spin_lock_bh(&conn->session->back_lock);
- __iscsi_put_task(task);
- spin_unlock_bh(&conn->session->back_lock);
+ spin_lock_bh(&session->back_lock);
+ __iscsi_put_task(session, task);
+ spin_unlock_bh(&session->back_lock);
continue;
}
- rc = iscsi_xmit_task(conn, task, false);
+ rc = iscsi_xmit_task(session, conn, task, false);
if (rc)
goto done;
}
@@ -1642,7 +1657,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
/*
* we always do fastlogout - conn stop code will clean up.
*/
- if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
+ if (session->state == ISCSI_STATE_LOGGING_OUT)
break;
task = list_entry(conn->requeue.next, struct iscsi_task,
@@ -1652,7 +1667,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
break;
list_del_init(&task->running);
- rc = iscsi_xmit_task(conn, task, true);
+ rc = iscsi_xmit_task(session, conn, task, true);
if (rc)
goto done;
if (!list_empty(&conn->mgmtqueue))
@@ -1664,19 +1679,19 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
task = list_entry(conn->cmdqueue.next, struct iscsi_task,
running);
list_del_init(&task->running);
- if (conn->session->state == ISCSI_STATE_LOGGING_OUT) {
- fail_scsi_task(task, DID_IMM_RETRY);
+ if (session->state == ISCSI_STATE_LOGGING_OUT) {
+ fail_scsi_task(session, task, DID_IMM_RETRY);
continue;
}
rc = iscsi_prep_scsi_cmd_pdu(task);
if (rc) {
if (rc == -ENOMEM || rc == -EACCES)
- fail_scsi_task(task, DID_IMM_RETRY);
+ fail_scsi_task(session, task, DID_IMM_RETRY);
else
- fail_scsi_task(task, DID_ABORT);
+ fail_scsi_task(session, task, DID_ABORT);
continue;
}
- rc = iscsi_xmit_task(conn, task, false);
+ rc = iscsi_xmit_task(session, conn, task, false);
if (rc)
goto done;
/*
@@ -1690,11 +1705,11 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
goto check_requeue;
}
- spin_unlock_bh(&conn->session->frwd_lock);
+ spin_unlock_bh(&session->frwd_lock);
return -ENODATA;
done:
- spin_unlock_bh(&conn->session->frwd_lock);
+ spin_unlock_bh(&session->frwd_lock);
return rc;
}
@@ -1828,7 +1843,7 @@ enum scsi_qc_status iscsi_queuecommand(struct Scsi_Host *host,
goto fault;
}
- if (iscsi_check_cmdsn_window_closed(conn)) {
+ if (iscsi_check_cmdsn_window_closed(session, conn)) {
reason = FAILURE_WINDOW_CLOSED;
goto reject;
}
@@ -1866,7 +1881,7 @@ enum scsi_qc_status iscsi_queuecommand(struct Scsi_Host *host,
prepd_reject:
spin_lock_bh(&session->back_lock);
- iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
+ iscsi_complete_task(session, task, ISCSI_TASK_REQUEUE_SCSIQ);
spin_unlock_bh(&session->back_lock);
reject:
spin_unlock_bh(&session->frwd_lock);
@@ -1876,7 +1891,7 @@ enum scsi_qc_status iscsi_queuecommand(struct Scsi_Host *host,
prepd_fault:
spin_lock_bh(&session->back_lock);
- iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
+ iscsi_complete_task(session, task, ISCSI_TASK_REQUEUE_SCSIQ);
spin_unlock_bh(&session->back_lock);
fault:
spin_unlock_bh(&session->frwd_lock);
@@ -1913,13 +1928,12 @@ static void iscsi_tmf_timedout(struct timer_list *t)
spin_unlock(&session->frwd_lock);
}
-static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
+static int iscsi_exec_task_mgmt_fn(struct iscsi_session *session,
+ struct iscsi_conn *conn,
struct iscsi_tm *hdr, int age,
int timeout)
__must_hold(&session->frwd_lock)
{
- struct iscsi_session *session = conn->session;
-
if (__iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0)) {
spin_unlock_bh(&session->frwd_lock);
iscsi_conn_printk(KERN_ERR, conn, "Could not send TMF.\n");
@@ -1962,9 +1976,9 @@ 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)
+static void fail_scsi_tasks(struct iscsi_session *session, struct iscsi_conn *conn,
+ u64 lun, int error)
{
- struct iscsi_session *session = conn->session;
struct iscsi_task *task;
int i;
@@ -1993,8 +2007,8 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error)
ISCSI_DBG_SESSION(session,
"failing sc %p itt 0x%x state %d\n",
task->sc, task->itt, task->state);
- __fail_scsi_task(task, error);
- __iscsi_put_task(task);
+ __fail_scsi_task(session, task, error);
+ __iscsi_put_task(session, task);
}
spin_unlock_bh(&session->back_lock);
}
@@ -2415,7 +2429,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
spin_unlock(&session->back_lock);
if (task->state == ISCSI_TASK_PENDING) {
- fail_scsi_task(task, DID_ABORT);
+ fail_scsi_task(session, task, DID_ABORT);
goto success;
}
@@ -2427,7 +2441,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
hdr = &session->tmhdr;
iscsi_prep_abort_task_pdu(task, hdr);
- if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout))
+ if (iscsi_exec_task_mgmt_fn(session, conn, hdr, age,
+ session->abort_timeout))
goto failed;
switch (session->tmf_state) {
@@ -2444,7 +2459,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
* then sent more data for the cmd.
*/
spin_lock_bh(&session->frwd_lock);
- fail_scsi_task(task, DID_ABORT);
+ fail_scsi_task(session, task, DID_ABORT);
session->tmf_state = TMF_INITIAL;
memset(hdr, 0, sizeof(*hdr));
spin_unlock_bh(&session->frwd_lock);
@@ -2541,7 +2556,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
hdr = &session->tmhdr;
iscsi_prep_lun_reset_pdu(sc, hdr);
- if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age,
+ if (iscsi_exec_task_mgmt_fn(session, conn, hdr, session->age,
session->lu_reset_timeout)) {
rc = FAILED;
goto unlock;
@@ -2566,7 +2581,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
spin_lock_bh(&session->frwd_lock);
memset(hdr, 0, sizeof(*hdr));
- fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
+ fail_scsi_tasks(session, conn, sc->device->lun, DID_ERROR);
session->tmf_state = TMF_INITIAL;
spin_unlock_bh(&session->frwd_lock);
@@ -2703,7 +2718,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
hdr = &session->tmhdr;
iscsi_prep_tgt_reset_pdu(sc, hdr);
- if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age,
+ if (iscsi_exec_task_mgmt_fn(session, conn, hdr, session->age,
session->tgt_reset_timeout)) {
rc = FAILED;
goto unlock;
@@ -2728,7 +2743,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
spin_lock_bh(&session->frwd_lock);
memset(hdr, 0, sizeof(*hdr));
- fail_scsi_tasks(conn, -1, DID_ERROR);
+ fail_scsi_tasks(session, conn, -1, DID_ERROR);
session->tmf_state = TMF_INITIAL;
spin_unlock_bh(&session->frwd_lock);
@@ -3374,7 +3389,7 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn)
task->itt, task->state);
spin_lock_bh(&session->back_lock);
- if (cleanup_queued_task(task)) {
+ if (cleanup_queued_task(session, task)) {
spin_unlock_bh(&session->back_lock);
continue;
}
@@ -3382,7 +3397,7 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn)
state = ISCSI_TASK_ABRT_SESS_RECOV;
if (task->state == ISCSI_TASK_PENDING)
state = ISCSI_TASK_COMPLETED;
- iscsi_complete_task(task, state);
+ iscsi_complete_task(session, task, state);
spin_unlock_bh(&session->back_lock);
}
}
@@ -3442,7 +3457,7 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
* flush queues.
*/
spin_lock_bh(&session->frwd_lock);
- fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED);
+ fail_scsi_tasks(session, conn, -1, DID_TRANSPORT_DISRUPTED);
fail_mgmt_tasks(session, conn);
memset(&session->tmhdr, 0, sizeof(session->tmhdr));
spin_unlock_bh(&session->frwd_lock);
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 7223bb18b048..a9c092a80b81 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -529,7 +529,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
int rc;
spin_lock(&session->back_lock);
- task = iscsi_itt_to_ctask(conn, hdr->itt);
+ task = iscsi_itt_to_ctask(session, conn, hdr->itt);
if (!task) {
spin_unlock(&session->back_lock);
return ISCSI_ERR_BAD_ITT;
@@ -677,6 +677,7 @@ iscsi_tcp_process_data_in(struct iscsi_tcp_conn *tcp_conn,
static int
iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
{
+ struct iscsi_session *session = conn->session;
int rc = 0, opcode, ahslen;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_task *task;
@@ -706,14 +707,14 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
switch(opcode) {
case ISCSI_OP_SCSI_DATA_IN:
- spin_lock(&conn->session->back_lock);
- task = iscsi_itt_to_ctask(conn, hdr->itt);
+ spin_lock(&session->back_lock);
+ task = iscsi_itt_to_ctask(session, conn, hdr->itt);
if (!task)
rc = ISCSI_ERR_BAD_ITT;
else
rc = iscsi_tcp_data_in(conn, task);
if (rc) {
- spin_unlock(&conn->session->back_lock);
+ spin_unlock(&session->back_lock);
break;
}
@@ -731,7 +732,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
* update the digest per-entry.
*/
if (conn->datadgst_en &&
- !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD))
+ !(session->tt->caps & CAP_DIGEST_OFFLOAD))
rx_crcp = tcp_conn->rx_crcp;
ISCSI_DBG_TCP(conn, "iscsi_tcp_begin_data_in( "
@@ -746,11 +747,11 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
tcp_conn->in.datalen,
iscsi_tcp_process_data_in,
rx_crcp);
- spin_unlock(&conn->session->back_lock);
+ spin_unlock(&session->back_lock);
return rc;
}
- rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
- spin_unlock(&conn->session->back_lock);
+ rc = __iscsi_complete_pdu(session, conn, hdr, NULL, 0);
+ spin_unlock(&session->back_lock);
break;
case ISCSI_OP_R2T:
if (ahslen) {
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
index 854efa4f61d8..37945f16811b 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -73,7 +73,7 @@ static void qedi_process_logout_resp(struct qedi_ctx *qedi,
spin_unlock(&qedi_conn->list_lock);
cmd->state = RESPONSE_RECEIVED;
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
spin_unlock(&session->back_lock);
}
@@ -138,7 +138,7 @@ static void qedi_process_text_resp(struct qedi_ctx *qedi,
cmd->state = RESPONSE_RECEIVED;
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr,
qedi_conn->gen_pdu.resp_buf,
(qedi_conn->gen_pdu.resp_wr_ptr -
qedi_conn->gen_pdu.resp_buf));
@@ -163,7 +163,8 @@ static void qedi_tmf_resp_work(struct work_struct *work)
goto exit_tmf_resp;
spin_lock(&session->back_lock);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL,
+ 0);
spin_unlock(&session->back_lock);
exit_tmf_resp:
@@ -247,7 +248,8 @@ static void qedi_process_tmf_resp(struct qedi_ctx *qedi,
}
spin_unlock(&qedi_conn->tmf_work_lock);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL,
+ 0);
kfree(resp_hdr_ptr);
unblock_sess:
@@ -304,7 +306,7 @@ static void qedi_process_login_resp(struct qedi_ctx *qedi,
memset(task_ctx, '\0', sizeof(*task_ctx));
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr,
qedi_conn->gen_pdu.resp_buf,
(qedi_conn->gen_pdu.resp_wr_ptr -
qedi_conn->gen_pdu.resp_buf));
@@ -470,7 +472,8 @@ static int qedi_process_nopin_mesg(struct qedi_ctx *qedi,
}
done:
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, bdq_data, pdu_len);
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, bdq_data,
+ pdu_len);
spin_unlock_bh(&session->back_lock);
return tgt_async_nop;
@@ -524,7 +527,7 @@ static void qedi_process_async_mesg(struct qedi_ctx *qedi,
resp_hdr->param2 = cpu_to_be16(cqe_async_msg->param2_rsrv);
resp_hdr->param3 = cpu_to_be16(cqe_async_msg->param3_rsrv);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, bdq_data,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, bdq_data,
pdu_len);
spin_unlock_bh(&session->back_lock);
@@ -567,7 +570,7 @@ static void qedi_process_reject_mesg(struct qedi_ctx *qedi,
hdr->statsn = cpu_to_be32(cqe_reject->stat_sn);
hdr->ffffffff = cpu_to_be32(0xffffffff);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr,
conn->data, pld_len);
spin_unlock_bh(&session->back_lock);
}
@@ -664,7 +667,7 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi,
if (qedi_io_tracing)
qedi_trace_io(qedi, task, cmd->task_id, QEDI_IO_TRACE_RSP);
- __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr,
+ __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr,
conn->data, datalen);
error:
spin_unlock_bh(&session->back_lock);
@@ -722,7 +725,7 @@ static void qedi_process_nopin_local_cmpl(struct qedi_ctx *qedi,
cmd->state = RESPONSE_RECEIVED;
spin_lock_bh(&session->back_lock);
- __iscsi_put_task(task);
+ __iscsi_put_task(session, task);
spin_unlock_bh(&session->back_lock);
}
@@ -1316,6 +1319,7 @@ static void qedi_abort_work(struct work_struct *work)
struct qedi_conn *qedi_conn = qedi_cmd->conn;
struct qedi_ctx *qedi = qedi_conn->qedi;
struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data;
+ struct iscsi_session *session = conn->session;
struct qedi_work_map *list_work = NULL;
struct iscsi_task *mtask;
struct qedi_cmd *cmd;
@@ -1326,16 +1330,16 @@ static void qedi_abort_work(struct work_struct *work)
mtask = qedi_cmd->task;
tmf_hdr = (struct iscsi_tm *)mtask->hdr;
- spin_lock_bh(&conn->session->back_lock);
- ctask = iscsi_itt_to_ctask(conn, tmf_hdr->rtt);
+ spin_lock_bh(&session->back_lock);
+ ctask = iscsi_itt_to_ctask(session, conn, tmf_hdr->rtt);
if (!ctask) {
- spin_unlock_bh(&conn->session->back_lock);
+ spin_unlock_bh(&session->back_lock);
QEDI_ERR(&qedi->dbg_ctx, "Invalid RTT. Letting abort timeout.\n");
goto clear_cleanup;
}
if (iscsi_task_is_completed(ctask)) {
- spin_unlock_bh(&conn->session->back_lock);
+ spin_unlock_bh(&session->back_lock);
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
"Task already completed\n");
/*
@@ -1344,7 +1348,7 @@ static void qedi_abort_work(struct work_struct *work)
*/
goto send_tmf;
}
- spin_unlock_bh(&conn->session->back_lock);
+ spin_unlock_bh(&session->back_lock);
cmd = (struct qedi_cmd *)ctask->dd_data;
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index cf52258ecdde..81989c905c82 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -367,6 +367,7 @@ static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry;
struct ql4_task_data *task_data;
struct iscsi_cls_conn *cls_conn;
+ struct iscsi_session *session;
struct iscsi_conn *conn;
itt_t itt;
uint32_t fw_ddb_index;
@@ -384,9 +385,10 @@ static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha,
cls_conn = ddb_entry->conn;
conn = cls_conn->dd_data;
- spin_lock(&conn->session->back_lock);
- task = iscsi_itt_to_task(conn, itt);
- spin_unlock(&conn->session->back_lock);
+ session = conn->session;
+ spin_lock(&session->back_lock);
+ task = iscsi_itt_to_task(session, conn, itt);
+ spin_unlock(&session->back_lock);
if (task == NULL) {
ql4_printk(KERN_ERR, ha, "%s: Task is NULL\n", __func__);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 3d765c77bcd9..f79b46798edf 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -474,17 +474,21 @@ 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 *,
+extern int __iscsi_complete_pdu(struct iscsi_session *session,
+ struct iscsi_conn *conn, struct iscsi_hdr *,
char *, int);
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);
+struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_session *session,
+ struct iscsi_conn *, itt_t);
+struct iscsi_task *iscsi_itt_to_task(struct iscsi_session *session,
+ struct iscsi_conn *, itt_t);
extern void iscsi_requeue_task(struct iscsi_task *task);
extern void iscsi_put_task(struct iscsi_task *task);
-extern void __iscsi_put_task(struct iscsi_task *task);
+void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task);
extern bool iscsi_get_task(struct iscsi_task *task);
-extern void iscsi_complete_scsi_task(struct iscsi_task *task,
- uint32_t exp_cmdsn, uint32_t max_cmdsn);
+void iscsi_complete_scsi_task(struct iscsi_session *session,
+ struct iscsi_task *task,
+ uint32_t exp_cmdsn, uint32_t max_cmdsn);
/*
* generic helpers
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 13/54] scsi: libiscsi: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (11 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 12/54] scsi: libiscsi: Pass the session pointer directly to several functions Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 14/54] scsi: be2iscsi: Enable " Bart Van Assche
` (40 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Lee Duncan, Chris Leech,
Mike Christie, James E.J. Bottomley, Martin K. Petersen
Document locking requirements with __must_hold().
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/libiscsi.c | 21 +++++++++++++++++++++
include/scsi/libiscsi.h | 15 ++++++++++-----
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 179de08ca515..34d4125417db 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -454,6 +454,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
*/
static void iscsi_free_task(struct iscsi_session *session,
struct iscsi_task *task)
+ __must_hold(&session->back_lock)
{
struct iscsi_conn *conn = task->conn;
struct scsi_cmnd *sc = task->sc;
@@ -499,6 +500,7 @@ EXPORT_SYMBOL_GPL(iscsi_get_task);
* The back_lock must be held when calling in case it frees the task.
*/
void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task)
+ __must_hold(&session->back_lock)
{
if (refcount_dec_and_test(&task->refcount))
iscsi_free_task(session, task);
@@ -527,6 +529,7 @@ EXPORT_SYMBOL_GPL(iscsi_put_task);
*/
static void iscsi_complete_task(struct iscsi_session *session,
struct iscsi_task *task, int state)
+ __must_hold(&session->back_lock)
{
struct iscsi_conn *conn = task->conn;
@@ -562,6 +565,7 @@ static void iscsi_complete_task(struct iscsi_session *session,
void iscsi_complete_scsi_task(struct iscsi_session *session,
struct iscsi_task *task,
uint32_t exp_cmdsn, uint32_t max_cmdsn)
+ __must_hold(&session->back_lock)
{
struct iscsi_conn *conn = task->conn;
@@ -578,6 +582,8 @@ EXPORT_SYMBOL_GPL(iscsi_complete_scsi_task);
*/
static bool cleanup_queued_task(struct iscsi_session *session,
struct iscsi_task *task)
+ __must_hold(&session->frwd_lock)
+ __must_hold(&session->back_lock)
{
struct iscsi_conn *conn = task->conn;
bool early_complete = false;
@@ -620,6 +626,8 @@ static bool cleanup_queued_task(struct iscsi_session *session,
*/
static void __fail_scsi_task(struct iscsi_session *session,
struct iscsi_task *task, int err)
+ __must_hold(&session->frwd_lock)
+ __must_hold(&session->back_lock)
{
struct scsi_cmnd *sc;
int state;
@@ -648,6 +656,7 @@ static void __fail_scsi_task(struct iscsi_session *session,
static void fail_scsi_task(struct iscsi_session *session,
struct iscsi_task *task, int err)
+ __must_hold(&session->frwd_lock)
{
spin_lock_bh(&session->back_lock);
__fail_scsi_task(session, task, err);
@@ -876,6 +885,7 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_session *session,
struct iscsi_conn *conn, struct iscsi_hdr *hdr,
struct iscsi_task *task, char *data,
int datalen)
+ __must_hold(&session->back_lock)
{
struct iscsi_scsi_rsp *rhdr = (struct iscsi_scsi_rsp *)hdr;
struct scsi_cmnd *sc = task->sc;
@@ -972,6 +982,7 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_session *session,
static void
iscsi_data_in_rsp(struct iscsi_session *session, struct iscsi_conn *conn,
struct iscsi_hdr *hdr, struct iscsi_task *task)
+ __must_hold(&session->back_lock)
{
struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr;
struct scsi_cmnd *sc = task->sc;
@@ -1078,6 +1089,7 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
static int iscsi_nop_out_rsp(struct iscsi_session *session,
struct iscsi_task *task,
struct iscsi_nopin *nop, char *data, int datalen)
+ __must_hold(&session->back_lock)
{
struct iscsi_conn *conn = task->conn;
int rc = 0;
@@ -1099,6 +1111,7 @@ static int iscsi_nop_out_rsp(struct iscsi_session *session,
static int iscsi_handle_reject(struct iscsi_session *session,
struct iscsi_conn *conn, struct iscsi_hdr *hdr,
char *data, int datalen)
+ __must_hold(&session->back_lock)
{
struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
struct iscsi_hdr rejected_pdu;
@@ -1194,6 +1207,7 @@ static int iscsi_handle_reject(struct iscsi_session *session,
*/
struct iscsi_task *iscsi_itt_to_task(struct iscsi_session *session,
struct iscsi_conn *conn, itt_t itt)
+ __must_hold(&session->back_lock)
{
int i;
@@ -1225,6 +1239,7 @@ EXPORT_SYMBOL_GPL(iscsi_itt_to_task);
*/
int __iscsi_complete_pdu(struct iscsi_session *session, struct iscsi_conn *conn,
struct iscsi_hdr *hdr, char *data, int datalen)
+ __must_hold(&session->back_lock)
{
int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0;
struct iscsi_task *task;
@@ -1420,6 +1435,7 @@ EXPORT_SYMBOL_GPL(iscsi_verify_itt);
*/
struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_session *session,
struct iscsi_conn *conn, itt_t itt)
+ __must_hold(&session->back_lock)
{
struct iscsi_task *task;
@@ -1499,6 +1515,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_failure);
static int iscsi_check_cmdsn_window_closed(struct iscsi_session *session,
struct iscsi_conn *conn)
+ __must_hold(&session->frwd_lock)
{
/*
* Check for iSCSI window and take care of CmdSN wrap-around
@@ -1515,6 +1532,7 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_session *session,
static int iscsi_xmit_task(struct iscsi_session *session, struct iscsi_conn *conn,
struct iscsi_task *task, bool was_requeue)
+ __must_hold(&session->frwd_lock)
{
int rc;
@@ -1932,6 +1950,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_session *session,
struct iscsi_conn *conn,
struct iscsi_tm *hdr, int age,
int timeout)
+ __must_hold(&session->eh_mutex)
__must_hold(&session->frwd_lock)
{
if (__iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0)) {
@@ -1978,6 +1997,7 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_session *session,
*/
static void fail_scsi_tasks(struct iscsi_session *session, struct iscsi_conn *conn,
u64 lun, int error)
+ __must_hold(&session->frwd_lock)
{
struct iscsi_task *task;
int i;
@@ -3372,6 +3392,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start);
static void
fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn)
+ __must_hold(&session->frwd_lock)
{
struct iscsi_task *task;
int i, state;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index f79b46798edf..e4ac4ec0ac3e 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -476,19 +476,24 @@ extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *,
char *, int);
extern int __iscsi_complete_pdu(struct iscsi_session *session,
struct iscsi_conn *conn, struct iscsi_hdr *,
- char *, int);
+ char *, int)
+ __must_hold(&session->back_lock);
extern int iscsi_verify_itt(struct iscsi_conn *, itt_t);
struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_session *session,
- struct iscsi_conn *, itt_t);
+ struct iscsi_conn *conn, itt_t itt)
+ __must_hold(&session->back_lock);
struct iscsi_task *iscsi_itt_to_task(struct iscsi_session *session,
- struct iscsi_conn *, itt_t);
+ struct iscsi_conn *conn, itt_t itt)
+ __must_hold(&session->back_lock);
extern void iscsi_requeue_task(struct iscsi_task *task);
extern void iscsi_put_task(struct iscsi_task *task);
-void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task);
+void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task)
+ __must_hold(&session->back_lock);
extern bool iscsi_get_task(struct iscsi_task *task);
void iscsi_complete_scsi_task(struct iscsi_session *session,
struct iscsi_task *task,
- uint32_t exp_cmdsn, uint32_t max_cmdsn);
+ uint32_t exp_cmdsn, uint32_t max_cmdsn)
+ __must_hold(&session->back_lock);
/*
* generic helpers
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 14/54] scsi: be2iscsi: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (12 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 13/54] scsi: libiscsi: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 15/54] scsi: cxgbi: " Bart Van Assche
` (39 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Ketan Mukadam, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements by annotating locking requirements with
__must_hold(). Enable lock context analysis for the be2iscsi driver by
setting CONTEXT_ANALYSIS in the Makefile.
Cc: Ketan Mukadam <ketan.mukadam@broadcom.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/be2iscsi/Makefile | 2 ++
drivers/scsi/be2iscsi/be_main.c | 5 +++++
2 files changed, 7 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
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index c8ee0473a1dd..356ab9c0fb7c 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1117,6 +1117,7 @@ static void
be_complete_io(struct beiscsi_conn *beiscsi_conn,
struct iscsi_task *task,
struct common_sol_cqe *csol_cqe)
+ __must_hold(&beiscsi_conn->conn->session->back_lock)
{
struct beiscsi_io_task *io_task = task->dd_data;
struct be_status_bhs *sts_bhs =
@@ -1185,6 +1186,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 +1214,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 +1271,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 +1427,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] 64+ messages in thread
* [PATCH v4 15/54] scsi: cxgbi: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (13 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 14/54] scsi: be2iscsi: Enable " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 16/54] scsi: bfa: " Bart Van Assche
` (38 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen, Kees Cook
Enable compile-time lock context analysis in the Makefile. Document where
locking is missing by adding an __assume_ctx_lock() annotation.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/cxgbi/Makefile | 3 +++
drivers/scsi/cxgbi/libcxgbi.c | 5 +++++
2 files changed, 8 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/
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index d73a6578b461..b0bffbc38183 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1540,6 +1540,11 @@ skb_read_pdu_bhs(struct cxgbi_sock *csk, struct iscsi_conn *conn,
struct iscsi_task *task;
u32 data_sn;
+ /*
+ * TODO: hold session->back_lock around the iscsi_itt_to_task()
+ * call below.
+ */
+ __assume_ctx_lock(&conn->session->back_lock);
task = iscsi_itt_to_ctask(conn->session, conn, itt);
data_sn = be32_to_cpu(((struct iscsi_data *)skb->data)->datasn);
if (task && task->sc) {
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 16/54] scsi: bfa: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (14 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 15/54] scsi: cxgbi: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 17/54] scsi: bnx2fc: Pass tgt directly to several functions Bart Van Assche
` (37 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Anil Gurumurthy, Sudarsana Kalluru,
James E.J. Bottomley, Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 17/54] scsi: bnx2fc: Pass tgt directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (15 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 16/54] scsi: bfa: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 18/54] scsi: bnx2fc: Enable lock context analysis Bart Van Assche
` (36 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Saurav Kashyap, Javed Hasan,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
Pass the tgt pointer directly to several functions. This patch prepares for
enabling lock context annotation. No functionality has been changed.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/bnx2fc/bnx2fc.h | 6 ++++--
drivers/scsi/bnx2fc/bnx2fc_els.c | 25 +++++++++++++------------
drivers/scsi/bnx2fc/bnx2fc_hwi.c | 2 +-
drivers/scsi/bnx2fc/bnx2fc_io.c | 14 +++++++-------
drivers/scsi/bnx2fc/bnx2fc_tgt.c | 2 +-
5 files changed, 26 insertions(+), 23 deletions(-)
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 8c8968ec8cb4..fde41224d31f 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -423,7 +423,8 @@ struct bnx2fc_cmd {
struct scsi_cmnd *sc_cmd;
struct bnx2fc_cmd_mgr *cmd_mgr;
struct bnx2fc_mp_req mp_req;
- void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg);
+ void (*cb_func)(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg);
struct bnx2fc_els_cb_arg *cb_arg;
struct delayed_work timeout_work; /* timer for ULP timeouts */
struct completion abts_done;
@@ -592,7 +593,8 @@ 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_rport *tgt,
+ struct bnx2fc_cmd *seq_clnp_req,
struct fcoe_task_ctx_entry *task,
u8 rx_state);
int bnx2fc_initiate_seq_cleanup(struct bnx2fc_cmd *orig_io_req, u32 offset,
diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c
index 749e30aaf926..5191d87fb446 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_els.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_els.c
@@ -22,10 +22,12 @@ static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp,
void *arg);
static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
void *data, u32 data_len,
- void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg),
+ void (*cb_func)(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg),
struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec);
-static void bnx2fc_rrq_compl(struct bnx2fc_els_cb_arg *cb_arg)
+static void bnx2fc_rrq_compl(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg)
{
struct bnx2fc_cmd *orig_io_req;
struct bnx2fc_cmd *rrq_req;
@@ -119,10 +121,10 @@ int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req)
return rc;
}
-static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg)
+static void bnx2fc_l2_els_compl(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg)
{
struct bnx2fc_cmd *els_req;
- struct bnx2fc_rport *tgt;
struct bnx2fc_mp_req *mp_req;
struct fc_frame_header *fc_hdr;
unsigned char *buf;
@@ -150,7 +152,6 @@ static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg)
goto free_arg;
}
- tgt = els_req->tgt;
mp_req = &(els_req->mp_req);
fc_hdr = &(mp_req->resp_fc_hdr);
resp_len = mp_req->resp_len;
@@ -262,7 +263,8 @@ int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp)
return rc;
}
-static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
+static void bnx2fc_srr_compl(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg)
{
struct bnx2fc_mp_req *mp_req;
struct fc_frame_header *fc_hdr, *fh;
@@ -296,7 +298,6 @@ static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
}
orig_io_req->srr_retry++;
if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) {
- struct bnx2fc_rport *tgt = orig_io_req->tgt;
spin_unlock_bh(&tgt->tgt_lock);
rc = bnx2fc_send_srr(orig_io_req,
orig_io_req->srr_offset,
@@ -372,7 +373,8 @@ static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg)
kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
}
-static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
+static void bnx2fc_rec_compl(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg)
{
struct bnx2fc_cmd *orig_io_req, *new_io_req;
struct bnx2fc_cmd *rec_req;
@@ -380,7 +382,6 @@ static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
struct fc_frame_header *fc_hdr, *fh;
struct fc_els_ls_rjt *rjt;
struct fc_els_rec_acc *acc;
- struct bnx2fc_rport *tgt;
struct fcoe_err_report_entry *err_entry;
struct scsi_cmnd *sc_cmd;
enum fc_rctl r_ctl;
@@ -399,7 +400,6 @@ static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg)
rec_req = cb_arg->io_req;
orig_io_req = cb_arg->aborted_io_req;
BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid);
- tgt = orig_io_req->tgt;
/* Handle REC timeout case */
if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) {
@@ -669,7 +669,8 @@ int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl)
static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op,
void *data, u32 data_len,
- void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg),
+ void (*cb_func)(struct bnx2fc_rport *tgt,
+ struct bnx2fc_els_cb_arg *cb_arg),
struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec)
{
struct fcoe_port *port = tgt->port;
@@ -847,7 +848,7 @@ void bnx2fc_process_els_compl(struct bnx2fc_cmd *els_req,
/* Parse ELS response */
if ((els_req->cb_func) && (els_req->cb_arg)) {
- els_req->cb_func(els_req->cb_arg);
+ els_req->cb_func(els_req->tgt, els_req->cb_arg);
els_req->cb_arg = NULL;
}
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index a5ecb87d5b2d..833ec0e35731 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -943,7 +943,7 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe,
case BNX2FC_SEQ_CLEANUP:
BNX2FC_IO_DBG(io_req, "cq_compl(0x%x) - seq cleanup resp\n",
io_req->xid);
- bnx2fc_process_seq_cleanup_compl(io_req, task, rx_state);
+ bnx2fc_process_seq_cleanup_compl(tgt, io_req, task, rx_state);
kref_put(&io_req->refcount, bnx2fc_cmd_release);
break;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 9c7a541a4523..82d70ccfc59b 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -142,7 +142,7 @@ static void bnx2fc_cmd_timeout(struct work_struct *work)
set_bit(BNX2FC_FLAG_ELS_TIMEOUT, &io_req->req_flags);
if ((io_req->cb_func) && (io_req->cb_arg)) {
- io_req->cb_func(io_req->cb_arg);
+ io_req->cb_func(tgt, io_req->cb_arg);
io_req->cb_arg = NULL;
}
}
@@ -1079,10 +1079,10 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
FCP_TMF_LUN_RESET);
}
-static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
+static int bnx2fc_abts_cleanup(struct bnx2fc_rport *tgt,
+ struct bnx2fc_cmd *io_req)
__must_hold(&tgt->tgt_lock)
{
- struct bnx2fc_rport *tgt = io_req->tgt;
unsigned int time_left;
init_completion(&io_req->cleanup_done);
@@ -1212,7 +1212,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
* cleanup the command and return that I/O was successfully
* aborted.
*/
- bnx2fc_abts_cleanup(io_req);
+ bnx2fc_abts_cleanup(tgt, io_req);
/* This only occurs when an task abort was requested while ABTS
is in progress. Setting the IO_CLEANUP flag will skip the
RRQ process in the case when the fw generated SCSI_CMD cmpl
@@ -1262,7 +1262,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
* Cleanup firmware residuals before returning control back
* to SCSI ML.
*/
- rc = bnx2fc_abts_cleanup(io_req);
+ rc = bnx2fc_abts_cleanup(tgt, io_req);
goto done;
} else {
/*
@@ -1282,7 +1282,8 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
return rc;
}
-void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req,
+void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_rport *tgt,
+ struct bnx2fc_cmd *seq_clnp_req,
struct fcoe_task_ctx_entry *task,
u8 rx_state)
{
@@ -1291,7 +1292,6 @@ void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req,
u32 offset = cb_arg->offset;
enum fc_rctl r_ctl = cb_arg->r_ctl;
int rc = 0;
- struct bnx2fc_rport *tgt = orig_io_req->tgt;
BNX2FC_IO_DBG(orig_io_req, "Entered process_cleanup_compl xid = 0x%x"
"cmd_type = %d\n",
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
index 77dcdfc412b1..e6942cb6cae6 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c
@@ -224,7 +224,7 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt)
bnx2fc_cmd_release); /* drop timer hold */
if ((io_req->cb_func) && (io_req->cb_arg)) {
- io_req->cb_func(io_req->cb_arg);
+ io_req->cb_func(tgt, io_req->cb_arg);
io_req->cb_arg = NULL;
}
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 18/54] scsi: bnx2fc: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (16 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 17/54] scsi: bnx2fc: Pass tgt directly to several functions Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 19/54] scsi: bnx2i: " Bart Van Assche
` (35 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Saurav Kashyap, Javed Hasan,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
Document the locking requirements with __must_hold(). 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 | 3 ++-
drivers/scsi/bnx2fc/bnx2fc_els.c | 2 ++
drivers/scsi/bnx2fc/bnx2fc_io.c | 1 +
4 files changed, 8 insertions(+), 1 deletion(-)
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 fde41224d31f..2fc80c607437 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -596,7 +596,8 @@ int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl);
void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_rport *tgt,
struct bnx2fc_cmd *seq_clnp_req,
struct fcoe_task_ctx_entry *task,
- u8 rx_state);
+ u8 rx_state)
+ __must_hold(&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 5191d87fb446..bca28acaa1a2 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_els.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_els.c
@@ -265,6 +265,7 @@ int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp)
static void bnx2fc_srr_compl(struct bnx2fc_rport *tgt,
struct bnx2fc_els_cb_arg *cb_arg)
+ __must_hold(&tgt->tgt_lock)
{
struct bnx2fc_mp_req *mp_req;
struct fc_frame_header *fc_hdr, *fh;
@@ -375,6 +376,7 @@ static void bnx2fc_srr_compl(struct bnx2fc_rport *tgt,
static void bnx2fc_rec_compl(struct bnx2fc_rport *tgt,
struct bnx2fc_els_cb_arg *cb_arg)
+ __must_hold(&tgt->tgt_lock)
{
struct bnx2fc_cmd *orig_io_req, *new_io_req;
struct bnx2fc_cmd *rec_req;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 82d70ccfc59b..60346d77cb6d 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1286,6 +1286,7 @@ void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_rport *tgt,
struct bnx2fc_cmd *seq_clnp_req,
struct fcoe_task_ctx_entry *task,
u8 rx_state)
+ __must_hold(&tgt->tgt_lock)
{
struct bnx2fc_els_cb_arg *cb_arg = seq_clnp_req->cb_arg;
struct bnx2fc_cmd *orig_io_req = cb_arg->aborted_io_req;
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 19/54] scsi: bnx2i: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (17 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 18/54] scsi: bnx2fc: Enable lock context analysis Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions Bart Van Assche
` (34 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Nilesh Javali, Manish Rangankar,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements with __must_hold(). Add an __assume_ctx_lock()
annotation where locking is missing.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/bnx2i/Makefile | 3 +++
drivers/scsi/bnx2i/bnx2i_hwi.c | 5 +++++
drivers/scsi/bnx2i/bnx2i_iscsi.c | 1 +
3 files changed, 9 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 4d4eca23d471..c22f1c981d02 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -405,6 +405,11 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn,
switch (tmfabort_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) {
case ISCSI_TM_FUNC_ABORT_TASK:
case ISCSI_TM_FUNC_TASK_REASSIGN:
+ /*
+ * TODO: hold session->back_lock around the iscsi_itt_to_task()
+ * call below.
+ */
+ __assume_ctx_lock(&session->back_lock);
ctask = iscsi_itt_to_task(session, conn, tmfabort_hdr->rtt);
if (!ctask || !ctask->sc)
/*
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] 64+ messages in thread
* [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (18 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 19/54] scsi: bnx2i: " Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-28 6:27 ` Damien Le Moal
2026-09-25 18:25 ` [PATCH v4 21/54] scsi: csiostor: Enable lock context analysis Bart Van Assche
` (33 subsequent siblings)
53 siblings, 1 reply; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen, John Garry, Damien Le Moal, Hannes Reinecke,
Kees Cook, Colin Ian King
Pass the struct csio_hw pointer directly to csio_scsi_cleanup_io_q(),
csio_scsi_abort_io_q(), csio_scsim_cleanup_io(), and
csio_scsim_cleanup_io_lnode() instead of passing the struct csio_scsim
pointer. Update all callers and header declarations accordingly.
Prepare the csiostor driver for enabling compiler-based lock context
analysis. No functionality has been changed.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/csiostor/csio_attr.c | 4 ++--
drivers/scsi/csiostor/csio_hw.c | 8 ++++---
drivers/scsi/csiostor/csio_rnode.c | 3 +--
drivers/scsi/csiostor/csio_scsi.c | 38 +++++++++++++-----------------
drivers/scsi/csiostor/csio_scsi.h | 7 +++---
5 files changed, 28 insertions(+), 32 deletions(-)
diff --git a/drivers/scsi/csiostor/csio_attr.c b/drivers/scsi/csiostor/csio_attr.c
index 9f021a7f78bd..7fddb98e1024 100644
--- a/drivers/scsi/csiostor/csio_attr.c
+++ b/drivers/scsi/csiostor/csio_attr.c
@@ -630,7 +630,7 @@ csio_vport_delete(struct fc_vport *fc_vport)
/* Quiesce ios and send remove event to lnode */
scsi_block_requests(shost);
spin_lock_irq(&hw->lock);
- csio_scsim_cleanup_io_lnode(csio_hw_to_scsim(hw), ln);
+ csio_scsim_cleanup_io_lnode(hw, ln);
csio_lnode_close(ln);
spin_unlock_irq(&hw->lock);
scsi_unblock_requests(shost);
@@ -655,7 +655,7 @@ csio_vport_disable(struct fc_vport *fc_vport, bool disable)
/* Quiesce ios and send stop event to lnode */
scsi_block_requests(shost);
spin_lock_irq(&hw->lock);
- csio_scsim_cleanup_io_lnode(csio_hw_to_scsim(hw), ln);
+ csio_scsim_cleanup_io_lnode(hw, ln);
csio_lnode_stop(ln);
spin_unlock_irq(&hw->lock);
scsi_unblock_requests(shost);
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c
index df9f81f29950..d8ed326dc602 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -92,7 +92,8 @@ static void csio_hw_mbm_cleanup(struct csio_hw *);
static void csio_hws_uninit(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_configuring(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_initializing(struct csio_hw *, enum csio_hw_ev);
-static void csio_hws_ready(struct csio_hw *, enum csio_hw_ev);
+static void csio_hws_ready(struct csio_hw *, enum csio_hw_ev)
+ __must_hold(&hw->lock);
static void csio_hws_quiescing(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_quiesced(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_resetting(struct csio_hw *, enum csio_hw_ev);
@@ -2879,6 +2880,7 @@ csio_hws_initializing(struct csio_hw *hw, enum csio_hw_ev evt)
*/
static void
csio_hws_ready(struct csio_hw *hw, enum csio_hw_ev evt)
+ __must_hold(&hw->lock)
{
/* Remember the event */
hw->evtflag = evt;
@@ -2897,9 +2899,9 @@ csio_hws_ready(struct csio_hw *hw, enum csio_hw_ev evt)
/* cleanup all outstanding cmds */
if (evt == CSIO_HWE_HBA_RESET ||
evt == CSIO_HWE_PCIERR_DETECTED)
- csio_scsim_cleanup_io(csio_hw_to_scsim(hw), false);
+ csio_scsim_cleanup_io(hw, false);
else
- csio_scsim_cleanup_io(csio_hw_to_scsim(hw), true);
+ csio_scsim_cleanup_io(hw, true);
csio_hw_intr_disable(hw);
csio_hw_mbm_cleanup(hw);
diff --git a/drivers/scsi/csiostor/csio_rnode.c b/drivers/scsi/csiostor/csio_rnode.c
index 713e13adf4dc..46d82802a5d4 100644
--- a/drivers/scsi/csiostor/csio_rnode.c
+++ b/drivers/scsi/csiostor/csio_rnode.c
@@ -586,8 +586,7 @@ __csio_unreg_rnode(struct csio_rnode *rn)
/* Cleanup I/Os that were waiting for rnode to unregister */
if (cmpl)
- csio_scsi_cleanup_io_q(csio_hw_to_scsim(hw), &tmp_q);
-
+ csio_scsi_cleanup_io_q(hw, &tmp_q);
}
/*****************************************************************************/
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index 0114e70e9884..b1473e1f514f 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1150,15 +1150,14 @@ csio_scsi_cmpl_handler(struct csio_hw *hw, void *wr, uint32_t len,
/*
* csio_scsi_cleanup_io_q - Cleanup the given queue.
- * @scm: SCSI module.
+ * @hw: HW module.
* @q: Queue to be cleaned up.
*
* Called with lock held. Has to exit with lock held.
*/
-void
-csio_scsi_cleanup_io_q(struct csio_scsim *scm, struct list_head *q)
+void csio_scsi_cleanup_io_q(struct csio_hw *hw, struct list_head *q)
{
- struct csio_hw *hw = scm->hw;
+ struct csio_scsim *scm = csio_hw_to_scsim(hw);
struct csio_ioreq *ioreq;
struct list_head *tmp, *next;
struct scsi_cmnd *scmnd;
@@ -1215,7 +1214,7 @@ csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd)
/*
* csio_scsi_abort_io_q - Abort all I/Os on given queue
- * @scm: SCSI module.
+ * @hw: HW module.
* @q: Queue to abort.
* @tmo: Timeout in ms
*
@@ -1229,10 +1228,9 @@ csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd)
* of this function has to ensure that the number of I/os to be aborted
* is finite enough to not cause lock-held-for-too-long issues.
*/
-static int
-csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo)
+static int csio_scsi_abort_io_q(struct csio_hw *hw, struct list_head *q,
+ uint32_t tmo)
{
- struct csio_hw *hw = scm->hw;
struct list_head *tmp, *next;
int count = DIV_ROUND_UP(tmo, CSIO_SCSI_ABORT_Q_POLL_MS);
struct scsi_cmnd *scmnd;
@@ -1264,15 +1262,14 @@ csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo)
/*
* csio_scsim_cleanup_io - Cleanup all I/Os in SCSI module.
- * @scm: SCSI module.
+ * @hw: HW module.
* @abort: abort required.
* Called with lock held, should exit with lock held.
* Can sleep when waiting for I/Os to complete.
*/
-int
-csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
+int csio_scsim_cleanup_io(struct csio_hw *hw, bool abort)
{
- struct csio_hw *hw = scm->hw;
+ struct csio_scsim *scm = csio_hw_to_scsim(hw);
int rv = 0;
int count = DIV_ROUND_UP(60 * 1000, CSIO_SCSI_ABORT_Q_POLL_MS);
@@ -1293,13 +1290,13 @@ csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
/* Else abort */
if (abort) {
- rv = csio_scsi_abort_io_q(scm, &scm->active_q, 30000);
+ rv = csio_scsi_abort_io_q(hw, &scm->active_q, 30000);
if (rv == 0)
return rv;
csio_dbg(hw, "Some I/O aborts timed out, cleaning up..\n");
}
- csio_scsi_cleanup_io_q(scm, &scm->active_q);
+ csio_scsi_cleanup_io_q(hw, &scm->active_q);
CSIO_DB_ASSERT(list_empty(&scm->active_q));
@@ -1308,16 +1305,15 @@ csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
/*
* csio_scsim_cleanup_io_lnode - Cleanup all I/Os of given lnode.
- * @scm: SCSI module.
+ * @hw: HW module
* @lnode: lnode
*
* Called with lock held, should exit with lock held.
* Can sleep (with dropped lock) when waiting for I/Os to complete.
*/
-int
-csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln)
+int csio_scsim_cleanup_io_lnode(struct csio_hw *hw, struct csio_lnode *ln)
{
- struct csio_hw *hw = scm->hw;
+ struct csio_scsim *scm = csio_hw_to_scsim(hw);
struct csio_scsi_level_data sld;
int rv;
int count = DIV_ROUND_UP(60 * 1000, CSIO_SCSI_ABORT_Q_POLL_MS);
@@ -1347,10 +1343,10 @@ csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln)
csio_dbg(hw, "Some I/Os pending on ln:%p, aborting them..\n", ln);
/* I/Os are pending, abort them */
- rv = csio_scsi_abort_io_q(scm, &ln->cmpl_q, 30000);
+ rv = csio_scsi_abort_io_q(hw, &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);
+ csio_scsi_cleanup_io_q(hw, &ln->cmpl_q);
}
CSIO_DB_ASSERT(list_empty(&ln->cmpl_q));
@@ -2194,7 +2190,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
spin_lock_irq(&hw->lock);
csio_scsi_gather_active_ios(scsim, &sld, &local_q);
- retval = csio_scsi_abort_io_q(scsim, &local_q, 30000);
+ retval = csio_scsi_abort_io_q(hw, &local_q, 30000);
spin_unlock_irq(&hw->lock);
/* Aborts may have timed out */
diff --git a/drivers/scsi/csiostor/csio_scsi.h b/drivers/scsi/csiostor/csio_scsi.h
index 39dda3c88f0d..610aae12be8a 100644
--- a/drivers/scsi/csiostor/csio_scsi.h
+++ b/drivers/scsi/csiostor/csio_scsi.h
@@ -338,10 +338,9 @@ csio_scsi_close(struct csio_ioreq *ioreq)
return ioreq->drv_status;
}
-void csio_scsi_cleanup_io_q(struct csio_scsim *, struct list_head *);
-int csio_scsim_cleanup_io(struct csio_scsim *, bool abort);
-int csio_scsim_cleanup_io_lnode(struct csio_scsim *,
- struct csio_lnode *);
+void csio_scsi_cleanup_io_q(struct csio_hw *, struct list_head *);
+int csio_scsim_cleanup_io(struct csio_hw *, bool abort);
+int csio_scsim_cleanup_io_lnode(struct csio_hw *, struct csio_lnode *);
struct csio_ioreq *csio_scsi_cmpl_handler(struct csio_hw *, void *, uint32_t,
struct csio_fl_dma_buf *,
void *, uint8_t **);
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 21/54] scsi: csiostor: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (19 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions Bart Van Assche
@ 2026-09-25 18:25 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 22/54] scsi: elx: " Bart Van Assche
` (32 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:25 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen, Kees Cook, Hannes Reinecke, Colin Ian King,
John Garry
Document locking requirements across the csiostor driver by annotating
functions in csio_hw.c, csio_lnode.c, csio_rnode.c, and csio_scsi.c with
__must_hold(). Enable lock context analysis by setting CONTEXT_ANALYSIS
in the Makefile.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/csiostor/Makefile | 2 ++
drivers/scsi/csiostor/csio_hw.c | 14 +++++++++++++-
drivers/scsi/csiostor/csio_lnode.c | 3 +++
drivers/scsi/csiostor/csio_rnode.c | 6 ++++++
drivers/scsi/csiostor/csio_scsi.c | 4 ++++
5 files changed, 28 insertions(+), 1 deletion(-)
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 d8ed326dc602..b5a36615a22b 100644
--- a/drivers/scsi/csiostor/csio_hw.c
+++ b/drivers/scsi/csiostor/csio_hw.c
@@ -92,7 +92,7 @@ static void csio_hw_mbm_cleanup(struct csio_hw *);
static void csio_hws_uninit(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_configuring(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_initializing(struct csio_hw *, enum csio_hw_ev);
-static void csio_hws_ready(struct csio_hw *, enum csio_hw_ev)
+static void csio_hws_ready(struct csio_hw *hw, enum csio_hw_ev)
__must_hold(&hw->lock);
static void csio_hws_quiescing(struct csio_hw *, enum csio_hw_ev);
static void csio_hws_quiesced(struct csio_hw *, enum csio_hw_ev);
@@ -915,6 +915,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;
@@ -2051,6 +2052,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;
@@ -2476,6 +2478,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;
@@ -2605,6 +2608,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;
@@ -2779,6 +2783,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;
@@ -2804,6 +2809,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;
@@ -2990,6 +2996,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;
@@ -3015,6 +3022,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;
@@ -3076,6 +3084,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;
@@ -3765,6 +3774,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);
@@ -3885,6 +3895,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;
@@ -4144,6 +4155,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 46d82802a5d4..fe985836c15c 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);
@@ -601,6 +603,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;
@@ -641,6 +644,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;
@@ -726,6 +730,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;
@@ -785,6 +790,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 b1473e1f514f..d81d10603fcc 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1156,6 +1156,7 @@ csio_scsi_cmpl_handler(struct csio_hw *hw, void *wr, uint32_t len,
* Called with lock held. Has to exit with lock held.
*/
void csio_scsi_cleanup_io_q(struct csio_hw *hw, struct list_head *q)
+ __must_hold(&hw->lock)
{
struct csio_scsim *scm = csio_hw_to_scsim(hw);
struct csio_ioreq *ioreq;
@@ -1230,6 +1231,7 @@ csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd)
*/
static int csio_scsi_abort_io_q(struct csio_hw *hw, struct list_head *q,
uint32_t tmo)
+ __must_hold(&hw->lock)
{
struct list_head *tmp, *next;
int count = DIV_ROUND_UP(tmo, CSIO_SCSI_ABORT_Q_POLL_MS);
@@ -1268,6 +1270,7 @@ static int csio_scsi_abort_io_q(struct csio_hw *hw, struct list_head *q,
* Can sleep when waiting for I/Os to complete.
*/
int csio_scsim_cleanup_io(struct csio_hw *hw, bool abort)
+ __must_hold(&hw->lock)
{
struct csio_scsim *scm = csio_hw_to_scsim(hw);
int rv = 0;
@@ -1312,6 +1315,7 @@ int csio_scsim_cleanup_io(struct csio_hw *hw, bool abort)
* Can sleep (with dropped lock) when waiting for I/Os to complete.
*/
int csio_scsim_cleanup_io_lnode(struct csio_hw *hw, struct csio_lnode *ln)
+ __must_hold(&hw->lock)
{
struct csio_scsim *scm = csio_hw_to_scsim(hw);
struct csio_scsi_level_data sld;
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 22/54] scsi: elx: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (20 preceding siblings ...)
2026-09-25 18:25 ` [PATCH v4 21/54] scsi: csiostor: Enable lock context analysis Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 23/54] scsi: esas2r: " Bart Van Assche
` (31 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Ram Vegesna, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 23/54] scsi: esas2r: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (21 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 22/54] scsi: elx: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 24/54] scsi: fcoe: " Bart Van Assche
` (30 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 24/54] scsi: fcoe: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (22 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 23/54] scsi: esas2r: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 25/54] scsi: fnic: Pass pointers directly to several functions Bart Van Assche
` (29 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Hannes Reinecke,
James E.J. Bottomley, Martin K. Petersen
Pass the FCoE controller pointer to all functions that are called with one or
more locks held. Document locking requirements by adding __must_hold()
annotations. Enable lock context analysis in the Makefile.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/fcoe/Makefile | 3 +++
drivers/scsi/fcoe/fcoe_ctlr.c | 50 +++++++++++++++++++++++++++--------
2 files changed, 42 insertions(+), 11 deletions(-)
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
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 496ddd45f74d..bf92293a0ef0 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -42,7 +42,8 @@ static void fcoe_ctlr_timer_work(struct work_struct *);
static void fcoe_ctlr_recv_work(struct work_struct *);
static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *);
-static void fcoe_ctlr_vn_start(struct fcoe_ctlr *);
+static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex);
static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *);
static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *);
static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *, u32, u8 *);
@@ -154,13 +155,14 @@ EXPORT_SYMBOL(fcoe_ctlr_init);
/**
* fcoe_sysfs_fcf_add() - Add a fcoe_fcf{,_device} to a fcoe_ctlr{,_device}
+ * @fip: The FCoE controller
* @new: The newly discovered FCF
*
* Called with fip->ctlr_mutex held
*/
-static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new)
+static int fcoe_sysfs_fcf_add(struct fcoe_ctlr *fip, struct fcoe_fcf *new)
+ __must_hold(&fip->ctlr_mutex)
{
- struct fcoe_ctlr *fip = new->fip;
struct fcoe_ctlr_device *ctlr_dev;
struct fcoe_fcf_device *temp, *fcf_dev;
int rc = -ENOMEM;
@@ -227,13 +229,14 @@ static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new)
/**
* fcoe_sysfs_fcf_del() - Remove a fcoe_fcf{,_device} to a fcoe_ctlr{,_device}
+ * @fip: The FCoE controller
* @new: The FCF to be removed
*
* Called with fip->ctlr_mutex held
*/
-static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
+static void fcoe_sysfs_fcf_del(struct fcoe_ctlr *fip, struct fcoe_fcf *new)
+ __must_hold(&fip->ctlr_mutex)
{
- struct fcoe_ctlr *fip = new->fip;
struct fcoe_ctlr_device *cdev;
struct fcoe_fcf_device *fcf_dev;
@@ -268,13 +271,14 @@ static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
* Called with &fcoe_ctlr lock held.
*/
static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
struct fcoe_fcf *fcf;
struct fcoe_fcf *next;
fip->sel_fcf = NULL;
list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
- fcoe_sysfs_fcf_del(fcf);
+ fcoe_sysfs_fcf_del(fip, fcf);
}
WARN_ON(fip->fcf_count);
@@ -316,6 +320,8 @@ EXPORT_SYMBOL(fcoe_ctlr_destroy);
* Called with neither ctlr_mutex nor ctlr_lock held.
*/
static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
+ __must_not_hold(&fip->ctlr_mutex)
+ __must_not_hold(&fip->ctlr_lock)
{
struct fcoe_fcf *sel;
struct fcoe_fcf *fcf;
@@ -476,6 +482,7 @@ EXPORT_SYMBOL(fcoe_ctlr_link_up);
* @fip: The FCoE controller to reset
*/
static void fcoe_ctlr_reset(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
fcoe_ctlr_reset_fcfs(fip);
timer_delete(&fip->timer);
@@ -817,6 +824,7 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send);
* Returns the time in jiffies for the next call.
*/
static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
struct fcoe_fcf *fcf;
struct fcoe_fcf *next;
@@ -866,7 +874,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
list_for_each_entry_safe(fcf, next, &del_list, list) {
/* Removes fcf from current list */
- fcoe_sysfs_fcf_del(fcf);
+ fcoe_sysfs_fcf_del(fip, fcf);
}
if (sel_time && !fip->sel_fcf && !fip->sel_time) {
@@ -1049,7 +1057,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
memcpy(fcf, &new, sizeof(new));
fcf->fip = fip;
- rc = fcoe_sysfs_fcf_add(fcf);
+ rc = fcoe_sysfs_fcf_add(fip, fcf);
if (rc) {
printk(KERN_ERR "Failed to allocate sysfs instance "
"for FCF, fab %16.16llx mac %pM\n",
@@ -1612,6 +1620,7 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
* Called with lock held.
*/
static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
struct fcoe_fcf *fcf;
struct fcoe_fcf *best = fip->sel_fcf;
@@ -1664,6 +1673,8 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip)
* Caller must verify that fip->sel_fcf is not NULL.
*/
static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
+ __must_hold(&fip->ctlr_lock)
{
struct sk_buff *skb;
struct sk_buff *skb_orig;
@@ -1733,6 +1744,7 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
* Called with ctlr_mutex held. The caller must not hold ctlr_lock.
*/
static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
struct fcoe_fcf *fcf;
@@ -2012,6 +2024,7 @@ static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata)
static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip,
enum fip_vn2vn_subcode sub,
const u8 *dest, size_t min_len)
+ __must_hold(&fip->ctlr_mutex)
{
struct sk_buff *skb;
struct fip_vn2vn_probe_frame {
@@ -2152,11 +2165,14 @@ static struct fc_rport_operations fcoe_ctlr_vn_rport_ops = {
/**
* fcoe_ctlr_disc_stop_locked() - stop discovery in VN2VN mode
+ * @fip: The FCoE controller
* @lport: The local port
*
* Called with ctlr_mutex held.
*/
-static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport)
+static void fcoe_ctlr_disc_stop_locked(struct fcoe_ctlr *fip,
+ struct fc_lport *lport)
+ __must_hold(&fip->ctlr_mutex)
{
struct fc_rport_priv *rdata;
@@ -2183,7 +2199,7 @@ static void fcoe_ctlr_disc_stop(struct fc_lport *lport)
struct fcoe_ctlr *fip = lport->disc.priv;
mutex_lock(&fip->ctlr_mutex);
- fcoe_ctlr_disc_stop_locked(lport);
+ fcoe_ctlr_disc_stop_locked(fip, lport);
mutex_unlock(&fip->ctlr_mutex);
}
@@ -2208,11 +2224,12 @@ static void fcoe_ctlr_disc_stop_final(struct fc_lport *lport)
* Called with fcoe_ctlr lock held.
*/
static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
unsigned long wait;
u32 port_id;
- fcoe_ctlr_disc_stop_locked(fip->lp);
+ fcoe_ctlr_disc_stop_locked(fip, fip->lp);
/*
* Get proposed port ID.
@@ -2246,6 +2263,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
* Called with fcoe_ctlr lock held.
*/
static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
fip->probe_tries = 0;
prandom_seed_state(&fip->rnd_state, fip->lp->wwpn);
@@ -2387,6 +2405,7 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
* Called with ctlr_mutex held.
*/
static void fcoe_ctlr_vn_send_claim(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
fcoe_ctlr_vn_send(fip, FIP_SC_VN_CLAIM_NOTIFY, fcoe_all_vn2vn, 0);
fip->sol_time = jiffies;
@@ -2401,6 +2420,7 @@ static void fcoe_ctlr_vn_send_claim(struct fcoe_ctlr *fip)
*/
static void fcoe_ctlr_vn_probe_req(struct fcoe_ctlr *fip,
struct fcoe_rport *frport)
+ __must_hold(&fip->ctlr_mutex)
{
if (frport->rdata.ids.port_id != fip->port_id)
return;
@@ -2452,6 +2472,7 @@ static void fcoe_ctlr_vn_probe_req(struct fcoe_ctlr *fip,
*/
static void fcoe_ctlr_vn_probe_reply(struct fcoe_ctlr *fip,
struct fcoe_rport *frport)
+ __must_hold(&fip->ctlr_mutex)
{
if (frport->rdata.ids.port_id != fip->port_id)
return;
@@ -2481,6 +2502,7 @@ static void fcoe_ctlr_vn_probe_reply(struct fcoe_ctlr *fip,
* Called with ctlr_mutex held.
*/
static void fcoe_ctlr_vn_add(struct fcoe_ctlr *fip, struct fcoe_rport *new)
+ __must_hold(&fip->ctlr_mutex)
{
struct fc_lport *lport = fip->lp;
struct fc_rport_priv *rdata;
@@ -2564,6 +2586,7 @@ static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *fip, u32 port_id, u8 *mac)
*/
static void fcoe_ctlr_vn_claim_notify(struct fcoe_ctlr *fip,
struct fcoe_rport *new)
+ __must_hold(&fip->ctlr_mutex)
{
if (new->flags & FIP_FL_REC_OR_P2P) {
LIBFCOE_FIP_DBG(fip, "send probe req for P2P/REC\n");
@@ -2619,6 +2642,7 @@ static void fcoe_ctlr_vn_claim_notify(struct fcoe_ctlr *fip,
*/
static void fcoe_ctlr_vn_claim_resp(struct fcoe_ctlr *fip,
struct fcoe_rport *new)
+ __must_hold(&fip->ctlr_mutex)
{
LIBFCOE_FIP_DBG(fip, "claim resp from from rport %x - state %s\n",
new->rdata.ids.port_id, fcoe_ctlr_state(fip->state));
@@ -2635,6 +2659,7 @@ static void fcoe_ctlr_vn_claim_resp(struct fcoe_ctlr *fip,
*/
static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip,
struct fcoe_rport *new)
+ __must_hold(&fip->ctlr_mutex)
{
struct fc_lport *lport = fip->lp;
struct fc_rport_priv *rdata;
@@ -2688,6 +2713,7 @@ static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip,
* Returns the soonest time for next age-out or a time far in the future.
*/
static unsigned long fcoe_ctlr_vn_age(struct fcoe_ctlr *fip)
+ __must_hold(&fip->ctlr_mutex)
{
struct fc_lport *lport = fip->lp;
struct fc_rport_priv *rdata;
@@ -2890,6 +2916,7 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
static void fcoe_ctlr_vlan_send(struct fcoe_ctlr *fip,
enum fip_vlan_subcode sub,
const u8 *dest)
+ __must_hold(&fip->ctlr_mutex)
{
struct sk_buff *skb;
struct fip_vlan_notify_frame {
@@ -2951,6 +2978,7 @@ static void fcoe_ctlr_vlan_send(struct fcoe_ctlr *fip,
*/
static void fcoe_ctlr_vlan_disc_reply(struct fcoe_ctlr *fip,
struct fcoe_rport *frport)
+ __must_hold(&fip->ctlr_mutex)
{
enum fip_vlan_subcode sub = FIP_SC_VL_NOTE;
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 25/54] scsi: fnic: Pass pointers directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (23 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 24/54] scsi: fcoe: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 26/54] scsi: fnic: Enable lock context analysis Bart Van Assche
` (28 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Satish Kharat, Sesidhar Baddela,
Karan Tilak Kumar, James E.J. Bottomley, Martin K. Petersen
In fdls_target_restart_nexus(), pass the struct fnic_iport_s pointer
directly from callers instead of deriving it from tport->iport. In
fnic_fdls_add_tport() and fnic_fdls_remove_tport(), pass the struct fnic
pointer directly instead of the struct fnic_iport_s pointer. This patch
prepares for enabling lock context analysis. No functionality has been
changed.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/fnic/fdls_disc.c | 11 ++++++-----
drivers/scsi/fnic/fnic_fcs.c | 19 ++++++++-----------
drivers/scsi/fnic/fnic_fdls.h | 7 +++----
3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c
index 8cb40466872f..7a33ec703391 100644
--- a/drivers/scsi/fnic/fdls_disc.c
+++ b/drivers/scsi/fnic/fdls_disc.c
@@ -87,7 +87,8 @@ static void fnic_fdls_start_flogi(struct fnic_iport_s *iport);
static struct fnic_tport_s *fdls_create_tport(struct fnic_iport_s *iport,
uint32_t fcid,
uint64_t wwpn);
-static void fdls_target_restart_nexus(struct fnic_tport_s *tport);
+static void fdls_target_restart_nexus(struct fnic_iport_s *iport,
+ struct fnic_tport_s *tport);
static void fdls_start_tport_timer(struct fnic_iport_s *iport,
struct fnic_tport_s *tport, int timeout);
static void fdls_tport_timer_callback(struct timer_list *t);
@@ -1810,9 +1811,9 @@ static void fdls_tgt_discovery_start(struct fnic_iport_s *iport)
* safely since the memory it is
* pointing to it will be freed later
*/
-static void fdls_target_restart_nexus(struct fnic_tport_s *tport)
+static void fdls_target_restart_nexus(struct fnic_iport_s *iport,
+ struct fnic_tport_s *tport)
{
- struct fnic_iport_s *iport = tport->iport;
struct fnic_tport_s *new_tport = NULL;
uint32_t fcid;
uint64_t wwpn;
@@ -2767,7 +2768,7 @@ 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");
- fdls_target_restart_nexus(tport);
+ fdls_target_restart_nexus(iport, tport);
return;
}
@@ -2893,7 +2894,7 @@ 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");
- fdls_target_restart_nexus(tport);
+ fdls_target_restart_nexus(iport, tport);
return;
}
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index b00672ef8b00..0668770dfb5d 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -942,10 +942,9 @@ 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)
+fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport,
+ unsigned long flags)
{
- struct fnic *fnic = iport->fnic;
struct fc_rport *rport;
struct fc_rport_identifiers ids;
struct rport_dd_data_s *rdd_data;
@@ -975,18 +974,16 @@ fnic_fdls_add_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport,
rport->supported_classes = FC_COS_CLASS3 | FC_RPORT_ROLE_FCP_TARGET;
rdd_data = rport->dd_data;
rdd_data->tport = tport;
- rdd_data->iport = iport;
+ rdd_data->iport = &fnic->iport;
tport->rport = rport;
tport->flags |= FNIC_FDLS_SCSI_REGISTERED;
}
void
-fnic_fdls_remove_tport(struct fnic_iport_s *iport,
- struct fnic_tport_s *tport, unsigned long flags)
+fnic_fdls_remove_tport(struct fnic *fnic, struct fnic_tport_s *tport,
+ unsigned long flags)
{
- struct fnic *fnic = iport->fnic;
struct rport_dd_data_s *rdd_data;
-
struct fc_rport *rport;
if (!tport)
@@ -1038,7 +1035,7 @@ void fnic_delete_fcp_tports(struct fnic *fnic)
fdls_set_tport_state(tport, FDLS_TGT_STATE_OFFLINING);
fnic_del_tport_timer_sync(fnic, tport);
if (IS_FNIC_FCP_INITIATOR(fnic))
- fnic_fdls_remove_tport(&fnic->iport, tport, flags);
+ fnic_fdls_remove_tport(fnic, tport, flags);
else if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_delete_tport(&fnic->iport, tport, flags);
}
@@ -1067,7 +1064,7 @@ void fnic_tport_event_handler(struct work_struct *work)
"Add rport event");
if (tport->state == FDLS_TGT_STATE_READY) {
if (IS_FNIC_FCP_INITIATOR(fnic))
- fnic_fdls_add_tport(&fnic->iport, tport, flags);
+ fnic_fdls_add_tport(fnic, tport, flags);
else if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_add_tport(fnic, tport, flags);
} else {
@@ -1081,7 +1078,7 @@ void fnic_tport_event_handler(struct work_struct *work)
"Remove rport event");
if (tport->state == FDLS_TGT_STATE_OFFLINING) {
if (IS_FNIC_FCP_INITIATOR(fnic))
- fnic_fdls_remove_tport(&fnic->iport, tport, flags);
+ fnic_fdls_remove_tport(fnic, tport, flags);
else if (IS_FNIC_NVME_INITIATOR(fnic))
nvfnic_delete_tport(&fnic->iport, tport, flags);
} else {
diff --git a/drivers/scsi/fnic/fnic_fdls.h b/drivers/scsi/fnic/fnic_fdls.h
index ce4b3aae77e3..75f83c78aea1 100644
--- a/drivers/scsi/fnic/fnic_fdls.h
+++ b/drivers/scsi/fnic/fnic_fdls.h
@@ -433,10 +433,9 @@ int fnic_send_fip_frame(struct fnic_iport_s *iport,
void *frame, int frame_size);
void fnic_fdls_learn_fcoe_macs(struct fnic_iport_s *iport, void *rx_frame,
uint8_t *fcid);
-void fnic_fdls_add_tport(struct fnic_iport_s *iport,
- struct fnic_tport_s *tport, unsigned long flags);
-void fnic_fdls_remove_tport(struct fnic_iport_s *iport,
- struct fnic_tport_s *tport,
+void fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport,
+ unsigned long flags);
+void fnic_fdls_remove_tport(struct fnic *fnic, struct fnic_tport_s *tport,
unsigned long flags);
void fnic_fcpio_reset(struct fnic *fnic);
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 26/54] scsi: fnic: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (24 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 25/54] scsi: fnic: Pass pointers directly to several functions Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 27/54] scsi: hisi_sas: " Bart Van Assche
` (27 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Karan Tilak Kumar, Satish Kharat,
Sesidhar Baddela, James E.J. Bottomley, Martin K. Petersen
Document locking requirements with __must_hold(). Suppress complaints
about conditional locking in fnic_device_reset() with __acquire() and
__release().
Cc: 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 | 46 +++++++++++++++++++++++++++++++++--
drivers/scsi/fnic/fip.c | 2 ++
drivers/scsi/fnic/fnic_fcs.c | 2 ++
drivers/scsi/fnic/fnic_scsi.c | 4 +++
5 files changed, 55 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 7a33ec703391..b04bb9a5dfa8 100644
--- a/drivers/scsi/fnic/fdls_disc.c
+++ b/drivers/scsi/fnic/fdls_disc.c
@@ -418,6 +418,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);
@@ -426,8 +427,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);
@@ -438,6 +439,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;
@@ -463,6 +465,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;
@@ -718,6 +721,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];
@@ -761,7 +765,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];
@@ -933,6 +939,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;
@@ -993,6 +1000,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;
@@ -1085,6 +1093,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;
@@ -1144,6 +1153,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;
@@ -1199,6 +1209,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;
@@ -1258,6 +1269,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;
@@ -1323,6 +1335,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;
@@ -1388,6 +1401,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;
@@ -1456,6 +1470,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;
@@ -1523,6 +1538,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;
@@ -1582,6 +1598,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;
@@ -1663,6 +1680,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;
@@ -1762,6 +1780,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;
@@ -1813,6 +1832,7 @@ static void fdls_tgt_discovery_start(struct fnic_iport_s *iport)
*/
static void fdls_target_restart_nexus(struct fnic_iport_s *iport,
struct fnic_tport_s *tport)
+ __must_hold(&iport->fnic->fnic_lock)
{
struct fnic_tport_s *new_tport = NULL;
uint32_t fcid;
@@ -2618,6 +2638,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);
@@ -2626,6 +2647,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);
@@ -2644,6 +2666,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;
@@ -2734,6 +2757,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;
@@ -2855,9 +2879,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;
@@ -3026,6 +3052,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;
@@ -3099,6 +3126,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;
@@ -3174,6 +3202,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;
@@ -3244,6 +3273,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;
@@ -3316,6 +3346,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;
@@ -3414,6 +3445,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;
@@ -3550,6 +3582,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;
@@ -3603,6 +3636,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;
@@ -3742,6 +3776,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;
@@ -4003,6 +4038,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;
@@ -4360,6 +4396,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;
@@ -4549,6 +4586,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;
@@ -4626,6 +4664,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;
@@ -4759,6 +4798,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;
@@ -5103,6 +5143,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;
@@ -5224,6 +5265,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 231dec180675..8f44abfc01a5 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 0668770dfb5d..b5a6a2b99c4e 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 *fnic, struct fnic_tport_s *tport,
unsigned long flags)
+ __must_hold(&fnic->fnic_lock)
{
struct fc_rport *rport;
struct fc_rport_identifiers ids;
@@ -982,6 +983,7 @@ fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport,
void
fnic_fdls_remove_tport(struct fnic *fnic, struct fnic_tport_s *tport,
unsigned long flags)
+ __must_hold(&fnic->fnic_lock)
{
struct rport_dd_data_s *rdd_data;
struct fc_rport *rport;
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] 64+ messages in thread
* [PATCH v4 27/54] scsi: hisi_sas: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (25 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 26/54] scsi: fnic: Enable lock context analysis Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 28/54] scsi: hpsa: Prepare for enabling " Bart Van Assche
` (26 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Xingui Yang, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 28/54] scsi: hpsa: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (26 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 27/54] scsi: hisi_sas: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 29/54] scsi: ibmvscsi: Enable " Bart Van Assche
` (25 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Don Brace, James E.J. Bottomley,
Martin K. Petersen, 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 795e8c7592af..2e11f0f5e8d3 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -3166,7 +3166,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] 64+ messages in thread
* [PATCH v4 29/54] scsi: ibmvscsi: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (27 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 28/54] scsi: hpsa: Prepare for enabling " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 30/54] scsi: ibmvscsi_tgt: " Bart Van Assche
` (24 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Madhavan Srinivasan,
James E.J. Bottomley, Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 30/54] scsi: ibmvscsi_tgt: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (28 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 29/54] scsi: ibmvscsi: Enable " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 31/54] scsi: ipr: Simplify ipr_eh_abort() Bart Van Assche
` (23 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Tyrel Datwyler, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements with __must_hold() and enable lock context
analysis.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ibmvscsi_tgt/Makefile | 3 +++
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 34 +++++++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletion(-)
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 e2af90b6da39..92b26f7fec50 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -219,6 +219,7 @@ static long ibmvscsis_unregister_command_q(struct scsi_info *vscsi)
*/
static void ibmvscsis_delete_client_info(struct scsi_info *vscsi,
bool client_closed)
+ __must_hold(&vscsi->intr_lock)
{
vscsi->client_cap = 0;
@@ -251,6 +252,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;
@@ -329,6 +331,7 @@ static struct viosrp_crq *ibmvscsis_cmd_q_dequeue(uint mask,
* Interrupt environment interrupt lock held
*/
static long ibmvscsis_send_init_message(struct scsi_info *vscsi, u8 format)
+ __must_hold(&vscsi->intr_lock)
{
struct viosrp_crq *crq;
u64 buffer[2] = { 0, 0 };
@@ -356,6 +359,7 @@ static long ibmvscsis_send_init_message(struct scsi_info *vscsi, u8 format)
* Process level only, interrupt lock held
*/
static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format)
+ __must_hold(&vscsi->intr_lock)
{
struct viosrp_crq *crq;
long rc = ADAPT_SUCCESS;
@@ -571,6 +575,7 @@ static void ibmvscsis_disconnect(struct work_struct *work)
*/
static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state,
uint flag_bits)
+ __must_hold(&vscsi->intr_lock)
{
uint state;
@@ -652,6 +657,7 @@ static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state,
* Must be called with interrupt lock held.
*/
static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
long rc = ADAPT_SUCCESS;
@@ -691,6 +697,7 @@ static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi)
* Must be called with interrupt lock held.
*/
static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
long rc = ADAPT_SUCCESS;
@@ -759,6 +766,7 @@ static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi)
* Interrupt, interrupt lock held
*/
static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
long rc = ADAPT_SUCCESS;
@@ -798,6 +806,7 @@ static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq)
* Must be called with interrupt lock held.
*/
static long ibmvscsis_establish_new_q(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
long rc = ADAPT_SUCCESS;
uint format;
@@ -874,6 +883,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;
@@ -924,6 +934,7 @@ static void ibmvscsis_reset_queue(struct scsi_info *vscsi)
*/
static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
@@ -974,6 +985,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 +1042,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 +1179,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;
@@ -1252,6 +1266,7 @@ static void ibmvscsis_poll_cmd_q(struct scsi_info *vscsi)
* Called with interrupt lock held
*/
static void ibmvscsis_free_cmd_qs(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
struct ibmvscsis_cmd *cmd, *nxt;
@@ -1272,6 +1287,7 @@ static void ibmvscsis_free_cmd_qs(struct scsi_info *vscsi)
* Must be called with interrupt lock held.
*/
static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
struct ibmvscsis_cmd *cmd = NULL;
struct iu_entry *iue;
@@ -1310,6 +1326,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;
@@ -1441,6 +1458,7 @@ static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)
static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd,
struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
long rc = 0;
@@ -1500,6 +1518,7 @@ static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi,
*/
static long ibmvscsis_adapter_info(struct scsi_info *vscsi,
struct iu_entry *iue)
+ __must_hold(&vscsi->intr_lock)
{
struct viosrp_adapter_info *mad = &vio_iu(iue)->mad.adapter_info;
struct mad_adapter_info_data *info;
@@ -1611,6 +1630,7 @@ static long ibmvscsis_adapter_info(struct scsi_info *vscsi,
* Interrupt called with adapter lock held
*/
static int ibmvscsis_cap_mad(struct scsi_info *vscsi, struct iu_entry *iue)
+ __must_hold(&vscsi->intr_lock)
{
struct viosrp_capabilities *mad = &vio_iu(iue)->mad.capabilities;
struct capabilities *cap;
@@ -1725,6 +1745,7 @@ static int ibmvscsis_cap_mad(struct scsi_info *vscsi, struct iu_entry *iue)
* Must be called with interrupt lock held.
*/
static long ibmvscsis_process_mad(struct scsi_info *vscsi, struct iu_entry *iue)
+ __must_hold(&vscsi->intr_lock)
{
struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad;
struct viosrp_empty_iu *empty;
@@ -1768,6 +1789,7 @@ static long ibmvscsis_process_mad(struct scsi_info *vscsi, struct iu_entry *iue)
* Must be called with interrupt lock held.
*/
static void srp_snd_msg_failed(struct scsi_info *vscsi, long rc)
+ __must_hold(&vscsi->intr_lock)
{
ktime_t kt;
@@ -1871,6 +1893,7 @@ static void srp_snd_msg_failed(struct scsi_info *vscsi, long rc)
* Called with interrupt lock held
*/
static void ibmvscsis_send_messages(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
struct viosrp_crq empty_crq = { };
struct viosrp_crq *crq = &empty_crq;
@@ -1979,6 +2002,7 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi)
static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd,
struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad;
@@ -2021,6 +2045,7 @@ static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi,
* Interrupt, called with adapter lock held
*/
static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue;
struct ibmvscsis_cmd *cmd;
@@ -2097,6 +2122,7 @@ static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)
*/
static long ibmvscsis_login_rsp(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
struct srp_login_rsp *rsp = &vio_iu(iue)->srp.login_rsp;
@@ -2157,6 +2183,7 @@ static long ibmvscsis_login_rsp(struct scsi_info *vscsi,
*/
static long ibmvscsis_srp_login_rej(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd, u32 reason)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
struct srp_login_rej *rej = &vio_iu(iue)->srp.login_rej;
@@ -2272,6 +2299,7 @@ static int ibmvscsis_drop_nexus(struct ibmvscsis_tport *tport)
static long ibmvscsis_srp_login(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd,
struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
struct srp_login_req *req = &vio_iu(iue)->srp.login_req;
@@ -2346,6 +2374,7 @@ static long ibmvscsis_srp_login(struct scsi_info *vscsi,
static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi,
struct ibmvscsis_cmd *cmd,
struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
struct iu_entry *iue = cmd->iue;
struct srp_i_logout *log_out = &vio_iu(iue)->srp.i_logout;
@@ -2367,8 +2396,8 @@ static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi,
return ADAPT_SUCCESS;
}
-/* Called with intr lock held */
static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq)
+ __must_hold(&vscsi->intr_lock)
{
struct ibmvscsis_cmd *cmd;
struct iu_entry *iue;
@@ -2469,6 +2498,7 @@ static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq)
* Interrupt, interrupt lock held
*/
static long ibmvscsis_ping_response(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
struct viosrp_crq *crq;
u64 buffer[2] = { 0, 0 };
@@ -2520,6 +2550,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;
@@ -2961,6 +2992,7 @@ static irqreturn_t ibmvscsis_interrupt(int dummy, void *data)
* Must be called with interrupt lock held.
*/
static long ibmvscsis_enable_change_state(struct scsi_info *vscsi)
+ __must_hold(&vscsi->intr_lock)
{
int bytes;
long rc = ADAPT_SUCCESS;
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 31/54] scsi: ipr: Simplify ipr_eh_abort()
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (29 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 30/54] scsi: ibmvscsi_tgt: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 32/54] scsi: ipr: Pass the host pointer directly to several functions Bart Van Assche
` (22 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Brian King, James E.J. Bottomley,
Martin K. Petersen
Derive the SCSI host pointer once instead of three times. This was detected
by Sashiko. No functionality has been changed.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ipr.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 1c74eec3a0c0..d221689d28c6 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5299,17 +5299,17 @@ static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time
**/
static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd)
{
+ struct Scsi_Host *host = scsi_cmd->device->host;
+ struct ipr_ioa_cfg *ioa_cfg = (void *)host->hostdata;
unsigned long flags;
int rc;
- struct ipr_ioa_cfg *ioa_cfg;
ENTER;
- ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
- spin_lock_irqsave(&scsi_cmd->device->host->host_lock, flags);
+ spin_lock_irqsave(&host->host_lock, flags);
rc = ipr_cancel_op(scsi_cmd);
- spin_unlock_irqrestore(&scsi_cmd->device->host->host_lock, flags);
+ spin_unlock_irqrestore(&host->host_lock, flags);
if (rc == SUCCESS)
rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun);
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 32/54] scsi: ipr: Pass the host pointer directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (30 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 31/54] scsi: ipr: Simplify ipr_eh_abort() Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 33/54] scsi: ipr: Prepare for enabling lock context analysis Bart Van Assche
` (21 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Brian King, James E.J. Bottomley,
Martin K. Petersen
Pass the struct Scsi_Host pointer directly to ipr_send_blocking_cmd(),
ipr_device_reset(), and __ipr_eh_dev_reset(). Introduce the local variable
'host' in error handling functions to avoid repetitive dereferencing of
cmd->device->host. This patch prepares for enabling lock context analysis.
No functionality has been changed.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ipr.c | 37 ++++++++++++++++++++++---------------
1 file changed, 22 insertions(+), 15 deletions(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index d221689d28c6..e9066608323c 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1006,6 +1006,7 @@ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
/**
* ipr_send_blocking_cmd - Send command and sleep on its completion.
+ * @host: SCSI host
* @ipr_cmd: ipr command struct
* @timeout_func: function to invoke if command times out
* @timeout: timeout
@@ -1013,18 +1014,17 @@ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr,
* Return value:
* none
**/
-static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd,
+static void ipr_send_blocking_cmd(struct Scsi_Host *host, struct ipr_cmnd *ipr_cmd,
void (*timeout_func) (struct timer_list *),
u32 timeout)
+ __must_hold(&host->host_lock)
{
- struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-
init_completion(&ipr_cmd->completion);
ipr_do_req(ipr_cmd, ipr_internal_cmd_done, timeout_func, timeout);
- spin_unlock_irq(&ioa_cfg->host->host_lock);
+ spin_unlock_irq(&host->host_lock);
wait_for_completion(&ipr_cmd->completion);
- spin_lock_irq(&ioa_cfg->host->host_lock);
+ spin_lock_irq(&host->host_lock);
}
static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg)
@@ -5011,7 +5011,9 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd)
* 0 on success / non-zero on failure
**/
static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
+ struct Scsi_Host *host,
struct ipr_resource_entry *res)
+ __must_hold(&host->host_lock)
{
struct ipr_cmnd *ipr_cmd;
struct ipr_ioarcb *ioarcb;
@@ -5030,7 +5032,8 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
cmd_pkt->cdb[0] = IPR_RESET_DEVICE;
- ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT);
+ ipr_send_blocking_cmd(host, ipr_cmd, ipr_timeout,
+ IPR_DEVICE_RESET_TIMEOUT);
ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q);
@@ -5049,14 +5052,15 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
* Return value:
* SUCCESS / FAILED
**/
-static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
+static int __ipr_eh_dev_reset(struct Scsi_Host *host, struct scsi_cmnd *scsi_cmd)
+ __must_hold(&host->host_lock)
{
struct ipr_ioa_cfg *ioa_cfg;
struct ipr_resource_entry *res;
int rc = 0;
ENTER;
- ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
+ ioa_cfg = (struct ipr_ioa_cfg *) host->hostdata;
res = scsi_cmd->device->hostdata;
/*
@@ -5072,7 +5076,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
res->resetting_device = 1;
scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");
- rc = ipr_device_reset(ioa_cfg, res);
+ rc = ipr_device_reset(ioa_cfg, host, res);
res->resetting_device = 0;
res->reset_occurred = 1;
@@ -5085,16 +5089,17 @@ static int ipr_eh_dev_reset(struct scsi_cmnd *cmd)
int rc;
struct ipr_ioa_cfg *ioa_cfg;
struct ipr_resource_entry *res;
+ struct Scsi_Host *host = cmd->device->host;
- ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata;
+ ioa_cfg = (struct ipr_ioa_cfg *) host->hostdata;
res = cmd->device->hostdata;
if (!res)
return FAILED;
- spin_lock_irq(&cmd->device->host->host_lock);
- rc = __ipr_eh_dev_reset(cmd);
- spin_unlock_irq(&cmd->device->host->host_lock);
+ spin_lock_irq(&host->host_lock);
+ rc = __ipr_eh_dev_reset(host, cmd);
+ spin_unlock_irq(&host->host_lock);
if (rc == SUCCESS)
rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun);
@@ -5190,6 +5195,7 @@ static void ipr_abort_timeout(struct timer_list *t)
**/
static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
{
+ struct Scsi_Host *host = scsi_cmd->device->host;
struct ipr_cmnd *ipr_cmd;
struct ipr_ioa_cfg *ioa_cfg;
struct ipr_resource_entry *res;
@@ -5199,7 +5205,7 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
struct ipr_hrr_queue *hrrq;
ENTER;
- ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
+ ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata;
res = scsi_cmd->device->hostdata;
/* If we are currently going through reset/reload, return failed.
@@ -5247,7 +5253,8 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd)
scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n",
scsi_cmd->cmnd[0]);
- ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT);
+ ipr_send_blocking_cmd(host, ipr_cmd, ipr_abort_timeout,
+ IPR_CANCEL_ALL_TIMEOUT);
ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc);
/*
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 33/54] scsi: ipr: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (31 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 32/54] scsi: ipr: Pass the host pointer directly to several functions Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 34/54] scsi: ips: " Bart Van Assche
` (20 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Brian King, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements with __must_hold().
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/ipr.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index e9066608323c..665fc54fcbb3 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5194,6 +5194,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 Scsi_Host *host = scsi_cmd->device->host;
struct ipr_cmnd *ipr_cmd;
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 34/54] scsi: ips: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (32 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 33/54] scsi: ipr: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 35/54] scsi: isci: Enable " Bart Van Assche
` (19 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Adaptec OEM Raid Solutions,
James E.J. Bottomley, Martin K. Petersen
Annotate ips_next() with __context_unsafe() 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 45c5b9acb664..c7d6c5aae340 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] 64+ messages in thread
* [PATCH v4 35/54] scsi: isci: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (33 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 34/54] scsi: ips: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 36/54] scsi: libfc: " Bart Van Assche
` (18 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 36/54] scsi: libfc: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (34 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 35/54] scsi: isci: Enable " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 37/54] scsi: libsas: Prepare for enabling " Bart Van Assche
` (17 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Hannes Reinecke,
James E.J. Bottomley, Martin K. Petersen
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 | 7 ++++++-
drivers/scsi/libfc/fc_exch.c | 6 ++++++
drivers/scsi/libfc/fc_fcp.c | 17 ++++++++++++++++-
4 files changed, 30 insertions(+), 2 deletions(-)
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..ce230a67a082 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 *);
@@ -68,6 +68,7 @@ static void fc_disc_stop_rports(struct fc_disc *disc)
* @fp: The RSCN frame
*/
static void fc_disc_recv_rscn_req(struct fc_disc *disc, struct fc_frame *fp)
+ __must_hold(&disc->disc_mutex)
{
struct fc_lport *lport;
struct fc_els_rscn *rp;
@@ -200,6 +201,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 +252,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 +297,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 +378,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..ba2530386f97 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 60a675aa5a99..dbd5673e2885 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -77,7 +77,8 @@ struct fc_fcp_internal {
static void fc_fcp_recv_data(struct fc_fcp_pkt *, struct fc_frame *);
static void fc_fcp_recv(struct fc_seq *, struct fc_frame *, void *);
static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
-static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
+static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp)
+ __must_hold(&fsp->scsi_pkt_lock);
static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
static void fc_fcp_recovery(struct fc_fcp_pkt *, u8 code);
@@ -207,6 +208,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 +226,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);
@@ -243,6 +246,7 @@ static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay)
}
static void fc_fcp_abort_done(struct fc_fcp_pkt *fsp)
+ __must_hold(&fsp->scsi_pkt_lock)
{
fsp->state |= FC_SRB_ABORTED;
fsp->state &= ~FC_SRB_ABORT_PENDING;
@@ -259,6 +263,7 @@ static void fc_fcp_abort_done(struct fc_fcp_pkt *fsp)
* @fsp: The FCP packet to abort exchanges on
*/
static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp)
+ __must_hold(&fsp->scsi_pkt_lock)
{
int rc;
@@ -296,6 +301,7 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp)
* The SCSI-ml will retry the command.
*/
static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp, int status_code)
+ __must_hold(&fsp->scsi_pkt_lock)
{
if (fsp->seq_ptr) {
fc_exch_done(fsp->seq_ptr);
@@ -470,6 +476,7 @@ static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp)
* @fp: The data frame
*/
static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
+ __must_hold(&fsp->scsi_pkt_lock)
{
struct scsi_cmnd *sc = fsp->cmd;
struct fc_lport *lport = fsp->lp;
@@ -588,6 +595,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
*/
static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
size_t offset, size_t seq_blen)
+ __must_hold(&fsp->scsi_pkt_lock)
{
struct fc_exch *ep;
struct scsi_cmnd *sc;
@@ -734,6 +742,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
* @fp: The response frame
*/
static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
+ __must_hold(&fsp->scsi_pkt_lock)
{
int ba_done = 1;
struct fc_ba_rjt *brp;
@@ -846,6 +855,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg)
* @fp: The response frame
*/
static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
+ __must_hold(&fsp->scsi_pkt_lock)
{
struct fc_frame_header *fh;
struct fcp_resp *fc_rp;
@@ -1242,6 +1252,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;
@@ -1453,6 +1464,7 @@ static void fc_fcp_timeout(struct timer_list *t)
* @fsp: The FCP packet to send the REC request on
*/
static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
+ __must_hold(&fsp->scsi_pkt_lock)
{
struct fc_lport *lport;
struct fc_frame *fp;
@@ -1690,6 +1702,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
* @code: The FCP status code to set
*/
static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code)
+ __must_hold(&fsp->scsi_pkt_lock)
{
FC_FCP_DBG(fsp, "start recovery code %x\n", code);
fsp->status_code = code;
@@ -1712,6 +1725,7 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code)
* when expecting status but the request has timed out.
*/
static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset)
+ __must_hold(&fsp->scsi_pkt_lock)
{
struct fc_lport *lport = fsp->lp;
struct fc_rport *rport;
@@ -1950,6 +1964,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] 64+ messages in thread
* [PATCH v4 37/54] scsi: libsas: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (35 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 36/54] scsi: libfc: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 38/54] scsi: libsas: Enable " Bart Van Assche
` (16 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen, 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] 64+ messages in thread
* [PATCH v4 38/54] scsi: libsas: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (36 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 37/54] scsi: libsas: Prepare for enabling " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 39/54] scsi: lpfc: Prepare for enabling " Bart Van Assche
` (15 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 39/54] scsi: lpfc: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (37 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 38/54] scsi: libsas: Enable " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 40/54] scsi: mpt3sas: Enable " Bart Van Assche
` (14 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Justin Tee, Paul Ely,
James E.J. Bottomley, Martin K. Petersen
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 6f6394a0047c..9274f9b04057 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..179971a293f6 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 8dd876a1a78d..3f39cc065029 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5507,6 +5507,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 cd285e87c278..8fb6d8a1cfb2 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -3722,6 +3722,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;
@@ -12876,6 +12877,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] 64+ messages in thread
* [PATCH v4 40/54] scsi: mpt3sas: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (38 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 39/54] scsi: lpfc: Prepare for enabling " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 41/54] scsi: mvsas: " Bart Van Assche
` (13 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Sathya Prakash, Sreekanth Reddy,
Suganath Prabu Subramani, Ranjan Kumar, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 41/54] scsi: mvsas: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (39 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 40/54] scsi: mpt3sas: Enable " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 42/54] scsi: pcmcia: " Bart Van Assche
` (12 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen, Kees Cook
Document locking requirements with __must_hold(). Annotate functions
that perform conditional locking with __context_unsafe().
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..d604aaac14a2 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] 64+ messages in thread
* [PATCH v4 42/54] scsi: pcmcia: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (40 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 41/54] scsi: mvsas: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 43/54] scsi: pm8001: " Bart Van Assche
` (11 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 43/54] scsi: pm8001: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (41 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 42/54] scsi: pcmcia: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 44/54] scsi: qedf: " Bart Van Assche
` (10 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Jack Wang, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements with __must_hold().
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
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 659dbd603a03..d2572dd66071 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;
@@ -3856,6 +3857,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] 64+ messages in thread
* [PATCH v4 44/54] scsi: qedf: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (42 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 43/54] scsi: pm8001: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 45/54] scsi: qedi: " Bart Van Assche
` (9 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Saurav Kashyap, Javed Hasan,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 45/54] scsi: qedi: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (43 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 44/54] scsi: qedf: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 46/54] scsi: qla1280: Pass the host pointer directly to several functions Bart Van Assche
` (8 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Nilesh Javali, Manish Rangankar,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
Annotate qedi_cleanup_all_io() with __context_unsafe() 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 37945f16811b..c8af10c32653 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -1137,6 +1137,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] 64+ messages in thread
* [PATCH v4 46/54] scsi: qla1280: Pass the host pointer directly to several functions
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (44 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 45/54] scsi: qedi: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 47/54] scsi: qla1280: Prepare for enabling lock context analysis Bart Van Assche
` (7 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
Pass the struct Scsi_Host pointer directly to
_qla1280_wait_for_single_command(), qla1280_wait_for_single_command(),
qla1280_wait_for_pending_commands(), and qla1280_error_action().
Introduce the local variable 'host' in error handling functions to avoid
repetitive dereferencing of cmd->device->host. This patch prepares for
enabling lock context analysis. No functionality has been changed.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/qla1280.c | 43 +++++++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 348c59a99cc5..863b89ac6ba2 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -735,15 +735,15 @@ static void qla1280_mailbox_timeout(struct timer_list *t)
}
static int
-_qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp,
+_qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp,
struct completion *wait)
{
int status = FAILED;
struct scsi_cmnd *cmd = sp->cmd;
- spin_unlock_irq(&ha->host->host_lock);
+ spin_unlock_irq(&host->host_lock);
wait_for_completion_timeout(wait, 4*HZ);
- spin_lock_irq(&ha->host->host_lock);
+ spin_lock_irq(&host->host_lock);
sp->wait = NULL;
if(CMD_HANDLE(cmd) == COMPLETED_HANDLE) {
status = SUCCESS;
@@ -753,16 +753,17 @@ _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)
+qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp)
{
DECLARE_COMPLETION_ONSTACK(wait);
sp->wait = &wait;
- return _qla1280_wait_for_single_command(ha, sp, &wait);
+ return _qla1280_wait_for_single_command(host, sp, &wait);
}
static int
-qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target)
+qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, struct Scsi_Host *host,
+ int bus, int target)
{
int cnt;
int status;
@@ -785,7 +786,7 @@ qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target)
if (target >= 0 && SCSI_TCN_32(cmd) != target)
continue;
- status = qla1280_wait_for_single_command(ha, sp);
+ status = qla1280_wait_for_single_command(host, sp);
if (status == FAILED)
break;
}
@@ -808,7 +809,8 @@ 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)
+qla1280_error_action(struct Scsi_Host *host, struct scsi_cmnd *cmd,
+ enum action action)
{
struct scsi_qla_host *ha;
int bus, target, lun;
@@ -914,7 +916,7 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action)
*/
if (found >= 0)
- result = _qla1280_wait_for_single_command(ha, sp, &wait);
+ result = _qla1280_wait_for_single_command(host, sp, &wait);
if (action == ABORT_COMMAND && result != SUCCESS) {
printk(KERN_WARNING
@@ -934,7 +936,7 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action)
* to wait for them.
*/
if (result == SUCCESS && wait_for_bus >= 0) {
- result = qla1280_wait_for_pending_commands(ha,
+ result = qla1280_wait_for_pending_commands(ha, host,
wait_for_bus, wait_for_target);
}
@@ -951,11 +953,12 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action)
static int
qla1280_eh_abort(struct scsi_cmnd * cmd)
{
+ struct Scsi_Host *host = cmd->device->host;
int rc;
- spin_lock_irq(&cmd->device->host->host_lock);
- rc = qla1280_error_action(cmd, ABORT_COMMAND);
- spin_unlock_irq(&cmd->device->host->host_lock);
+ spin_lock_irq(&host->host_lock);
+ rc = qla1280_error_action(host, cmd, ABORT_COMMAND);
+ spin_unlock_irq(&host->host_lock);
return rc;
}
@@ -967,11 +970,12 @@ qla1280_eh_abort(struct scsi_cmnd * cmd)
static int
qla1280_eh_device_reset(struct scsi_cmnd *cmd)
{
+ struct Scsi_Host *host = cmd->device->host;
int rc;
- spin_lock_irq(&cmd->device->host->host_lock);
- rc = qla1280_error_action(cmd, DEVICE_RESET);
- spin_unlock_irq(&cmd->device->host->host_lock);
+ spin_lock_irq(&host->host_lock);
+ rc = qla1280_error_action(host, cmd, DEVICE_RESET);
+ spin_unlock_irq(&host->host_lock);
return rc;
}
@@ -983,11 +987,12 @@ qla1280_eh_device_reset(struct scsi_cmnd *cmd)
static int
qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
{
+ struct Scsi_Host *host = cmd->device->host;
int rc;
- spin_lock_irq(&cmd->device->host->host_lock);
- rc = qla1280_error_action(cmd, BUS_RESET);
- spin_unlock_irq(&cmd->device->host->host_lock);
+ spin_lock_irq(&host->host_lock);
+ rc = qla1280_error_action(host, cmd, BUS_RESET);
+ spin_unlock_irq(&host->host_lock);
return rc;
}
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH v4 47/54] scsi: qla1280: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (45 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 46/54] scsi: qla1280: Pass the host pointer directly to several functions Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 48/54] scsi: qla2xxx: Enable " Bart Van Assche
` (6 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
Document locking requirements with __must_hold().
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/qla1280.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 863b89ac6ba2..f71e668d011c 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_Host *host, struct srb *sp,
struct completion *wait)
+ __must_hold(&host->host_lock)
{
int status = FAILED;
struct scsi_cmnd *cmd = sp->cmd;
@@ -754,6 +755,7 @@ _qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp,
static int
qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp)
+ __must_hold(&host->host_lock)
{
DECLARE_COMPLETION_ONSTACK(wait);
@@ -764,6 +766,7 @@ qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp)
static int
qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, struct Scsi_Host *host,
int bus, int target)
+ __must_hold(&host->host_lock)
{
int cnt;
int status;
@@ -811,6 +814,7 @@ qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, struct Scsi_Host *ho
static int
qla1280_error_action(struct Scsi_Host *host, struct scsi_cmnd *cmd,
enum action action)
+ __must_hold(&host->host_lock)
{
struct scsi_qla_host *ha;
int bus, target, lun;
@@ -1495,6 +1499,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;
@@ -1660,6 +1665,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 */
@@ -1710,6 +1716,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;
@@ -1849,6 +1856,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;
@@ -2418,6 +2426,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;
@@ -2543,6 +2552,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;
@@ -2603,6 +2613,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;
@@ -2637,6 +2648,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;
@@ -3754,6 +3766,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;
@@ -3886,6 +3899,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] 64+ messages in thread
* [PATCH v4 48/54] scsi: qla2xxx: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (46 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 47/54] scsi: qla1280: Prepare for enabling lock context analysis Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 49/54] scsi: qla4xxx: " Bart Van Assche
` (5 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Nilesh Javali,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
Make several code blocks with conditional locking compatible with
thread-safety analysis. Annotate functions that perform conditional
locking with __context_unsafe(). 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 2366cca51bce..1a9a0f148bb3 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 431a59d499b3..5a7caff61b16 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;
}
@@ -3775,6 +3777,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;
@@ -6728,11 +6731,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;
}
@@ -6741,6 +6746,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;
@@ -6767,12 +6773,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 fd3984127497..f96b9eb15126 100644
--- a/drivers/scsi/qla2xxx/qla_tmpl.c
+++ b/drivers/scsi/qla2xxx/qla_tmpl.c
@@ -1034,6 +1034,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] 64+ messages in thread
* [PATCH v4 49/54] scsi: qla4xxx: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (47 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 48/54] scsi: qla2xxx: Enable " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 50/54] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
` (4 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Nilesh Javali, Manish Rangankar,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen
Annotate the functions that perform conditional locking with
__context_unsafe().
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..6aeb8097a73d 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] 64+ messages in thread
* [PATCH v4 50/54] scsi: iSCSI transport: Prepare for enabling lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (48 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 49/54] scsi: qla4xxx: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 51/54] scsi: smartpqi: Enable " Bart Van Assche
` (3 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Lee Duncan, Chris Leech,
Mike Christie, James E.J. Bottomley, Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 51/54] scsi: smartpqi: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (49 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 50/54] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 52/54] scsi: snic: " Bart Van Assche
` (2 subsequent siblings)
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Tomas Henzl, Don Brace,
James E.J. Bottomley, Martin K. Petersen
Document locking requirements with __acquires(), __releases() and
__cond_releases(). Suppress context analysis complaints with __acquire()
annotations. This approach has been chosen because this driver uses the
mutex API incorrectly. Fixing this driver falls outside the scope of this
patch series.
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 d8d0fe915805..9401d9347404 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);
@@ -3672,6 +3684,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",
@@ -3683,6 +3697,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;
@@ -3693,6 +3711,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);
@@ -3700,25 +3722,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);
@@ -3749,6 +3778,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:
@@ -8893,6 +8924,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)
@@ -9653,7 +9686,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;
@@ -9687,11 +9724,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;
@@ -9715,11 +9756,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] 64+ messages in thread
* [PATCH v4 52/54] scsi: snic: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (50 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 51/54] scsi: smartpqi: Enable " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 53/54] scsi: sym53c8xx_2: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 54/54] scsi: drivers: " Bart Van Assche
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Narsimhulu Musini, Karan Tilak Kumar,
Sesidhar Baddela, James E.J. Bottomley, Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 53/54] scsi: sym53c8xx_2: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (51 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 52/54] scsi: snic: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 54/54] scsi: drivers: " Bart Van Assche
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, Matthew Wilcox, James E.J. Bottomley,
Martin K. Petersen
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] 64+ messages in thread
* [PATCH v4 54/54] scsi: drivers: Enable lock context analysis
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
` (52 preceding siblings ...)
2026-09-25 18:26 ` [PATCH v4 53/54] scsi: sym53c8xx_2: " Bart Van Assche
@ 2026-09-25 18:26 ` Bart Van Assche
53 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-25 18:26 UTC (permalink / raw)
To: Martin K . Petersen
Cc: linux-scsi, Bart Van Assche, James E.J. Bottomley,
Martin K. Petersen
Enable lock context analysis for all drivers in the drivers/scsi/ directory
except for the scsi_debug driver. The scsi_debug driver is excluded because
of a locking bug in that driver.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/Makefile | 25 ++-----------------------
1 file changed, 2 insertions(+), 23 deletions(-)
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 533623382eca..370e38625763 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -14,29 +14,8 @@
# satisfy certain initialization assumptions in the SCSI layer.
# *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!
-CONTEXT_ANALYSIS_constants.o := y
-CONTEXT_ANALYSIS_hosts.o := y
-CONTEXT_ANALYSIS_scsi.o := y
-CONTEXT_ANALYSIS_scsi_common.o := y
-CONTEXT_ANALYSIS_scsi_devinfo.o := y
-CONTEXT_ANALYSIS_scsi_dh.o := y
-CONTEXT_ANALYSIS_scsi_error.o := y
-CONTEXT_ANALYSIS_scsi_ioctl.o := y
-CONTEXT_ANALYSIS_scsi_lib.o := y
-CONTEXT_ANALYSIS_scsi_lib_dma.o := y
-CONTEXT_ANALYSIS_scsi_logging.o := y
-CONTEXT_ANALYSIS_scsi_netlink.o := y
-CONTEXT_ANALYSIS_scsi_pm.o := y
-CONTEXT_ANALYSIS_scsi_proc.o := y
-CONTEXT_ANALYSIS_scsi_scan.o := y
-CONTEXT_ANALYSIS_scsi_sysfs.o := y
-CONTEXT_ANALYSIS_scsi_trace.o := y
-CONTEXT_ANALYSIS_scsicam.o := y
-CONTEXT_ANALYSIS_sd.o := y
-CONTEXT_ANALYSIS_sd_dif.o := y
-CONTEXT_ANALYSIS_sd_zbc.o := y
-CONTEXT_ANALYSIS_sr.o := y
-CONTEXT_ANALYSIS_sr_ioctl.o := y
+CONTEXT_ANALYSIS := y
+CONTEXT_ANALYSIS_scsi_debug.o := n
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
^ permalink raw reply related [flat|nested] 64+ messages in thread
* Re: [PATCH v4 06/54] scsi: NCR5380: Prepare for enabling lock context analysis
2026-09-25 18:25 ` [PATCH v4 06/54] scsi: NCR5380: " Bart Van Assche
@ 2026-09-26 0:42 ` Finn Thain
2026-09-28 17:42 ` Bart Van Assche
0 siblings, 1 reply; 64+ messages in thread
From: Finn Thain @ 2026-09-26 0:42 UTC (permalink / raw)
To: Bart Van Assche
Cc: Martin K . Petersen, linux-scsi, Michael Schmitz,
James E.J. Bottomley, Martin K. Petersen
On Fri, 25 Sep 2026, Bart Van Assche wrote:
> Pass the struct NCR5380_hostdata pointer directly to NCR5380_select()
> and NCR5380_information_transfer() instead of the struct Scsi_Host
> pointer. This ensures that the lock context annotations
> (__releases(&hostdata->lock) and __acquires(&hostdata->lock)) refer to
> a function argument. Update callers and function prototypes accordingly.
>
> Cc: Finn Thain <fthain@linux-m68k.org>
> Cc: Michael Schmitz <schmitzmic@gmail.com>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
> drivers/scsi/NCR5380.c | 19 ++++++++++---------
> drivers/scsi/NCR5380.h | 5 +++--
> 2 files changed, 13 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
> index 006dcf981218..6afbd5936892 100644
> --- a/drivers/scsi/NCR5380.c
> +++ b/drivers/scsi/NCR5380.c
> @@ -718,7 +718,7 @@ static void NCR5380_main(struct work_struct *work)
> * entire unit.
> */
>
> - if (!NCR5380_select(instance, cmd)) {
> + if (!NCR5380_select(hostdata, cmd)) {
> dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
> } else {
> dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
> @@ -728,7 +728,7 @@ static void NCR5380_main(struct work_struct *work)
> }
> if (hostdata->connected && !hostdata->dma_len) {
> dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
> - NCR5380_information_transfer(instance);
> + NCR5380_information_transfer(hostdata);
> done = 0;
> }
> if (!hostdata->connected) {
> @@ -937,7 +937,7 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
>
> /**
> * NCR5380_select - attempt arbitration and selection for a given command
> - * @instance: the Scsi_Host instance
> + * @hostdata: host private data
> * @cmd: the scsi_cmnd to execute
> *
> * This routine establishes an I_T_L nexus for a SCSI command. This involves
> @@ -960,10 +960,11 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
> * cmd->result host byte set to DID_BAD_TARGET.
> */
>
> -static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
> +static bool NCR5380_select(struct NCR5380_hostdata *hostdata,
> + struct scsi_cmnd *cmd)
> __releases(&hostdata->lock) __acquires(&hostdata->lock)
> {
> - struct NCR5380_hostdata *hostdata = shost_priv(instance);
> + struct Scsi_Host *instance = hostdata->host;
> unsigned char tmp[3], phase;
> unsigned char *data;
> int len;
> @@ -1643,23 +1644,23 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
> }
>
> /*
> - * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
> + * Function : NCR5380_information_transfer(struct NCR5380_hostdata *hostdata)
> *
> * Purpose : run through the various SCSI phases and do as the target
> * directs us to. Operates on the currently connected command,
> * instance->connected.
> *
> - * Inputs : instance, instance for which we are doing commands
> + * Inputs : hostdata, the private host data
> *
> * Side effects : SCSI things happen, the disconnected queue will be
> * modified if a command disconnects, *instance->connected will
> * change.
> */
>
Acked-by: Finn Thain <fthain@linux-m68k.org>
Would you please update that to kerneldoc format? Something like this:
/**
* NCR5380_information_transfer - respond to information transfer phases
* @hostdata: private host data
*
* Run through various bus phases as directed by the target.
* Operates on the currently connected command until it's either completed
* or moved to the disconnected queue.
*/
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-25 18:25 ` [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions Bart Van Assche
@ 2026-09-26 20:02 ` Khalid Aziz
2026-09-28 17:41 ` Bart Van Assche
0 siblings, 1 reply; 64+ messages in thread
From: Khalid Aziz @ 2026-09-26 20:02 UTC (permalink / raw)
To: Bart Van Assche
Cc: Martin K . Petersen, linux-scsi, James E.J. Bottomley,
Martin K. Petersen
On Fri, Sep 25, 2026 at 11:25:42AM -0700, Bart Van Assche wrote:
> Pass the struct Scsi_Host pointer directly to multiple functions. This
> prepares the BusLogic driver for enabling compiler-based 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 | 93 +++++++++++++++++++++++------------------
> drivers/scsi/BusLogic.h | 2 +-
> 2 files changed, 54 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
> index 27b446c0c5d0..75aaf35383a9 100644
> --- a/drivers/scsi/BusLogic.c
> +++ b/drivers/scsi/BusLogic.c
..... snip.....
>
> @@ -2878,11 +2883,11 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt)
> Outgoing Mailbox for execution by the associated Host Adapter.
> */
>
> -static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> +static enum scsi_qc_status blogic_qcmd_lck(struct Scsi_Host *shost, struct scsi_cmnd *command)
Buslogic.c defines blogic_qcmd() usind "DEF_SCSI_QCMD(blogic_qcmd)" which in turn will call
blogic_qcmd_lck() with just struct *scsi_cmd as a single parameter as defined in
include/scsi/scsi_host.h. I did not see an update to DEF_SCSI_QCMD in patches 1-3. With this
change, callers are not being updated and that will not work. Can you double check this?
Thanks,
Khalid
> {
> void (*comp_cb)(struct scsi_cmnd *) = scsi_done;
> struct blogic_adapter *adapter =
> - (struct blogic_adapter *) command->device->host->hostdata;
> + (struct blogic_adapter *) shost->hostdata;
> struct blogic_tgt_flags *tgt_flags =
> &adapter->tgt_flags[command->device->id];
> struct blogic_tgt_stats *tgt_stats = adapter->tgt_stats;
> @@ -2913,12 +2918,12 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> probably hung so signal an error as a Host Adapter Hard Reset
> should be initiated soon.
> */
> - ccb = blogic_alloc_ccb(adapter);
> + ccb = blogic_alloc_ccb(shost);
> 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);
> - ccb = blogic_alloc_ccb(adapter);
> + spin_lock_irq(&shost->host_lock);
> + ccb = blogic_alloc_ccb(shost);
> if (ccb == NULL) {
> command->result = DID_ERROR << 16;
> comp_cb(command);
> @@ -3046,7 +3051,7 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> if (dma_mapping_error(&adapter->pci_device->dev, sense_buf)) {
> blogic_err("DMA mapping for sense data buffer failed\n",
> adapter);
> - blogic_dealloc_ccb(ccb, 0);
> + blogic_dealloc_ccb(shost, ccb, 0);
> return SCSI_MLQUEUE_HOST_BUSY;
> }
> ccb->sensedata = sense_buf;
> @@ -3061,15 +3066,15 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> so signal an error as a Host Adapter Hard Reset should
> be initiated soon.
> */
> - if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) {
> - spin_unlock_irq(&adapter->scsi_host->host_lock);
> + if (!blogic_write_outbox(shost, BLOGIC_MBOX_START, ccb)) {
> + 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);
> - if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START,
> + spin_lock_irq(&shost->host_lock);
> + if (!blogic_write_outbox(shost, BLOGIC_MBOX_START,
> ccb)) {
> blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter);
> - blogic_dealloc_ccb(ccb, 1);
> + blogic_dealloc_ccb(shost, ccb, 1);
> command->result = DID_ERROR << 16;
> scsi_done(command);
> }
> @@ -3089,12 +3094,20 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> pending.
> */
> if (ccb->status == BLOGIC_CCB_COMPLETE)
> - blogic_process_ccbs(adapter);
> + blogic_process_ccbs(shost);
> }
> return 0;
> }
>
> -static DEF_SCSI_QCMD(blogic_qcmd)
> +static enum scsi_qc_status blogic_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
> +{
> + enum scsi_qc_status rc;
> +
> + spin_lock_irq(&shost->host_lock);
> + rc = blogic_qcmd_lck(shost, cmd);
> + spin_unlock_irq(&shost->host_lock);
> + return rc;
> +}
>
> #if 0
> /*
> @@ -3103,9 +3116,8 @@ static DEF_SCSI_QCMD(blogic_qcmd)
>
> static int blogic_abort(struct scsi_cmnd *command)
> {
> - struct blogic_adapter *adapter =
> - (struct blogic_adapter *) command->device->host->hostdata;
> -
> + struct Scsi_Host *const shost = command->device->host;
> + struct blogic_adapter *adapter = (void *) shost->hostdata;
> int tgt_id = command->device->id;
> struct blogic_ccb *ccb;
> blogic_inc_count(&adapter->tgt_stats[tgt_id].aborts_request);
> @@ -3144,7 +3156,7 @@ static int blogic_abort(struct scsi_cmnd *command)
> adapter->fw_ver[0] < '5') {
> blogic_warn("Unable to Abort CCB #%ld to Target %d - Abort Tag Not Supported\n", adapter, ccb->serial, tgt_id);
> return FAILURE;
> - } else if (blogic_write_outbox(adapter, BLOGIC_MBOX_ABORT,
> + } else if (blogic_write_outbox(shost, BLOGIC_MBOX_ABORT,
> ccb)) {
> blogic_warn("Aborting CCB #%ld to Target %d\n",
> adapter, ccb->serial, tgt_id);
> @@ -3169,7 +3181,7 @@ static int blogic_abort(struct scsi_cmnd *command)
> may still be pending.
> */
> if (ccb->status == BLOGIC_CCB_COMPLETE)
> - blogic_process_ccbs(adapter);
> + blogic_process_ccbs(shost);
> return SUCCESS;
> }
> return SUCCESS;
> @@ -3181,8 +3193,9 @@ static int blogic_abort(struct scsi_cmnd *command)
> currently executing SCSI Commands as having been Reset.
> */
>
> -static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
> +static int blogic_resetadapter(struct Scsi_Host *host, bool hard_reset)
> {
> + struct blogic_adapter *adapter = (void *)host->hostdata;
> struct blogic_ccb *ccb;
> int tgt_id;
>
> @@ -3203,7 +3216,7 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
>
> for (ccb = adapter->all_ccbs; ccb != NULL; ccb = ccb->next_all)
> if (ccb->status == BLOGIC_CCB_ACTIVE)
> - blogic_dealloc_ccb(ccb, 1);
> + blogic_dealloc_ccb(host, ccb, 1);
> /*
> * Wait a few seconds between the Host Adapter Hard Reset which
> * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
> @@ -3212,9 +3225,9 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset)
> */
>
> if (hard_reset) {
> - spin_unlock_irq(&adapter->scsi_host->host_lock);
> + spin_unlock_irq(&host->host_lock);
> blogic_delay(adapter->bus_settle_time);
> - spin_lock_irq(&adapter->scsi_host->host_lock);
> + spin_lock_irq(&host->host_lock);
> }
>
> for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) {
> diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
> index 24697a5bedc8..6ace3c307a90 100644
> --- a/drivers/scsi/BusLogic.h
> +++ b/drivers/scsi/BusLogic.h
> @@ -1279,7 +1279,7 @@ 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 Scsi_Host *host, bool hard_reset);
> static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
> static int __init blogic_setup(char *);
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions
2026-09-25 18:25 ` [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions Bart Van Assche
@ 2026-09-28 6:27 ` Damien Le Moal
0 siblings, 0 replies; 64+ messages in thread
From: Damien Le Moal @ 2026-09-28 6:27 UTC (permalink / raw)
To: Bart Van Assche, Martin K . Petersen
Cc: linux-scsi, James E.J. Bottomley, Martin K. Petersen, John Garry,
Hannes Reinecke, Kees Cook, Colin Ian King
On 2026/09/25 20:25, Bart Van Assche wrote:
> Pass the struct csio_hw pointer directly to csio_scsi_cleanup_io_q(),
> csio_scsi_abort_io_q(), csio_scsim_cleanup_io(), and
> csio_scsim_cleanup_io_lnode() instead of passing the struct csio_scsim
> pointer. Update all callers and header declarations accordingly.
>
> Prepare the csiostor driver for enabling compiler-based lock context
> analysis. No functionality has been changed.
>
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-26 20:02 ` Khalid Aziz
@ 2026-09-28 17:41 ` Bart Van Assche
2026-09-28 18:55 ` Khalid Aziz
0 siblings, 1 reply; 64+ messages in thread
From: Bart Van Assche @ 2026-09-28 17:41 UTC (permalink / raw)
To: Khalid Aziz
Cc: Martin K . Petersen, linux-scsi, James E.J. Bottomley,
Martin K. Petersen
On 9/26/26 1:02 PM, Khalid Aziz wrote:
> On Fri, Sep 25, 2026 at 11:25:42AM -0700, Bart Van Assche wrote:
>> -static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
>> +static enum scsi_qc_status blogic_qcmd_lck(struct Scsi_Host *shost, struct scsi_cmnd *command)
>
> Buslogic.c defines blogic_qcmd() usind "DEF_SCSI_QCMD(blogic_qcmd)" which in turn will call
> blogic_qcmd_lck() with just struct *scsi_cmd as a single parameter as defined in
> include/scsi/scsi_host.h. I did not see an update to DEF_SCSI_QCMD in patches 1-3. With this
> change, callers are not being updated and that will not work. Can you double check this?
[ ... ]
>> -static DEF_SCSI_QCMD(blogic_qcmd)
>> +static enum scsi_qc_status blogic_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
>> +{
>> + enum scsi_qc_status rc;
>> +
>> + spin_lock_irq(&shost->host_lock);
>> + rc = blogic_qcmd_lck(shost, cmd);
>> + spin_unlock_irq(&shost->host_lock);
>> + return rc;
>> +}
Hi Khalid,
Please take a look at the above changes. It seems like these have been
overlooked.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 06/54] scsi: NCR5380: Prepare for enabling lock context analysis
2026-09-26 0:42 ` Finn Thain
@ 2026-09-28 17:42 ` Bart Van Assche
0 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-28 17:42 UTC (permalink / raw)
To: Finn Thain
Cc: Martin K . Petersen, linux-scsi, Michael Schmitz,
James E.J. Bottomley, Martin K. Petersen
On 9/25/26 5:42 PM, Finn Thain wrote:
> On Fri, 25 Sep 2026, Bart Van Assche wrote:
>> /*
>> - * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
>> + * Function : NCR5380_information_transfer(struct NCR5380_hostdata *hostdata)
>> *
>> * Purpose : run through the various SCSI phases and do as the target
>> * directs us to. Operates on the currently connected command,
>> * instance->connected.
>> *
>> - * Inputs : instance, instance for which we are doing commands
>> + * Inputs : hostdata, the private host data
>> *
>> * Side effects : SCSI things happen, the disconnected queue will be
>> * modified if a command disconnects, *instance->connected will
>> * change.
>> */
>>
>
> Acked-by: Finn Thain <fthain@linux-m68k.org>
Thanks!
> Would you please update that to kerneldoc format? Something like this:
>
> /**
> * NCR5380_information_transfer - respond to information transfer phases
> * @hostdata: private host data
> *
> * Run through various bus phases as directed by the target.
> * Operates on the currently connected command until it's either completed
> * or moved to the disconnected queue.
> */
Sure, if I have to repost this patch series I will include the above
change.
Bart.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-28 17:41 ` Bart Van Assche
@ 2026-09-28 18:55 ` Khalid Aziz
2026-09-28 19:28 ` Bart Van Assche
0 siblings, 1 reply; 64+ messages in thread
From: Khalid Aziz @ 2026-09-28 18:55 UTC (permalink / raw)
To: Bart Van Assche
Cc: Martin K . Petersen, linux-scsi, James E.J. Bottomley,
Martin K. Petersen
On Mon, Sep 28, 2026 at 10:41:38AM -0700, Bart Van Assche wrote:
> On 9/26/26 1:02 PM, Khalid Aziz wrote:
> > On Fri, Sep 25, 2026 at 11:25:42AM -0700, Bart Van Assche wrote:
> > > -static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command)
> > > +static enum scsi_qc_status blogic_qcmd_lck(struct Scsi_Host *shost, struct scsi_cmnd *command)
> >
> > Buslogic.c defines blogic_qcmd() usind "DEF_SCSI_QCMD(blogic_qcmd)" which in turn will call
> > blogic_qcmd_lck() with just struct *scsi_cmd as a single parameter as defined in
> > include/scsi/scsi_host.h. I did not see an update to DEF_SCSI_QCMD in patches 1-3. With this
> > change, callers are not being updated and that will not work. Can you double check this?
>
> [ ... ]
>
> > > -static DEF_SCSI_QCMD(blogic_qcmd)
> > > +static enum scsi_qc_status blogic_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
> > > +{
> > > + enum scsi_qc_status rc;
> > > +
> > > + spin_lock_irq(&shost->host_lock);
> > > + rc = blogic_qcmd_lck(shost, cmd);
> > > + spin_unlock_irq(&shost->host_lock);
> > > + return rc;
> > > +}
> Hi Khalid,
>
> Please take a look at the above changes. It seems like these have been
> overlooked.
Yes, that change does modify caller. I prefer not to pull in macro definitions from
header files into the driver code. This opens up possibility for API inconsistencies if the
macro in header file is ever updated. Why not extract struct *scsi_host in blogic_qcmd_lck() from
struct *scsi_cmd instead and continue to use DEF_SCSI_QCMD()?
--
Khalid
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-28 18:55 ` Khalid Aziz
@ 2026-09-28 19:28 ` Bart Van Assche
2026-09-30 20:13 ` Khalid Aziz
0 siblings, 1 reply; 64+ messages in thread
From: Bart Van Assche @ 2026-09-28 19:28 UTC (permalink / raw)
To: Khalid Aziz
Cc: Martin K . Petersen, linux-scsi, James E.J. Bottomley,
Martin K. Petersen
On 9/28/26 11:55 AM, Khalid Aziz wrote:
> I prefer not to pull in macro definitions from header files into the
> driver code. This opens up possibility for API inconsistencies if
> the macro in header file is ever updated.
The DEF_SCSI_QCMD() macro was introduced in 2010 and there have not
been any changes to its functionality in the 16 years that passed since
its introduction. Hence, I think it's unlikely that it will be changed
in the future.
> Why not extract struct *scsi_host in blogic_qcmd_lck() from
> struct *scsi_cmd instead and continue to use DEF_SCSI_QCMD()?
Because it is the only way to avoid __assume_ctx_lock() in
blogic_qcmd_lck(). __assume_ctx_lock() should be avoided if
possible because it defeats the purpose of compile-time thread-safety
analysis.
The BusLogic driver is one of the few drivers that releases and
reacquires shost->host_lock() from inside blogic_qcmd_lck(). Preventing
that the Clang compiler complains about the spin_unlock_irq() and
spin_lock_irq() calls in blogic_qcmd_lck() requires adding a
__must_hold(&shost->host_lock) annotation to the blogic_qcmd_lck()
function. And adding the __must_hold(&shost->host_lock) annotation
to the blogic_qcmd_lck() function is only possible if 'shost' is one of
the arguments of the blogic_qcmd_lck() function.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-28 19:28 ` Bart Van Assche
@ 2026-09-30 20:13 ` Khalid Aziz
2026-09-30 20:42 ` Bart Van Assche
0 siblings, 1 reply; 64+ messages in thread
From: Khalid Aziz @ 2026-09-30 20:13 UTC (permalink / raw)
To: Bart Van Assche
Cc: Martin K . Petersen, linux-scsi, James E.J. Bottomley,
Martin K. Petersen
On Mon, Sep 28, 2026 at 12:28:57PM -0700, Bart Van Assche wrote:
> On 9/28/26 11:55 AM, Khalid Aziz wrote:
> > I prefer not to pull in macro definitions from header files into the
> > driver code. This opens up possibility for API inconsistencies if
> > the macro in header file is ever updated.
> The DEF_SCSI_QCMD() macro was introduced in 2010 and there have not
> been any changes to its functionality in the 16 years that passed since
> its introduction. Hence, I think it's unlikely that it will be changed
> in the future.
>
> > Why not extract struct *scsi_host in blogic_qcmd_lck() from
> > struct *scsi_cmd instead and continue to use DEF_SCSI_QCMD()?
>
> Because it is the only way to avoid __assume_ctx_lock() in
> blogic_qcmd_lck(). __assume_ctx_lock() should be avoided if
> possible because it defeats the purpose of compile-time thread-safety
> analysis.
>
> The BusLogic driver is one of the few drivers that releases and
> reacquires shost->host_lock() from inside blogic_qcmd_lck(). Preventing
> that the Clang compiler complains about the spin_unlock_irq() and
> spin_lock_irq() calls in blogic_qcmd_lck() requires adding a
> __must_hold(&shost->host_lock) annotation to the blogic_qcmd_lck()
> function. And adding the __must_hold(&shost->host_lock) annotation
> to the blogic_qcmd_lck() function is only possible if 'shost' is one of
> the arguments of the blogic_qcmd_lck() function.
That is significant code change just to satisfy a code analysis tool. That
is making me uncomfortble to say the least. Even if DEF_SCSI_QCMD() has
not changed in 16 years, I am strongly in favor of using standard function
definitions especially when offered through a common macro for the subsystem
and in my opinion it also enforces the soft agreement on API between SCSI layers.
I am currently traveling without my laptop and it is hard for me to do proper
code review. I will get back to this in about 2 weeks.
Thanks,
Khalid
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
2026-09-30 20:13 ` Khalid Aziz
@ 2026-09-30 20:42 ` Bart Van Assche
0 siblings, 0 replies; 64+ messages in thread
From: Bart Van Assche @ 2026-09-30 20:42 UTC (permalink / raw)
To: Khalid Aziz
Cc: Martin K . Petersen, linux-scsi, James E.J. Bottomley,
Martin K. Petersen
On 9/30/26 1:13 PM, Khalid Aziz wrote:
> I am currently traveling without my laptop and it is hard for me to do proper
> code review. I will get back to this in about 2 weeks.
Hi Khalid,
Thanks for having responded anyway while traveling without laptop. I
agree that this makes it hard to review code properly.
There are several options to proceed:
- Leave out the BusLogic driver from this patch series and revisit this
driver at a later time.
- Modify DEF_SCSI_QCMD() by making it pass the 'host' argument directly
to all SCSI drivers that use this macro.
- The approach of the current patch series: open-code DEF_SCSI_QCMD() in
the BusLogic driver only.
Please let me know what you prefer.
Thanks,
Bart.
^ permalink raw reply [flat|nested] 64+ messages in thread
end of thread, other threads:[~2026-09-30 20:43 UTC | newest]
Thread overview: 64+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-25 18:25 [PATCH v4 00/54] scsi: Enable context analysis for most drivers Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 01/54] PCI: Convert to_pci_dev() into an inline function Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 02/54] scsi: sg: Prepare for enabling lock context analysis Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 03/54] scsi: st: " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions Bart Van Assche
2026-09-26 20:02 ` Khalid Aziz
2026-09-28 17:41 ` Bart Van Assche
2026-09-28 18:55 ` Khalid Aziz
2026-09-28 19:28 ` Bart Van Assche
2026-09-30 20:13 ` Khalid Aziz
2026-09-30 20:42 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 05/54] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 06/54] scsi: NCR5380: " Bart Van Assche
2026-09-26 0:42 ` Finn Thain
2026-09-28 17:42 ` Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 07/54] scsi: aacraid: Enable " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 08/54] scsi: aha152x: Prepare for enabling " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 09/54] scsi: aic7xxx: Enable " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 10/54] scsi: aic94xx: " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 11/54] scsi: arcmsr: " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 12/54] scsi: libiscsi: Pass the session pointer directly to several functions Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 13/54] scsi: libiscsi: Prepare for enabling lock context analysis Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 14/54] scsi: be2iscsi: Enable " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 15/54] scsi: cxgbi: " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 16/54] scsi: bfa: " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 17/54] scsi: bnx2fc: Pass tgt directly to several functions Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 18/54] scsi: bnx2fc: Enable lock context analysis Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 19/54] scsi: bnx2i: " Bart Van Assche
2026-09-25 18:25 ` [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions Bart Van Assche
2026-09-28 6:27 ` Damien Le Moal
2026-09-25 18:25 ` [PATCH v4 21/54] scsi: csiostor: Enable lock context analysis Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 22/54] scsi: elx: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 23/54] scsi: esas2r: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 24/54] scsi: fcoe: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 25/54] scsi: fnic: Pass pointers directly to several functions Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 26/54] scsi: fnic: Enable lock context analysis Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 27/54] scsi: hisi_sas: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 28/54] scsi: hpsa: Prepare for enabling " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 29/54] scsi: ibmvscsi: Enable " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 30/54] scsi: ibmvscsi_tgt: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 31/54] scsi: ipr: Simplify ipr_eh_abort() Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 32/54] scsi: ipr: Pass the host pointer directly to several functions Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 33/54] scsi: ipr: Prepare for enabling lock context analysis Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 34/54] scsi: ips: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 35/54] scsi: isci: Enable " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 36/54] scsi: libfc: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 37/54] scsi: libsas: Prepare for enabling " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 38/54] scsi: libsas: Enable " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 39/54] scsi: lpfc: Prepare for enabling " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 40/54] scsi: mpt3sas: Enable " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 41/54] scsi: mvsas: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 42/54] scsi: pcmcia: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 43/54] scsi: pm8001: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 44/54] scsi: qedf: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 45/54] scsi: qedi: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 46/54] scsi: qla1280: Pass the host pointer directly to several functions Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 47/54] scsi: qla1280: Prepare for enabling lock context analysis Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 48/54] scsi: qla2xxx: Enable " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 49/54] scsi: qla4xxx: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 50/54] scsi: iSCSI transport: Prepare for enabling " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 51/54] scsi: smartpqi: Enable " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 52/54] scsi: snic: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 53/54] scsi: sym53c8xx_2: " Bart Van Assche
2026-09-25 18:26 ` [PATCH v4 54/54] scsi: drivers: " Bart Van Assche
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox