scsi: Enable context analysis for most drivers
Subsystems (40)
v4 cover scsi: Enable context analysis for most drivers
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(-)
PATCH v4 1/54 PCI: Convert to_pci_dev() into an inline function
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().
--- include/linux/pci.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
include/linux/pci.h +4 -1
@@ -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)
PATCH v4 2/54 scsi: sg: Prepare for enabling lock context analysis
In reply to Bart Van AsscheAnnotate open_wait() with __must_hold() since it unlocks and locks a mutex.
--- drivers/scsi/sg.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/sg.c +1 -0
@@ -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 ;
PATCH v4 3/54 scsi: st: Prepare for enabling lock context analysis
In reply to Bart Van AsscheDocument what mutex is released by st_common_ioctl().
--- drivers/scsi/st.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/st.c +1 -0
@@ -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 ;
PATCH v4 4/54 scsi: BusLogic: Pass the host pointer directly to several functions
In reply to Bart Van AsschePass 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.
--- drivers/scsi/BusLogic.c | 93 +++++++++++++++++++++++------------------ drivers/scsi/BusLogic.h | 2 +- 2 files changed, 54 insertions(+), 41 deletions(-)
drivers/scsi/BusLogic.c +53 -40
@@ -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++) {
drivers/scsi/BusLogic.h +1 -1
@@ -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 *);
Khalid Aziz
maintainerRe: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Quoted 15 lines · Bart Van Assche
Pass the struct
Scsi_Hostpointer directly to multiple functions. This prepares the BusLogic driver for enabling compiler-based lock context analysis. No functionality has been changed.Cc Khalid Aziz <[email protected]>Signed-off-by Bart Van Assche <[email protected]>--- drivers/scsi/BusLogic.c | 93 +++++++++++++++++++++++------------------ drivers/scsi/BusLogic.h | 2 +- 2 files changed, 54 insertions(+), 41 deletions(-)drivers/scsi/BusLogic.c +0
-0
..... snip.....
drivers/scsi/BusLogic.c static int blogic_hostreset(struct scsi_cmnd *SCpnt) · line 2886
Quoted 7 lines
drivers/scsi/BusLogic.c +1
-1@@ -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
Quoted 153 lines
drivers/scsi/BusLogic.c +30
-22{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++) {drivers/scsi/BusLogic.h +1
-1@@ -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 *);
Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Quoted 8 lines · Khalid Aziz
drivers/scsi/BusLogic.c static int blogic_hostreset(struct scsi_cmnd *SCpnt) · line 2886
Quoted 2 lines · Bart Van Assche
drivers/scsi/BusLogic.c +1
-1-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.cdefinesblogic_qcmd()usind "DEF_SCSI_QCMD(blogic_qcmd)" which in turn will callblogic_qcmd_lck()with just struct*scsi_cmdas a single parameter as defined ininclude/scsi/scsi_host.h. I did not see an update toDEF_SCSI_QCMDin patches 1-3. With this change, callers are not being updated and that will not work. Can you double check this?
[ ... ]
Quoted 10 lines
drivers/scsi/BusLogic.c static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command) · line 3110
Quoted 10 lines
drivers/scsi/BusLogic.c +9
-1-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.
Khalid Aziz
maintainerRe: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Quoted 24 lines · Bart Van Assche
Quoted 8 lines · Khalid Aziz
drivers/scsi/BusLogic.c static int blogic_hostreset(struct scsi_cmnd *SCpnt) · line 2886
Quoted 2 lines · Bart Van Assche
drivers/scsi/BusLogic.c +1
-1-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.cdefinesblogic_qcmd()usind "DEF_SCSI_QCMD(blogic_qcmd)" which in turn will callblogic_qcmd_lck()with just struct*scsi_cmdas a single parameter as defined ininclude/scsi/scsi_host.h. I did not see an update toDEF_SCSI_QCMDin patches 1-3. With this change, callers are not being updated and that will not work. Can you double check this?[ ... ]
Quoted 10 lines
drivers/scsi/BusLogic.c static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command) · line 3110
Quoted 10 lines
drivers/scsi/BusLogic.c +9
-1-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,
Quoted 2 lines
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
Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Quoted 3 lines · Khalid Aziz
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.
Quoted 2 lines
Why not extract struct
*scsi_hostinblogic_qcmd_lck()from struct*scsi_cmdinstead and continue to useDEF_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.
Khalid Aziz
maintainerRe: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Quoted 17 lines · Bart Van Assche
Quoted 3 lines · Khalid Aziz
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.Quoted 2 lines
Why not extract struct
*scsi_hostinblogic_qcmd_lck()from struct*scsi_cmdinstead and continue to useDEF_SCSI_QCMD()?Because it is the only way to avoid
__assume_ctx_lock()inblogic_qcmd_lck().__assume_ctx_lock()should be avoided if possible because it defeats the purpose of compile-time thread-safety analysis.
Quoted 8 lines
The BusLogic driver is one of the few drivers that releases and reacquires
shost->host_lock()from insideblogic_qcmd_lck(). Preventing that the Clang compiler complains about thespin_unlock_irq()andspin_lock_irq()calls inblogic_qcmd_lck()requires adding a__must_hold(&shost->host_lock)annotation to theblogic_qcmd_lck()function. And adding the__must_hold(&shost->host_lock)annotation to theblogic_qcmd_lck()function is only possible if 'shost' is one of the arguments of theblogic_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
Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Quoted 2 lines · Khalid Aziz
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.
Re: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
In reply to Bart Van AsscheQuoted 11 lines · Bart Van Assche
Pass the struct
Scsi_Hostpointer directly to multiple functions. This prepares the BusLogic driver for enabling compiler-based lock context analysis. No functionality has been changed.Cc Khalid Aziz <[email protected]>Signed-off-by Bart Van Assche <[email protected]>--- drivers/scsi/BusLogic.c | 93 +++++++++++++++++++++++------------------ drivers/scsi/BusLogic.h | 2 +- 2 files changed, 54 insertions(+), 41 deletions(-)
Hi Bert,
Sorry about the delay in picking this back up.
I looked at a few other ways of accomplishing what you are trying to do and those result in more code churn than I would like. This might be the least disruptive. I found that MPT Fusion and FCoE drivers also define their queuecommand functions without using DEF_SCSI_QCMD(). These are very commonly used drivers so that makes me feel more comfortable with the change you are proposing. I am ok with this change:
--
Khalid
Quoted 301 lines
drivers/scsi/BusLogic.c +53
-40@@ -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++) {drivers/scsi/BusLogic.h +1
-1@@ -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 *);
Martin K. Petersen
maintainerRe: [PATCH v4 04/54] scsi: BusLogic: Pass the host pointer directly to several functions
Khalid,
Quoted 7 lines
I looked at a few other ways of accomplishing what you are trying to do and those result in more code churn than I would like. This might be the least disruptive. I found that MPT Fusion and FCoE drivers also define their queuecommand functions without using
DEF_SCSI_QCMD(). These are very commonly used drivers so that makes me feel more comfortable with the change you are proposing. I am ok with this change:
Applied #4 + #5 to 7.4/scsi-staging, thanks!
Signature · 1 line
Martin K. Petersen
PATCH v4 5/54 scsi: BusLogic: Prepare for enabling lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold() annotations to prepare the BusLogic driver for enabling compiler-based lock context analysis.
--- drivers/scsi/BusLogic.c | 6 ++++++ drivers/scsi/BusLogic.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/scsi/BusLogic.c +6 -0
@@ -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;
drivers/scsi/BusLogic.h +2 -1
@@ -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 *);
Re: [PATCH v4 05/54] scsi: BusLogic: Prepare for enabling lock context analysis
Quoted 11 lines · Bart Van Assche
Document locking requirements with
__must_hold()annotations to prepare the BusLogic driver for enabling compiler-based lock context analysis.Cc Khalid Aziz <[email protected]>Signed-off-by Bart Van Assche <[email protected]>--- drivers/scsi/BusLogic.c | 6 ++++++ drivers/scsi/BusLogic.h | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-)
Looks good to me.
--
Khalid
Quoted 66 lines
drivers/scsi/BusLogic.c +6
-0@@ -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;drivers/scsi/BusLogic.h +2
-1@@ -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 *);
PATCH v4 6/54 scsi: NCR5380: Prepare for enabling lock context analysis
In reply to Bart Van AsschePass 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.
--- drivers/scsi/NCR5380.c | 19 ++++++++++--------- drivers/scsi/NCR5380.h | 5 +++-- 2 files changed, 13 insertions(+), 11 deletions(-)
drivers/scsi/NCR5380.c +10 -9
@@ -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;
drivers/scsi/NCR5380.h +3 -2
@@ -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,
Re: [PATCH v4 06/54] scsi: NCR5380: Prepare for enabling lock context analysis
Quoted 68 lines · Bart Van Assche
Pass the struct
NCR5380_hostdatapointer directly toNCR5380_select()andNCR5380_information_transfer()instead of the structScsi_Hostpointer. 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 <[email protected]>Cc Michael Schmitz <[email protected]>Signed-off-by Bart Van Assche <[email protected]>--- drivers/scsi/NCR5380.c | 19 ++++++++++--------- drivers/scsi/NCR5380.h | 5 +++-- 2 files changed, 13 insertions(+), 11 deletions(-)drivers/scsi/NCR5380.c +7
-6@@ -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,
drivers/scsi/NCR5380.c static int NCR5380_transfer_dma(struct Scsi_Host *instance, · line 1659
Quoted 10 lines
drivers/scsi/NCR5380.c +1
-1* 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. */
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.
*/
Re: [PATCH v4 06/54] scsi: NCR5380: Prepare for enabling lock context analysis
Quoted 18 lines · Finn Thain
Quoted 7 lines · Bart Van Assche
/*
- * Function :NCR5380_information_transfer(structScsi_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.Quoted 9 lines
*
- * 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->connectedwill
* change.
*/
Quoted 1 line
Acked-by Finn Thain <[email protected]>
Thanks!
Quoted 10 lines
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.
PATCH v4 7/54 scsi: aacraid: Enable lock context analysis
In reply to Bart Van AsscheDocument the aac_send_reset_adapter() locking requirements with __must_hold(). Annotate functions that perform conditional locking with __context_unsafe(). Enable lock context analysis.
--- drivers/scsi/aacraid/Makefile | 2 ++ drivers/scsi/aacraid/commctrl.c | 1 + drivers/scsi/aacraid/commsup.c | 3 +++ 3 files changed, 6 insertions(+)
drivers/scsi/aacraid/Makefile +2 -0
@@ -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 \
drivers/scsi/aacraid/commctrl.c +1 -0
@@ -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;
drivers/scsi/aacraid/commsup.c +3 -0
@@ -475,6 +475,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hwint 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;
PATCH v4 8/54 scsi: aha152x: Prepare for enabling lock context analysis
In reply to Bart Van AsscheAnnotate aha152x_error() with __noreturn. This suppresses a lock context analysis compiler warning if lock context analysis is enabled.
--- drivers/scsi/aha152x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/aha152x.c +2 -2
@@ -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);
PATCH v4 9/54 scsi: aic7xxx: Enable lock context analysis
In reply to Bart Van AsscheAnnotate 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.
--- drivers/scsi/aic7xxx/Makefile | 2 ++ drivers/scsi/aic7xxx/aic79xx_osm.h | 2 ++ drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 ++ 3 files changed, 6 insertions(+)
drivers/scsi/aic7xxx/Makefile +2 -0
@@ -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
drivers/scsi/aic7xxx/aic79xx_osm.h +2 -0
@@ -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); }
drivers/scsi/aic7xxx/aic7xxx_osm.h +2 -0
@@ -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); }
PATCH v4 10/54 scsi: aic94xx: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/aic94xx/Makefile | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/aic94xx/Makefile +2 -0
@@ -6,6 +6,8 @@ # Copyright (C) 2005 Luben Tuikov <[email protected]> # +CONTEXT_ANALYSIS := y + ccflags-$(CONFIG_AIC94XX_DEBUG) := -DASD_DEBUG -DASD_ENTER_EXIT obj-$(CONFIG_SCSI_AIC94XX) += aic94xx.o
PATCH v4 11/54 scsi: arcmsr: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/arcmsr/Makefile | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/arcmsr/Makefile +2 -0
@@ -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
PATCH v4 12/54 scsi: libiscsi: Pass the session pointer directly to several functions
In reply to Bart Van AsschePass 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.
--- 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(-)
drivers/infiniband/ulp/iser/iser_initiator.c +2 -1
@@ -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;
drivers/scsi/be2iscsi/be_main.c +7 -6
@@ -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 ; }
drivers/scsi/bnx2i/bnx2i_hwi.c +21 -19
@@ -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);
drivers/scsi/cxgbi/libcxgbi.c +5 -3
@@ -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;
drivers/scsi/libiscsi.c +126 -111
714 lines not on this page · raw message
drivers/scsi/libiscsi_tcp.c +9 -8
@@ -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) {
drivers/scsi/qedi/qedi_fw.c +19 -15
@@ -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,
drivers/scsi/qla4xxx/ql4_isr.c +5 -3
@@ -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__);
include/scsi/libiscsi.h +10 -6
@@ -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
PATCH v4 13/54 scsi: libiscsi: Prepare for enabling lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold().
--- drivers/scsi/libiscsi.c | 21 +++++++++++++++++++++ include/scsi/libiscsi.h | 15 ++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-)
drivers/scsi/libiscsi.c +21 -0
@@ -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;
include/scsi/libiscsi.h +10 -5
@@ -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
PATCH v4 14/54 scsi: be2iscsi: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements by annotating locking requirements with __must_hold(). Enable lock context analysis for the be2iscsi driver by setting CONTEXT_ANALYSIS in the Makefile.
--- drivers/scsi/be2iscsi/Makefile | 2 ++ drivers/scsi/be2iscsi/be_main.c | 5 +++++ 2 files changed, 7 insertions(+)
drivers/scsi/be2iscsi/Makefile +2 -0
@@ -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
drivers/scsi/be2iscsi/be_main.c +5 -0
@@ -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;
PATCH v4 15/54 scsi: cxgbi: Enable lock context analysis
In reply to Bart Van AsscheEnable compile-time lock context analysis in the Makefile. Document where locking is missing by adding an __assume_ctx_lock() annotation.
--- drivers/scsi/cxgbi/Makefile | 3 +++ drivers/scsi/cxgbi/libcxgbi.c | 5 +++++ 2 files changed, 8 insertions(+)
drivers/scsi/cxgbi/Makefile +3 -0
@@ -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/
drivers/scsi/cxgbi/libcxgbi.c +5 -0
@@ -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) {
PATCH v4 16/54 scsi: bfa: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/bfa/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/bfa/Makefile +3 -0
@@ -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
PATCH v4 17/54 scsi: bnx2fc: Pass tgt directly to several functions
In reply to Bart Van AsschePass the tgt pointer directly to several functions. This patch prepares for enabling lock context annotation. No functionality has been changed.
--- 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(-)
drivers/scsi/bnx2fc/bnx2fc.h +4 -2
@@ -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,
drivers/scsi/bnx2fc/bnx2fc_els.c +13 -12
@@ -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 ; }
drivers/scsi/bnx2fc/bnx2fc_hwi.c +1 -1
@@ -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 ;
drivers/scsi/bnx2fc/bnx2fc_io.c +7 -7
@@ -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",
drivers/scsi/bnx2fc/bnx2fc_tgt.c +1 -1
@@ -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 ; }
PATCH v4 18/54 scsi: bnx2fc: Enable lock context analysis
In reply to Bart Van AsscheDocument the locking requirements with __must_hold(). Make the argument names in the definition and the declaration of bnx2fc_process_seq_cleanup_compl() consistent.
--- 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(-)
drivers/scsi/bnx2fc/Makefile +3 -0
@@ -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 \
drivers/scsi/bnx2fc/bnx2fc.h +2 -1
@@ -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);
drivers/scsi/bnx2fc/bnx2fc_els.c +2 -0
@@ -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;
drivers/scsi/bnx2fc/bnx2fc_io.c +1 -0
@@ -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;
PATCH v4 19/54 scsi: bnx2i: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold(). Add an __assume_ctx_lock() annotation where locking is missing.
--- drivers/scsi/bnx2i/Makefile | 3 +++ drivers/scsi/bnx2i/bnx2i_hwi.c | 5 +++++ drivers/scsi/bnx2i/bnx2i_iscsi.c | 1 + 3 files changed, 9 insertions(+)
drivers/scsi/bnx2i/Makefile +3 -0
@@ -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
drivers/scsi/bnx2i/bnx2i_hwi.c +5 -0
@@ -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)/*
drivers/scsi/bnx2i/bnx2i_iscsi.c +1 -0
@@ -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;
PATCH v4 20/54 scsi: csiostor: Pass the hw pointer directly to several functions
In reply to Bart Van AsschePass 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.
--- 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(-)
drivers/scsi/csiostor/csio_attr.c +2 -2
@@ -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);
drivers/scsi/csiostor/csio_hw.c +5 -3
@@ -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);
drivers/scsi/csiostor/csio_rnode.c +1 -2
@@ -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); }/*****************************************************************************/
drivers/scsi/csiostor/csio_scsi.c +17 -21
@@ -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 */
drivers/scsi/csiostor/csio_scsi.h +3 -4
@@ -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 **);
Re: [PATCH v4 20/54] scsi: csiostor: Pass the hw pointer directly to several functions
Quoted 9 lines · Bart Van Assche
Pass the struct
csio_hwpointer directly tocsio_scsi_cleanup_io_q(),csio_scsi_abort_io_q(),csio_scsim_cleanup_io(), andcsio_scsim_cleanup_io_lnode()instead of passing the structcsio_scsimpointer. 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 <[email protected]>
Signature · 2 lines
Damien Le Moal Western Digital Research
PATCH v4 21/54 scsi: csiostor: Enable lock context analysis
In reply to Bart Van AsscheDocument 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.
--- 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(-)
drivers/scsi/csiostor/Makefile +2 -0
@@ -4,6 +4,8 @@ # ## +CONTEXT_ANALYSIS := y + ccflags-y += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb4 obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor.o
drivers/scsi/csiostor/csio_hw.c +13 -1
@@ -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;
drivers/scsi/csiostor/csio_lnode.c +3 -0
@@ -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);
drivers/scsi/csiostor/csio_rnode.c +6 -0
@@ -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 ;
drivers/scsi/csiostor/csio_scsi.c +4 -0
@@ -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;
PATCH v4 22/54 scsi: elx: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/elx/Makefile | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/elx/Makefile +1 -0
@@ -4,6 +4,7 @@ # * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. # */ +CONTEXT_ANALYSIS := y obj-$(CONFIG_SCSI_EFCT) := efct.o
PATCH v4 23/54 scsi: esas2r: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/esas2r/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/esas2r/Makefile +3 -0
@@ -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 \
PATCH v4 24/54 scsi: fcoe: Enable lock context analysis
In reply to Bart Van AsschePass 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.
--- drivers/scsi/fcoe/Makefile | 3 +++ drivers/scsi/fcoe/fcoe_ctlr.c | 50 +++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 11 deletions(-)
drivers/scsi/fcoe/Makefile +3 -0
@@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_FCOE) += fcoe.o obj-$(CONFIG_LIBFCOE) += libfcoe.o
drivers/scsi/fcoe/fcoe_ctlr.c +39 -11
236 lines not on this page · raw message
PATCH v4 25/54 scsi: fnic: Pass pointers directly to several functions
In reply to Bart Van AsscheIn 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.
--- 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(-)
drivers/scsi/fnic/fdls_disc.c +6 -5
@@ -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 ; }
drivers/scsi/fnic/fnic_fcs.c +8 -11
@@ -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 {
drivers/scsi/fnic/fnic_fdls.h +3 -4
@@ -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);
PATCH v4 26/54 scsi: fnic: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold(). Suppress complaints about conditional locking in fnic_device_reset() with __acquire() and __release().
--- 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(-)
drivers/scsi/fnic/Makefile +3 -0
@@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_FCOE_FNIC) += fnic.o fnic-y := \
drivers/scsi/fnic/fdls_disc.c +44 -2
296 lines not on this page · raw message
drivers/scsi/fnic/fip.c +2 -0
@@ -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;
drivers/scsi/fnic/fnic_fcs.c +2 -0
@@ -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;
drivers/scsi/fnic/fnic_scsi.c +4 -0
@@ -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); }
Re: [PATCH v4 26/54] scsi: fnic: Enable lock context analysis
Hi Bart,
Quoted 6 lines · Bart Van Assche
Document locking requirements with
__must_hold(). Suppress complaints about conditional locking infnic_device_reset()with__acquire()and__release().Cc Karan Tilak Kumar <[email protected]>Signed-off-by Bart Van Assche <[email protected]>
I am seeing the following warnings/errors with LLVM 23.1.3 after this change in -next as commit 70d2304ae575 ("scsi: fnic: Enable lock context analysis"):
$ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper allmodconfig drivers/scsi/fnic/
drivers/scsi/fnic/fnic_nvme.c:1332:2: error: releasing spinlock 'iport->fnic->fnic_lock' that was not held [-Werror,-Wthread-safety-analysis]
1332 | spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
| ^
drivers/scsi/fnic/fnic_nvme.c:1336:1: error: spinlock 'iport->fnic->fnic_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis]
1336 | }
| ^
drivers/scsi/fnic/fnic_nvme.c:1335:2: note: spinlock acquired here
1335 | spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
| ^
include/linux/spinlock.h:389:35: note: expanded from macro 'spin_lock_irqsave'
389 | __release(spinlock_check(lock)); __acquire(lock); \
| ^
include/linux/compiler-context-analysis.h:375:23: note: expanded from macro '__acquire'
375 | #define __acquire(x) __acquire_ctx_lock(x)
| ^
drivers/scsi/fnic/fnic_nvme.c:1445:2: error: releasing spinlock 'iport->fnic->fnic_lock' that was not held [-Werror,-Wthread-safety-analysis]
1445 | spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags);
| ^
drivers/scsi/fnic/fnic_nvme.c:1449:1: error: spinlock 'iport->fnic->fnic_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis]
1449 | }
| ^
drivers/scsi/fnic/fnic_nvme.c:1448:2: note: spinlock acquired here
1448 | spin_lock_irqsave(&fnic->fnic_lock, fnic->lock_flags);
| ^
include/linux/spinlock.h:389:35: note: expanded from macro 'spin_lock_irqsave'
389 | __release(spinlock_check(lock)); __acquire(lock); \
| ^
include/linux/compiler-context-analysis.h:375:23: note: expanded from macro '__acquire'
375 | #define __acquire(x) __acquire_ctx_lock(x)
| ^
drivers/scsi/fnic/fnic_nvme.c:2120:2: error: releasing spinlock 'iport->fnic->fnic_lock' that was not held [-Werror,-Wthread-safety-analysis]
2120 | spin_unlock_irqrestore(&fnic->fnic_lock, flags);
| ^
drivers/scsi/fnic/fnic_nvme.c:2178:1: error: spinlock 'iport->fnic->fnic_lock' is not held on every path through here [-Werror,-Wthread-safety-analysis]
2178 | }
| ^
drivers/scsi/fnic/fnic_nvme.c:2144:2: note: spinlock acquired here
2144 | spin_lock_irqsave(&fnic->fnic_lock, flags);
| ^
include/linux/spinlock.h:389:35: note: expanded from macro 'spin_lock_irqsave'
389 | __release(spinlock_check(lock)); __acquire(lock); \
| ^
include/linux/compiler-context-analysis.h:375:23: note: expanded from macro '__acquire'
375 | #define __acquire(x) __acquire_ctx_lock(x)
| ^
drivers/scsi/fnic/fnic_nvme.c:2199:2: error: releasing spinlock 'fnic->fnic_lock' that was not held [-Werror,-Wthread-safety-analysis]
2199 | spin_unlock_irqrestore(&fnic->fnic_lock, flags);
| ^
drivers/scsi/fnic/fnic_nvme.c:2215:1: error: spinlock 'fnic->fnic_lock' is still held at the end of function [-Werror,-Wthread-safety-analysis]
2215 | }
| ^
drivers/scsi/fnic/fnic_nvme.c:2202:2: note: spinlock acquired here
2202 | spin_lock_irqsave(&fnic->fnic_lock, flags);
| ^
include/linux/spinlock.h:389:35: note: expanded from macro 'spin_lock_irqsave'
389 | __release(spinlock_check(lock)); __acquire(lock); \
| ^
include/linux/compiler-context-analysis.h:375:23: note: expanded from macro '__acquire'
375 | #define __acquire(x) __acquire_ctx_lock(x)
| ^
8 errors generated.Signature · 2 lines
Cheers, Nathan
Re: [PATCH v4 26/54] scsi: fnic: Enable lock context analysis
Quoted 10 lines · Nathan Chancellor
Hi Bart,
Quoted 6 lines · Bart Van Assche
Document locking requirements with
__must_hold(). Suppress complaints about conditional locking infnic_device_reset()with__acquire()and__release().Cc Karan Tilak Kumar <[email protected]>Signed-off-by Bart Van Assche <[email protected]>
Quoted 8 lines
I am seeing the following warnings/errors with LLVM 23.1.3 after this change in -next as commit
70d2304ae575("scsi: fnic: Enable lock context analysis"):$ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper allmodconfig drivers/scsi/fnic/ drivers/scsi/fnic/fnic_nvme.c:1332:2: error: releasing spinlock 'iport->fnic->fnic_lock' that was not held [-Werror,-Wthread-safety-analysis] 1332 | spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags); | ^
I can't reproduce this with LLVM built from git HEAD (commit d7ae8658cb98b2ef2c7e6ebf21912f31d2c1feeb). Could the above indicate a bug in LLVM 23.1.3?
Thanks,
Bart.
Re: [PATCH v4 26/54] scsi: fnic: Enable lock context analysis
Quoted 15 lines · Bart Van Assche
Quoted 14 lines · Nathan Chancellor
Hi Bart,
Quoted 6 lines · Bart Van Assche
Document locking requirements with
__must_hold(). Suppress complaints about conditional locking infnic_device_reset()with__acquire()and__release().Cc Karan Tilak Kumar <[email protected]>Signed-off-by Bart Van Assche <[email protected]>I am seeing the following warnings/errors with LLVM 23.1.3 after this change in -next as commit
70d2304ae575("scsi: fnic: Enable lock context analysis"):
Quoted 8 lines
Quoted 4 lines
$ make -skj"$(nproc)" ARCH=x86_64 LLVM=1 mrproper allmodconfig drivers/scsi/fnic/ drivers/scsi/fnic/fnic_nvme.c:1332:2: error: releasing spinlock 'iport->fnic->fnic_lock' that was not held [-Werror,-Wthread-safety-analysis] 1332 | spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags); | ^I can't reproduce this with LLVM built from git HEAD (commit
d7ae8658cb98b2ef2c7e6ebf21912f31d2c1feeb). Could the above indicate a bug in LLVM 23.1.3?
I can reproduce it with clang @ 1ae71725e3edb2bb5c5bed7f2cff9d2f22e10636 so it doesn't seem like something specific to LLVM 23. Is it configuration related?
Signature · 2 lines
Cheers, Nathan
Re: [PATCH v4 26/54] scsi: fnic: Enable lock context analysis
Quoted 3 lines · Nathan Chancellor
I can reproduce it with clang @
1ae71725e3edb2bb5c5bed7f2cff9d2f22e10636so it doesn't seem like something specific to LLVM 23. Is it configuration related?
CONFIG_NVME_FC was missing from my kernel config. I will send a patch.
Thanks,
Bart.
PATCH v4 27/54 scsi: hisi_sas: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/hisi_sas/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/hisi_sas/Makefile +3 -0
@@ -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
PATCH v4 28/54 scsi: hpsa: Prepare for enabling lock context analysis
In reply to Bart Van Asschemutex_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().
--- drivers/scsi/hpsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/hpsa.c +1 -1
@@ -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 ; }
PATCH v4 29/54 scsi: ibmvscsi: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/ibmvscsi/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/ibmvscsi/Makefile +3 -0
@@ -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
PATCH v4 30/54 scsi: ibmvscsi_tgt: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold() and enable lock context analysis.
--- drivers/scsi/ibmvscsi_tgt/Makefile | 3 +++ drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 34 +++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-)
drivers/scsi/ibmvscsi_tgt/Makefile +3 -0
@@ -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
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +33 -1
@@ -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 ;
PATCH v4 31/54 scsi: ipr: Simplify ipr_eh_abort()
In reply to Bart Van AsscheDerive the SCSI host pointer once instead of three times. This was detected by Sashiko. No functionality has been changed.
--- drivers/scsi/ipr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/ipr.c +4 -4
@@ -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);
PATCH v4 32/54 scsi: ipr: Pass the host pointer directly to several functions
In reply to Bart Van AsschePass 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.
--- drivers/scsi/ipr.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-)
drivers/scsi/ipr.c +22 -15
@@ -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);/*
PATCH v4 33/54 scsi: ipr: Prepare for enabling lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold().
--- drivers/scsi/ipr.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/ipr.c +1 -0
@@ -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;
PATCH v4 34/54 scsi: ips: Prepare for enabling lock context analysis
In reply to Bart Van AsscheAnnotate ips_next() with __context_unsafe() because it performs conditional locking.
--- drivers/scsi/ips.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/ips.c +1 -0
@@ -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 ;
PATCH v4 35/54 scsi: isci: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/isci/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/isci/Makefile +3 -0
@@ -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 \
PATCH v4 36/54 scsi: libfc: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold().
--- 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(-)
drivers/scsi/libfc/Makefile +2 -0
@@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # $Id: Makefile +CONTEXT_ANALYSIS := y + obj-$(CONFIG_LIBFC) += libfc.o libfc-objs := \
drivers/scsi/libfc/fc_disc.c +6 -1
@@ -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;
drivers/scsi/libfc/fc_exch.c +6 -0
@@ -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));
drivers/scsi/libfc/fc_fcp.c +16 -1
@@ -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;
PATCH v4 37/54 scsi: libsas: Prepare for enabling lock context analysis
In reply to Bart Van AsscheSince Clang requires that lock context annotations only refer to variables that are visible, modify a __must_hold() annotation.
--- drivers/scsi/libsas/sas_ata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/libsas/sas_ata.c +1 -1
@@ -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;
PATCH v4 38/54 scsi: libsas: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/libsas/Makefile | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/libsas/Makefile +2 -0
@@ -6,6 +6,8 @@ # Copyright (C) 2005 Luben Tuikov <[email protected]> # +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas.o libsas-y += sas_init.o \ sas_phy.o \
PATCH v4 39/54 scsi: lpfc: Prepare for enabling lock context analysis
In reply to Bart Van AsscheAnnotate the functions that perform conditional locking with __context_unsafe().
--- 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(+)
drivers/scsi/lpfc/lpfc_els.c +2 -0
@@ -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);
drivers/scsi/lpfc/lpfc_nportdisc.c +1 -0
@@ -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);
drivers/scsi/lpfc/lpfc_scsi.c +1 -0
@@ -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));
drivers/scsi/lpfc/lpfc_sli.c +2 -0
@@ -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;
PATCH v4 40/54 scsi: mpt3sas: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/mpt3sas/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/mpt3sas/Makefile +3 -0
@@ -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 \
PATCH v4 41/54 scsi: mvsas: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold(). Annotate functions that perform conditional locking with __context_unsafe().
--- drivers/scsi/mvsas/Makefile | 2 ++ drivers/scsi/mvsas/mv_sas.c | 7 +++++++ 2 files changed, 9 insertions(+)
drivers/scsi/mvsas/Makefile +2 -0
@@ -7,6 +7,8 @@ # Copyright 2009-2011 Marvell. <[email protected]> # +CONTEXT_ANALYSIS := y + ccflags-$(CONFIG_SCSI_MVSAS_DEBUG) := -DMV_DEBUG obj-$(CONFIG_SCSI_MVSAS) += mvsas.o
drivers/scsi/mvsas/mv_sas.c +7 -0
@@ -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;
PATCH v4 42/54 scsi: pcmcia: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/pcmcia/Makefile | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/pcmcia/Makefile +2 -0
@@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 +CONTEXT_ANALYSIS := y + ccflags-y := -I $(srctree)/drivers/scsi # 16-bit client drivers
PATCH v4 43/54 scsi: pm8001: Enable lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold().
--- drivers/scsi/pm8001/Makefile | 1 + drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++ 2 files changed, 3 insertions(+)
drivers/scsi/pm8001/Makefile +1 -0
@@ -4,6 +4,7 @@ # # Copyright (C) 2008-2009 USI Co., Ltd. +CONTEXT_ANALYSIS := y obj-$(CONFIG_SCSI_PM8001) += pm80xx.o
drivers/scsi/pm8001/pm80xx_hwi.c +2 -0
@@ -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 );
PATCH v4 44/54 scsi: qedf: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/qedf/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/qedf/Makefile +3 -0
@@ -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
PATCH v4 45/54 scsi: qedi: Enable lock context analysis
In reply to Bart Van AsscheAnnotate qedi_cleanup_all_io() with __context_unsafe() since it performs conditional locking.
--- drivers/scsi/qedi/Makefile | 3 +++ drivers/scsi/qedi/qedi_fw.c | 1 + 2 files changed, 4 insertions(+)
drivers/scsi/qedi/Makefile +3 -0
@@ -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
drivers/scsi/qedi/qedi_fw.c +1 -0
@@ -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;
PATCH v4 46/54 scsi: qla1280: Pass the host pointer directly to several functions
In reply to Bart Van AsschePass 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.
--- drivers/scsi/qla1280.c | 43 +++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-)
drivers/scsi/qla1280.c +24 -19
@@ -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; }
PATCH v4 47/54 scsi: qla1280: Prepare for enabling lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold().
--- drivers/scsi/qla1280.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/scsi/qla1280.c +14 -0
@@ -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 *hostatic 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;
PATCH v4 48/54 scsi: qla2xxx: Enable lock context analysis
In reply to Bart Van AsscheMake 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.
--- 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(-)
drivers/scsi/qla2xxx/Makefile +3 -0
@@ -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 \
drivers/scsi/qla2xxx/qla_nx.c +2 -0
@@ -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 ;
drivers/scsi/qla2xxx/qla_target.c +18 -11
@@ -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 ; }
drivers/scsi/qla2xxx/qla_tmpl.c +1 -0
@@ -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 ;
PATCH v4 49/54 scsi: qla4xxx: Enable lock context analysis
In reply to Bart Van AsscheAnnotate the functions that perform conditional locking with __context_unsafe().
--- drivers/scsi/qla4xxx/Makefile | 3 +++ drivers/scsi/qla4xxx/ql4_nx.c | 2 ++ 2 files changed, 5 insertions(+)
drivers/scsi/qla4xxx/Makefile +3 -0
@@ -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
drivers/scsi/qla4xxx/ql4_nx.c +2 -0
@@ -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;
PATCH v4 50/54 scsi: iSCSI transport: Prepare for enabling lock context analysis
In reply to Bart Van AsscheDocument locking requirements with __must_hold().
--- drivers/scsi/scsi_transport_iscsi.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/scsi_transport_iscsi.c +1 -0
@@ -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);
PATCH v4 51/54 scsi: smartpqi: Enable lock context analysis
In reply to Bart Van AsscheDocument 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.
--- drivers/scsi/smartpqi/Makefile | 3 ++ drivers/scsi/smartpqi/smartpqi_init.c | 67 ++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 11 deletions(-)
drivers/scsi/smartpqi/Makefile +3 -0
@@ -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
drivers/scsi/smartpqi/smartpqi_init.c +56 -11
188 lines not on this page · raw message
PATCH v4 52/54 scsi: snic: Enable lock context analysis
In reply to Bart Van AsscheSet the CONTEXT_ANALYSIS variable in the Makefile.
--- drivers/scsi/snic/Makefile | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/snic/Makefile +3 -0
@@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_SNIC) += snic.o snic-y := \
PATCH v4 53/54 scsi: sym53c8xx_2: Enable lock context analysis
In reply to Bart Van Assche--- drivers/scsi/sym53c8xx_2/Makefile | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/sym53c8xx_2/Makefile +2 -0
@@ -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
PATCH v4 54/54 scsi: drivers: Enable lock context analysis
In reply to Bart Van AsscheEnable 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.
--- drivers/scsi/Makefile | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-)
drivers/scsi/Makefile +2 -23
@@ -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
Bart,
Quoted 2 lines
This patch series enables lock context analysis for all SCSI drivers in the
drivers/scsi/directory exceptscsi_debug.
Applied to 7.4/scsi-staging with the exception of the BusLogic changes. Thanks!
Signature · 1 line
Martin K. Petersen
Quoted 10 lines · Bart Van Assche
This patch series enables lock context analysis for all SCSI drivers in the
drivers/scsi/directory exceptscsi_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'.[...]
Applied to 7.4/scsi-queue, thanks!
[01/54] PCI: Convert to_pci_dev() into an inline function
https://git.kernel.org/mkp/scsi/c/e46ce4e8ef2e [02/54] scsi: sg: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/c5b5b5786ae1 [03/54] scsi: st: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/d69fcaa34b67 [06/54] scsi: NCR5380: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/a51e9948d168 [07/54] scsi: aacraid: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/44bb77a1afaf [08/54] scsi: aha152x: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/825b26b342eb [09/54] scsi: aic7xxx: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/22d469241b6b [10/54] scsi: aic94xx: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/678dd8c98ef5 [11/54] scsi: arcmsr: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/5a08252a78e1 [12/54] scsi: libiscsi: Pass the session pointer directly to several functions https://git.kernel.org/mkp/scsi/c/ae1c0d65bc71 [13/54] scsi: libiscsi: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/bbee7e5b4fd9 [14/54] scsi: be2iscsi: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/901ade3fa13c [15/54] scsi: cxgbi: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/f3e83f658751 [16/54] scsi: bfa: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/d9a376f43c1b [17/54] scsi: bnx2fc: Pass tgt directly to several functions https://git.kernel.org/mkp/scsi/c/32f9cdb45bdb [18/54] scsi: bnx2fc: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/9495fadabea9 [19/54] scsi: bnx2i: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/89cb9bbfcb6c [20/54] scsi: csiostor: Pass the hw pointer directly to several functions https://git.kernel.org/mkp/scsi/c/640361f6a944 [21/54] scsi: csiostor: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/7a6d3b98469d [22/54] scsi: elx: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/8281912eda17 [23/54] scsi: esas2r: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/5ba6b666f701 [24/54] scsi: fcoe: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/f9581845d992 [25/54] scsi: fnic: Pass pointers directly to several functions https://git.kernel.org/mkp/scsi/c/ac063a30e80d [26/54] scsi: fnic: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/70d2304ae575 [27/54] scsi: hisi_sas: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/11c345d6dbd8 [28/54] scsi: hpsa: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/107115c393ea [29/54] scsi: ibmvscsi: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/256962ec2846 [30/54] scsi: ibmvscsi_tgt: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/fc4f84fdc528 [31/54] scsi: ipr: Simplify ipr_eh_abort() https://git.kernel.org/mkp/scsi/c/2a0cb1a2423d [32/54] scsi: ipr: Pass the host pointer directly to several functions https://git.kernel.org/mkp/scsi/c/e2bb4cd08080 [33/54] scsi: ipr: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/9c176edb892c [34/54] scsi: ips: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/68ce6d43f4ff [35/54] scsi: isci: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/10385e735e8a [36/54] scsi: libfc: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/3a6d7333e3f2 [37/54] scsi: libsas: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/4901e49c5c60 [38/54] scsi: libsas: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/554a002f96f3 [39/54] scsi: lpfc: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/b6ac5193c692 [40/54] scsi: mpt3sas: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/8d3d0e8d26a6 [41/54] scsi: mvsas: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/53812028f864 [42/54] scsi: pcmcia: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/202aeb5af5e2 [43/54] scsi: pm8001: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/74688075dd07 [44/54] scsi: qedf: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/cdc1694e333b [45/54] scsi: qedi: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/6210d20f7fe4 [46/54] scsi: qla1280: Pass the host pointer directly to several functions https://git.kernel.org/mkp/scsi/c/5bb1688785a5 [47/54] scsi: qla1280: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/23d5f939d99f [48/54] scsi: qla2xxx: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/5ed1a2dd293a [49/54] scsi: qla4xxx: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/20026b0b55ec [50/54] scsi: iSCSI transport: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/d5f024412d23 [51/54] scsi: smartpqi: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/78b27248f721 [52/54] scsi: snic: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/e24eedc81ec4 [53/54] scsi: sym53c8xx_2: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/659dec2ce32e [54/54] scsi: drivers: Enable lock context analysis https://git.kernel.org/mkp/scsi/c/782a516e8f43
Signature · 1 line
Martin K. Petersen
Re: (subset) [PATCH v4 00/54] scsi: Enable context analysis for most drivers
In reply to Bart Van AsscheQuoted 10 lines · Bart Van Assche
This patch series enables lock context analysis for all SCSI drivers in the
drivers/scsi/directory exceptscsi_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'.[...]
Applied to 7.4/scsi-queue, thanks!
[04/54] scsi: BusLogic: Pass the host pointer directly to several functions
https://git.kernel.org/mkp/scsi/c/b54bd8da110d [05/54] scsi: BusLogic: Prepare for enabling lock context analysis https://git.kernel.org/mkp/scsi/c/ba80a742b3e1
Signature · 1 line
Martin K. Petersen