diff options
| author | Bart Van Assche <bvanassche@acm.org> | 2026-08-07 15:49:50 -0700 |
|---|---|---|
| committer | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-08-13 22:04:50 -0400 |
| commit | 4c461ee2b2a5a7c327fe092b41de1fcc002adc01 (patch) | |
| tree | d4e4a1664e6c59e611901096be163e3a70ce8443 /include | |
| parent | 09982efcc07e739c7e4ac6089e3e521132388b53 (diff) | |
| download | linux-4c461ee2b2a5a7c327fe092b41de1fcc002adc01.tar.gz linux-4c461ee2b2a5a7c327fe092b41de1fcc002adc01.zip | |
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 <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>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://patch.msgid.link/681e4a5260c182feb5fc1d96f0d43c62c21dc6c9.1786142946.git.bvanassche@acm.org
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/scsi/scsi_host.h | 24 |
1 files changed, 17 insertions, 7 deletions
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 <linux/cleanup.h> #include <linux/device.h> #include <linux/list.h> #include <linux/types.h> @@ -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 */ |
