scsi: core: Fix the unit attention counter implementation

scsi_decide_disposition() may call scsi_check_sense().
scsi_decide_disposition() calls are not serialized. Hence, counter
updates by scsi_check_sense() must be serialized. Hence this patch that
makes the counters updated by scsi_check_sense() atomic.

Cc: Kai Mäkisara <Kai.Makisara@kolumbus.fi>
Fixes: a5d518cd4e ("scsi: core: Add counters for New Media and Power On/Reset UNIT ATTENTIONs")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
Link: https://patch.msgid.link/20251014220244.3689508-1-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Bart Van Assche
2025-10-14 15:02:43 -07:00
committed by Martin K. Petersen
parent 35bc3c8ee3
commit d54c676d4f
2 changed files with 6 additions and 8 deletions

View File

@@ -554,9 +554,9 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd)
* happened, even if someone else gets the sense data. * happened, even if someone else gets the sense data.
*/ */
if (sshdr.asc == 0x28) if (sshdr.asc == 0x28)
scmd->device->ua_new_media_ctr++; atomic_inc(&sdev->ua_new_media_ctr);
else if (sshdr.asc == 0x29) else if (sshdr.asc == 0x29)
scmd->device->ua_por_ctr++; atomic_inc(&sdev->ua_por_ctr);
} }
if (scsi_sense_is_deferred(&sshdr)) if (scsi_sense_is_deferred(&sshdr))

View File

@@ -252,8 +252,8 @@ struct scsi_device {
unsigned int queue_stopped; /* request queue is quiesced */ unsigned int queue_stopped; /* request queue is quiesced */
bool offline_already; /* Device offline message logged */ bool offline_already; /* Device offline message logged */
unsigned int ua_new_media_ctr; /* Counter for New Media UNIT ATTENTIONs */ atomic_t ua_new_media_ctr; /* Counter for New Media UNIT ATTENTIONs */
unsigned int ua_por_ctr; /* Counter for Power On / Reset UAs */ atomic_t ua_por_ctr; /* Counter for Power On / Reset UAs */
atomic_t disk_events_disable_depth; /* disable depth for disk events */ atomic_t disk_events_disable_depth; /* disable depth for disk events */
@@ -693,10 +693,8 @@ static inline int scsi_device_busy(struct scsi_device *sdev)
} }
/* Macros to access the UNIT ATTENTION counters */ /* Macros to access the UNIT ATTENTION counters */
#define scsi_get_ua_new_media_ctr(sdev) \ #define scsi_get_ua_new_media_ctr(sdev) atomic_read(&sdev->ua_new_media_ctr)
((const unsigned int)(sdev->ua_new_media_ctr)) #define scsi_get_ua_por_ctr(sdev) atomic_read(&sdev->ua_por_ctr)
#define scsi_get_ua_por_ctr(sdev) \
((const unsigned int)(sdev->ua_por_ctr))
#define MODULE_ALIAS_SCSI_DEVICE(type) \ #define MODULE_ALIAS_SCSI_DEVICE(type) \
MODULE_ALIAS("scsi:t-" __stringify(type) "*") MODULE_ALIAS("scsi:t-" __stringify(type) "*")