From: Bart Van Assche <bvanassche@acm.org>
To: "Martin K . Petersen" <martin.petersen@oracle.com>
Cc: linux-scsi@vger.kernel.org, Bart Van Assche <bvanassche@acm.org>,
Jianzhou Zhao <luckd0g@163.com>,
"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
Kashyap Desai <kashyap.desai@broadcom.com>,
Sumit Saxena <sumit.saxena@broadcom.com>,
Shivasharan S <shivasharan.srikanteshwara@broadcom.com>,
Chandrakanth patil <chandrakanth.patil@broadcom.com>,
Sathya Prakash <sathya.prakash@broadcom.com>,
Sreekanth Reddy <sreekanth.reddy@broadcom.com>,
Suganath Prabu Subramani <suganath-prabu.subramani@broadcom.com>,
Ranjan Kumar <ranjan.kumar@broadcom.com>,
Nilesh Javali <njavali@marvell.com>,
Manish Rangankar <mrangankar@marvell.com>,
GR-QLogic-Storage-Upstream@marvell.com
Subject: [PATCH 36/36] scsi: core: Protect host state changes with the host lock
Date: Thu, 12 Mar 2026 14:15:47 -0700 [thread overview]
Message-ID: <20260312211636.3245119-37-bvanassche@acm.org> (raw)
In-Reply-To: <20260312211636.3245119-1-bvanassche@acm.org>
Some but not all SCSI host state changes are protected with the SCSI
host lock. Annotate the SCSI host state with __guarded_by(&host_lock),
protect all SCSI host state changes with the SCSI host lock and use
READ_ONCE() for all SCSI host state reads. This patch prevents that
KCSAN complains about data races when accessing the SCSI host state.
Reported-by: Jianzhou Zhao <luckd0g@163.com>
Closes: https://lore.kernel.org/all/36d59d0e.6db0.19cdbeee01b.Coremail.luckd0g@163.com/
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
drivers/scsi/hosts.c | 13 ++++++++-----
drivers/scsi/megaraid/megaraid_sas_base.c | 2 +-
drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +-
drivers/scsi/qla4xxx/ql4_os.c | 6 ++----
drivers/scsi/scsi_lib.c | 3 +--
drivers/scsi/scsi_sysfs.c | 7 ++++---
include/scsi/scsi_host.h | 23 ++++++++++++++++-------
7 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index e047747d4ecf..7482ae7777c8 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -278,7 +278,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
if (error)
goto out_disable_runtime_pm;
- scsi_host_set_state(shost, SHOST_RUNNING);
+ scoped_guard(spinlock_irq, shost->host_lock)
+ scsi_host_set_state(shost, SHOST_RUNNING);
get_device(shost->shost_gendev.parent);
device_enable_async_suspend(&shost->shost_dev);
@@ -352,6 +353,7 @@ EXPORT_SYMBOL(scsi_add_host_with_dma);
static void scsi_host_dev_release(struct device *dev)
{
struct Scsi_Host *shost = dev_to_shost(dev);
+ enum scsi_host_state host_state = scsi_get_host_state(shost);
struct device *parent = dev->parent;
/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
@@ -364,7 +366,7 @@ static void scsi_host_dev_release(struct device *dev)
if (shost->work_q)
destroy_workqueue(shost->work_q);
- if (shost->shost_state == SHOST_CREATED) {
+ if (host_state == SHOST_CREATED) {
/*
* Free the shost_dev device name and remove the proc host dir
* here if scsi_host_{alloc,put}() have been called but neither
@@ -380,7 +382,7 @@ static void scsi_host_dev_release(struct device *dev)
ida_free(&host_index_ida, shost->host_no);
- if (shost->shost_state != SHOST_CREATED)
+ if (host_state != SHOST_CREATED)
put_device(parent);
kfree(shost);
}
@@ -414,7 +416,8 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv
shost->host_lock = &shost->default_lock;
spin_lock_init(shost->host_lock);
- shost->shost_state = SHOST_CREATED;
+ scoped_guard(spinlock_init, shost->host_lock)
+ shost->shost_state = SHOST_CREATED;
INIT_LIST_HEAD(&shost->__devices);
INIT_LIST_HEAD(&shost->__targets);
INIT_LIST_HEAD(&shost->eh_abort_list);
@@ -600,7 +603,7 @@ EXPORT_SYMBOL(scsi_host_lookup);
**/
struct Scsi_Host *scsi_host_get(struct Scsi_Host *shost)
{
- if ((shost->shost_state == SHOST_DEL) ||
+ if (scsi_get_host_state(shost) == SHOST_DEL ||
!get_device(&shost->shost_gendev))
return NULL;
return shost;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index ccefe5841a17..97a81a86db82 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3075,7 +3075,7 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
scmd_printk(KERN_INFO, scmd,
"SCSI host state: %d SCSI host busy: %d FW outstanding: %d\n",
- scmd->device->host->shost_state,
+ scsi_get_host_state(scmd->device->host),
scsi_host_busy(scmd->device->host),
atomic_read(&instance->fw_outstanding));
/*
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6ff788557294..e40913d2479e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -5460,7 +5460,7 @@ static enum scsi_qc_status scsih_qcmd(struct Scsi_Host *shost,
* Avoid error handling escallation when device is disconnected
*/
if (handle == MPT3SAS_INVALID_DEVICE_HANDLE || sas_device_priv_data->block) {
- if (scmd->device->host->shost_state == SHOST_RECOVERY &&
+ if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY &&
scmd->cmnd[0] == TEST_UNIT_READY) {
scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07);
scsi_done(scmd);
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index d598ab4126f8..c9d9fc7c81fb 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -9411,11 +9411,9 @@ static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
* This routine finds that if reset host is called in EH
* scenario or from some application like sg_reset
**/
-static int qla4xxx_is_eh_active(struct Scsi_Host *shost)
+static bool qla4xxx_is_eh_active(struct Scsi_Host *shost)
{
- if (shost->shost_state == SHOST_RECOVERY)
- return 1;
- return 0;
+ return scsi_get_host_state(shost) == SHOST_RECOVERY;
}
/**
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6e8c7a42603e..5f7580b089e9 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1638,10 +1638,9 @@ static enum scsi_qc_status scsi_dispatch_cmd(struct scsi_cmnd *cmd)
goto done;
}
- if (unlikely(host->shost_state == SHOST_DEL)) {
+ if (scsi_get_host_state(host) == SHOST_DEL) {
cmd->result = (DID_NO_CONNECT << 16);
goto done;
-
}
trace_scsi_dispatch_cmd_start(cmd);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index dfc3559e7e04..9480432f650b 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -214,8 +214,9 @@ store_shost_state(struct device *dev, struct device_attribute *attr,
if (!state)
return -EINVAL;
- if (scsi_host_set_state(shost, state))
- return -EINVAL;
+ scoped_guard(spinlock_irq, shost->host_lock)
+ if (scsi_host_set_state(shost, state))
+ return -EINVAL;
return count;
}
@@ -223,7 +224,7 @@ static ssize_t
show_shost_state(struct device *dev, struct device_attribute *attr, char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
- const char *name = scsi_host_state_name(shost->shost_state);
+ const char *name = scsi_host_state_name(scsi_get_host_state(shost));
if (!name)
return -EINVAL;
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 2bbe7cb0060b..9841402e8bdf 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -729,7 +729,7 @@ struct Scsi_Host {
unsigned int irq;
- enum scsi_host_state shost_state;
+ enum scsi_host_state shost_state __guarded_by(&host_lock);
/* ldm bits */
struct device shost_gendev, shost_dev;
@@ -787,11 +787,18 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
return container_of(dev, struct Scsi_Host, shost_gendev);
}
+static inline enum scsi_host_state scsi_get_host_state(struct Scsi_Host *shost)
+{
+ return context_unsafe(READ_ONCE(shost->shost_state));
+}
+
static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
{
- return shost->shost_state == SHOST_RECOVERY ||
- shost->shost_state == SHOST_CANCEL_RECOVERY ||
- shost->shost_state == SHOST_DEL_RECOVERY ||
+ enum scsi_host_state state = scsi_get_host_state(shost);
+
+ return state == SHOST_RECOVERY ||
+ state == SHOST_CANCEL_RECOVERY ||
+ state == SHOST_DEL_RECOVERY ||
shost->tmf_in_progress;
}
@@ -837,8 +844,9 @@ static inline struct device *scsi_get_device(struct Scsi_Host *shost)
**/
static inline int scsi_host_scan_allowed(struct Scsi_Host *shost)
{
- return shost->shost_state == SHOST_RUNNING ||
- shost->shost_state == SHOST_RECOVERY;
+ enum scsi_host_state state = scsi_get_host_state(shost);
+
+ return state == SHOST_RUNNING || state == SHOST_RECOVERY;
}
extern void scsi_unblock_requests(struct Scsi_Host *);
@@ -942,6 +950,7 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
return shost->prot_guard_type;
}
-extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state);
+int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
+ __must_hold(&shost->host_lock);
#endif /* _SCSI_SCSI_HOST_H */
prev parent reply other threads:[~2026-03-12 21:19 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-12 21:15 [PATCH 00/36] Enable lock context analysis for most SCSI drivers Bart Van Assche
2026-03-12 21:15 ` [PATCH 01/36] scsi: core: Prepare for enabling lock context analysis Bart Van Assche
2026-03-12 21:15 ` [PATCH 02/36] scsi: scsi_debug: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 03/36] scsi: sg: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 04/36] scsi: st: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 05/36] scsi: BusLogic: Introduce a local variable Bart Van Assche
2026-03-26 20:50 ` Khalid Aziz
2026-03-12 21:15 ` [PATCH 06/36] scsi: BusLogic: Prepare for enabling lock context analysis Bart Van Assche
2026-03-26 20:59 ` Khalid Aziz
2026-03-12 21:15 ` [PATCH 07/36] scsi: NCR5380: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 08/36] scsi: aacraid: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 09/36] scsi: aha152x: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 10/36] scsi: aic7xxx: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 11/36] scsi: be2iscsi: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 12/36] scsi: bnx2fc: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 13/36] scsi: bnx2i: Introduce a local variable Bart Van Assche
2026-03-12 21:15 ` [PATCH 14/36] scsi: bnx2i: Prepare for enabling lock context analysis Bart Van Assche
2026-03-12 21:15 ` [PATCH 15/36] scsi: csiostor: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 16/36] scsi: fnic: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 17/36] scsi: hpsa: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 18/36] scsi: ibmvscsi_tgt: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 19/36] scsi: ipr: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 20/36] scsi: ips: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 21/36] scsi: libfc: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 22/36] scsi: libiscsi: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 23/36] scsi: libsas: " Bart Van Assche
2026-03-13 1:35 ` Jason Yan
2026-03-12 21:15 ` [PATCH 24/36] scsi: lpfc: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 25/36] scsi: megaraid_sas: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 26/36] scsi: mvsas: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 27/36] scsi: pm8001: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 28/36] scsi: qedi: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 29/36] scsi: qla1280: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 30/36] scsi: qla2xxx: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 31/36] scsi: qla4xxx: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 32/36] scsi: ufs: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 33/36] scsi: iSCSI transport: " Bart Van Assche
2026-03-12 21:15 ` [PATCH 34/36] scsi: smartpqi: " Bart Van Assche
2026-03-16 15:36 ` Don.Brace
2026-03-12 21:15 ` [PATCH 35/36] scsi: Enable " Bart Van Assche
2026-03-12 21:15 ` Bart Van Assche [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260312211636.3245119-37-bvanassche@acm.org \
--to=bvanassche@acm.org \
--cc=GR-QLogic-Storage-Upstream@marvell.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=chandrakanth.patil@broadcom.com \
--cc=kashyap.desai@broadcom.com \
--cc=linux-scsi@vger.kernel.org \
--cc=luckd0g@163.com \
--cc=martin.petersen@oracle.com \
--cc=mrangankar@marvell.com \
--cc=njavali@marvell.com \
--cc=ranjan.kumar@broadcom.com \
--cc=sathya.prakash@broadcom.com \
--cc=shivasharan.srikanteshwara@broadcom.com \
--cc=sreekanth.reddy@broadcom.com \
--cc=suganath-prabu.subramani@broadcom.com \
--cc=sumit.saxena@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox