From 4c461ee2b2a5a7c327fe092b41de1fcc002adc01 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 7 Aug 2026 15:49:50 -0700 Subject: scsi: core: Protect host state changes with the host lock Some but not all SCSI host state changes are protected with the SCSI host lock. Annotate the SCSI host state with __guarded_by(host_lock) and protect all SCSI host state changes with the SCSI host lock. This patch prevents that KCSAN complains about data races when accessing the SCSI host state. Reported-by: Jianzhou Zhao Closes: https://lore.kernel.org/all/36d59d0e.6db0.19cdbeee01b.Coremail.luckd0g@163.com/ Signed-off-by: Bart Van Assche Reviewed-by: John Garry Link: https://patch.msgid.link/681e4a5260c182feb5fc1d96f0d43c62c21dc6c9.1786142946.git.bvanassche@acm.org Signed-off-by: Martin K. Petersen (Oracle) --- include/scsi/scsi_host.h | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 7e2011830ba4..c9754771bf29 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -2,6 +2,7 @@ #ifndef _SCSI_SCSI_HOST_H #define _SCSI_SCSI_HOST_H +#include #include #include #include @@ -727,7 +728,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; @@ -785,11 +786,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; } @@ -835,8 +843,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 *); @@ -940,6 +949,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 */ -- cgit v1.2.3