summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorFrancisco Gutierrez <frankramirez@google.com>2025-07-23 18:35:43 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-11-24 10:29:30 +0100
commit22c24c7c5e81c373e87d87268870b9f55ea697b8 (patch)
treeb490b088770940df5027b2a02df2acfa512bc0ab /drivers/scsi
parentbbfe60eba369186914262225e46fb92738e99069 (diff)
downloadlinux-22c24c7c5e81c373e87d87268870b9f55ea697b8.tar.gz
linux-22c24c7c5e81c373e87d87268870b9f55ea697b8.tar.bz2
linux-22c24c7c5e81c373e87d87268870b9f55ea697b8.zip
scsi: pm80xx: Fix race condition caused by static variables
[ Upstream commit d6477ee38ccfbeaed885733c13f41d9076e2f94a ] Eliminate the use of static variables within the log pull implementation to resolve a race condition and prevent data gaps when pulling logs from multiple controllers in parallel, ensuring each operation is properly isolated. Signed-off-by: Francisco Gutierrez <frankramirez@google.com> Link: https://lore.kernel.org/r/20250723183543.1443301-1-frankramirez@google.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/pm8001/pm8001_ctl.c22
-rw-r--r--drivers/scsi/pm8001/pm8001_init.c1
-rw-r--r--drivers/scsi/pm8001/pm8001_sas.h4
3 files changed, 17 insertions, 10 deletions
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 5c26a13ffbd2..20c4e10f7bb5 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -534,23 +534,25 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev,
char *str = buf;
u32 read_size =
pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size / 1024;
- static u32 start, end, count;
u32 max_read_times = 32;
u32 max_count = (read_size * 1024) / (max_read_times * 4);
u32 *temp = (u32 *)pm8001_ha->memoryMap.region[IOP].virt_ptr;
- if ((count % max_count) == 0) {
- start = 0;
- end = max_read_times;
- count = 0;
+ mutex_lock(&pm8001_ha->iop_log_lock);
+
+ if ((pm8001_ha->iop_log_count % max_count) == 0) {
+ pm8001_ha->iop_log_start = 0;
+ pm8001_ha->iop_log_end = max_read_times;
+ pm8001_ha->iop_log_count = 0;
} else {
- start = end;
- end = end + max_read_times;
+ pm8001_ha->iop_log_start = pm8001_ha->iop_log_end;
+ pm8001_ha->iop_log_end = pm8001_ha->iop_log_end + max_read_times;
}
- for (; start < end; start++)
- str += sprintf(str, "%08x ", *(temp+start));
- count++;
+ for (; pm8001_ha->iop_log_start < pm8001_ha->iop_log_end; pm8001_ha->iop_log_start++)
+ str += sprintf(str, "%08x ", *(temp+pm8001_ha->iop_log_start));
+ pm8001_ha->iop_log_count++;
+ mutex_unlock(&pm8001_ha->iop_log_lock);
return str - buf;
}
static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL);
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index c2f6151cbd2d..00664bd2caab 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -529,6 +529,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
pm8001_ha->id = pm8001_id++;
pm8001_ha->logging_level = logging_level;
pm8001_ha->non_fatal_count = 0;
+ mutex_init(&pm8001_ha->iop_log_lock);
if (link_rate >= 1 && link_rate <= 15)
pm8001_ha->link_rate = (link_rate << 8);
else {
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 2fadd353f1c1..72cd1523235c 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -543,6 +543,10 @@ struct pm8001_hba_info {
u32 ci_offset;
u32 pi_offset;
u32 max_memcnt;
+ u32 iop_log_start;
+ u32 iop_log_end;
+ u32 iop_log_count;
+ struct mutex iop_log_lock;
};
struct pm8001_work {