scsi: pm80xx: Fix race condition caused by static variables

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>
This commit is contained in:
Francisco Gutierrez 2025-07-23 18:35:43 +00:00 committed by Martin K. Petersen
parent e5e11f666d
commit d6477ee38c
3 changed files with 17 additions and 10 deletions

View File

@ -534,23 +534,25 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev,
char *str = buf; char *str = buf;
u32 read_size = u32 read_size =
pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size / 1024; pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size / 1024;
static u32 start, end, count;
u32 max_read_times = 32; u32 max_read_times = 32;
u32 max_count = (read_size * 1024) / (max_read_times * 4); u32 max_count = (read_size * 1024) / (max_read_times * 4);
u32 *temp = (u32 *)pm8001_ha->memoryMap.region[IOP].virt_ptr; u32 *temp = (u32 *)pm8001_ha->memoryMap.region[IOP].virt_ptr;
if ((count % max_count) == 0) { mutex_lock(&pm8001_ha->iop_log_lock);
start = 0;
end = max_read_times; if ((pm8001_ha->iop_log_count % max_count) == 0) {
count = 0; pm8001_ha->iop_log_start = 0;
pm8001_ha->iop_log_end = max_read_times;
pm8001_ha->iop_log_count = 0;
} else { } else {
start = end; pm8001_ha->iop_log_start = pm8001_ha->iop_log_end;
end = end + max_read_times; pm8001_ha->iop_log_end = pm8001_ha->iop_log_end + max_read_times;
} }
for (; start < end; start++) for (; pm8001_ha->iop_log_start < pm8001_ha->iop_log_end; pm8001_ha->iop_log_start++)
str += sprintf(str, "%08x ", *(temp+start)); str += sprintf(str, "%08x ", *(temp+pm8001_ha->iop_log_start));
count++; pm8001_ha->iop_log_count++;
mutex_unlock(&pm8001_ha->iop_log_lock);
return str - buf; return str - buf;
} }
static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL); static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL);

View File

@ -552,6 +552,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
pm8001_ha->id = pm8001_id++; pm8001_ha->id = pm8001_id++;
pm8001_ha->logging_level = logging_level; pm8001_ha->logging_level = logging_level;
pm8001_ha->non_fatal_count = 0; pm8001_ha->non_fatal_count = 0;
mutex_init(&pm8001_ha->iop_log_lock);
if (link_rate >= 1 && link_rate <= 15) if (link_rate >= 1 && link_rate <= 15)
pm8001_ha->link_rate = (link_rate << 8); pm8001_ha->link_rate = (link_rate << 8);
else { else {

View File

@ -547,6 +547,10 @@ struct pm8001_hba_info {
u32 ci_offset; u32 ci_offset;
u32 pi_offset; u32 pi_offset;
u32 max_memcnt; u32 max_memcnt;
u32 iop_log_start;
u32 iop_log_end;
u32 iop_log_count;
struct mutex iop_log_lock;
}; };
struct pm8001_work { struct pm8001_work {