mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs
The driver, through the SAS transport, exposes a sysfs interface to enable/disable PHYs in a controller/expander setup. When multiple PHYs are disabled and enabled in rapid succession, the persistent and current config pages related to SAS IO unit/SAS Expander pages could get corrupted. Use separate memory for each config request. Signed-off-by: Prayas Patel <prayas.patel@broadcom.com> Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com> Link: https://lore.kernel.org/r/20241110194405.10108-3-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
367ac16e5f
commit
711201a8b8
@ -134,8 +134,6 @@ extern atomic64_t event_counter;
|
||||
|
||||
#define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */
|
||||
|
||||
#define MPI3MR_DEFAULT_CFG_PAGE_SZ 1024 /* in bytes */
|
||||
|
||||
#define MPI3MR_RESET_TOPOLOGY_SETTLE_TIME 10
|
||||
|
||||
#define MPI3MR_SCMD_TIMEOUT (60 * HZ)
|
||||
@ -1133,9 +1131,6 @@ struct scmd_priv {
|
||||
* @io_throttle_low: I/O size to stop throttle in 512b blocks
|
||||
* @num_io_throttle_group: Maximum number of throttle groups
|
||||
* @throttle_groups: Pointer to throttle group info structures
|
||||
* @cfg_page: Default memory for configuration pages
|
||||
* @cfg_page_dma: Configuration page DMA address
|
||||
* @cfg_page_sz: Default configuration page memory size
|
||||
* @sas_transport_enabled: SAS transport enabled or not
|
||||
* @scsi_device_channel: Channel ID for SCSI devices
|
||||
* @transport_cmds: Command tracker for SAS transport commands
|
||||
@ -1332,10 +1327,6 @@ struct mpi3mr_ioc {
|
||||
u16 num_io_throttle_group;
|
||||
struct mpi3mr_throttle_group_info *throttle_groups;
|
||||
|
||||
void *cfg_page;
|
||||
dma_addr_t cfg_page_dma;
|
||||
u16 cfg_page_sz;
|
||||
|
||||
u8 sas_transport_enabled;
|
||||
u8 scsi_device_channel;
|
||||
struct mpi3mr_drv_cmd transport_cmds;
|
||||
|
@ -4186,17 +4186,6 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc)
|
||||
mpi3mr_read_tsu_interval(mrioc);
|
||||
mpi3mr_print_ioc_info(mrioc);
|
||||
|
||||
if (!mrioc->cfg_page) {
|
||||
dprint_init(mrioc, "allocating config page buffers\n");
|
||||
mrioc->cfg_page_sz = MPI3MR_DEFAULT_CFG_PAGE_SZ;
|
||||
mrioc->cfg_page = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
mrioc->cfg_page_sz, &mrioc->cfg_page_dma, GFP_KERNEL);
|
||||
if (!mrioc->cfg_page) {
|
||||
retval = -1;
|
||||
goto out_failed_noretry;
|
||||
}
|
||||
}
|
||||
|
||||
dprint_init(mrioc, "allocating host diag buffers\n");
|
||||
mpi3mr_alloc_diag_bufs(mrioc);
|
||||
|
||||
@ -4768,11 +4757,7 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
|
||||
mrioc->admin_req_base, mrioc->admin_req_dma);
|
||||
mrioc->admin_req_base = NULL;
|
||||
}
|
||||
if (mrioc->cfg_page) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mrioc->cfg_page_sz,
|
||||
mrioc->cfg_page, mrioc->cfg_page_dma);
|
||||
mrioc->cfg_page = NULL;
|
||||
}
|
||||
|
||||
if (mrioc->pel_seqnum_virt) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mrioc->pel_seqnum_sz,
|
||||
mrioc->pel_seqnum_virt, mrioc->pel_seqnum_dma);
|
||||
@ -5392,55 +5377,6 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* mpi3mr_free_config_dma_memory - free memory for config page
|
||||
* @mrioc: Adapter instance reference
|
||||
* @mem_desc: memory descriptor structure
|
||||
*
|
||||
* Check whether the size of the buffer specified by the memory
|
||||
* descriptor is greater than the default page size if so then
|
||||
* free the memory pointed by the descriptor.
|
||||
*
|
||||
* Return: Nothing.
|
||||
*/
|
||||
static void mpi3mr_free_config_dma_memory(struct mpi3mr_ioc *mrioc,
|
||||
struct dma_memory_desc *mem_desc)
|
||||
{
|
||||
if ((mem_desc->size > mrioc->cfg_page_sz) && mem_desc->addr) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mem_desc->size,
|
||||
mem_desc->addr, mem_desc->dma_addr);
|
||||
mem_desc->addr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_alloc_config_dma_memory - Alloc memory for config page
|
||||
* @mrioc: Adapter instance reference
|
||||
* @mem_desc: Memory descriptor to hold dma memory info
|
||||
*
|
||||
* This function allocates new dmaable memory or provides the
|
||||
* default config page dmaable memory based on the memory size
|
||||
* described by the descriptor.
|
||||
*
|
||||
* Return: 0 on success, non-zero on failure.
|
||||
*/
|
||||
static int mpi3mr_alloc_config_dma_memory(struct mpi3mr_ioc *mrioc,
|
||||
struct dma_memory_desc *mem_desc)
|
||||
{
|
||||
if (mem_desc->size > mrioc->cfg_page_sz) {
|
||||
mem_desc->addr = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
mem_desc->size, &mem_desc->dma_addr, GFP_KERNEL);
|
||||
if (!mem_desc->addr)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
mem_desc->addr = mrioc->cfg_page;
|
||||
mem_desc->dma_addr = mrioc->cfg_page_dma;
|
||||
memset(mem_desc->addr, 0, mrioc->cfg_page_sz);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpi3mr_post_cfg_req - Issue config requests and wait
|
||||
* @mrioc: Adapter instance reference
|
||||
@ -5596,8 +5532,12 @@ static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc,
|
||||
cfg_req->page_length = cfg_hdr->page_length;
|
||||
cfg_req->page_version = cfg_hdr->page_version;
|
||||
}
|
||||
if (mpi3mr_alloc_config_dma_memory(mrioc, &mem_desc))
|
||||
goto out;
|
||||
|
||||
mem_desc.addr = dma_alloc_coherent(&mrioc->pdev->dev,
|
||||
mem_desc.size, &mem_desc.dma_addr, GFP_KERNEL);
|
||||
|
||||
if (!mem_desc.addr)
|
||||
return retval;
|
||||
|
||||
mpi3mr_add_sg_single(&cfg_req->sgl, sgl_flags, mem_desc.size,
|
||||
mem_desc.dma_addr);
|
||||
@ -5626,7 +5566,12 @@ static int mpi3mr_process_cfg_req(struct mpi3mr_ioc *mrioc,
|
||||
}
|
||||
|
||||
out:
|
||||
mpi3mr_free_config_dma_memory(mrioc, &mem_desc);
|
||||
if (mem_desc.addr) {
|
||||
dma_free_coherent(&mrioc->pdev->dev, mem_desc.size,
|
||||
mem_desc.addr, mem_desc.dma_addr);
|
||||
mem_desc.addr = NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user