]> www.infradead.org Git - users/hch/misc.git/commitdiff
scsi: pm80xx: Fix race condition caused by static variables
authorFrancisco Gutierrez <frankramirez@google.com>
Wed, 23 Jul 2025 18:35:43 +0000 (18:35 +0000)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 26 Aug 2025 02:20:07 +0000 (22:20 -0400)
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>
drivers/scsi/pm8001/pm8001_ctl.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/pm8001/pm8001_sas.h

index 7618f9cc9986daaf636709c4f5e722a2486489f7..0c96875cf8fd1799397d2e12c538222d52c36f69 100644 (file)
@@ -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);
index 599410bcdfea59aba40e3dd6749434b7b5966d48..8ff4b89ff81e25387eca3767c7352dbaac4a5663 100644 (file)
@@ -552,6 +552,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 {
index 91b2cdf3535cdd6ad176925710f8df8bbda6cfb0..b63b6ffcaaf5bef1edea8a8da9813ed7adb864dd 100644 (file)
@@ -547,6 +547,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 {