* [PATCH 1/7] mpt3sas: Handle PCIe sgl's in same 4G region.
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
@ 2021-03-05 10:28 ` Suganath Prabu S
2021-03-05 10:28 ` [PATCH 2/7] mpt3sas: Handle chain buffer DMA allocations " Suganath Prabu S
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:28 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 8622 bytes --]
According to MPI Specification PCIe SGL buffers should not cross
4GB boundary. So while allocating PCIe SGL buffers, if any buffer
crosses the 4GB boundary then,
* Release the already allocated memory pools and
* Reallocate them by changing the DMA coherent mask to 32 bit.
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 159 ++++++++++++++++++++--------
drivers/scsi/mpt3sas/mpt3sas_base.h | 1 +
2 files changed, 113 insertions(+), 47 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index ac066f8..f9e6f8e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -2905,23 +2905,22 @@ static int
_base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
{
struct sysinfo s;
- int dma_mask;
if (ioc->is_mcpu_endpoint ||
sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma ||
dma_get_required_mask(&pdev->dev) <= 32)
- dma_mask = 32;
+ ioc->dma_mask = 32;
/* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
else if (ioc->hba_mpi_version_belonged > MPI2_VERSION)
- dma_mask = 63;
+ ioc->dma_mask = 63;
else
- dma_mask = 64;
+ ioc->dma_mask = 64;
- if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(dma_mask)) ||
- dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(dma_mask)))
+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)) ||
+ dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)))
return -ENODEV;
- if (dma_mask > 32) {
+ if (ioc->dma_mask > 32) {
ioc->base_add_sg_single = &_base_add_sg_single_64;
ioc->sge_size = sizeof(Mpi2SGESimple64_t);
} else {
@@ -2931,7 +2930,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
si_meminfo(&s);
ioc_info(ioc, "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n",
- dma_mask, convert_to_kb(s.totalram));
+ ioc->dma_mask, convert_to_kb(s.totalram));
return 0;
}
@@ -5338,10 +5337,10 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc)
dma_pool_free(ioc->pcie_sgl_dma_pool,
ioc->pcie_sg_lookup[i].pcie_sgl,
ioc->pcie_sg_lookup[i].pcie_sgl_dma);
+ ioc->pcie_sg_lookup[i].pcie_sgl = NULL;
}
dma_pool_destroy(ioc->pcie_sgl_dma_pool);
}
-
if (ioc->config_page) {
dexitprintk(ioc,
ioc_info(ioc, "config_page(0x%p): free\n",
@@ -5399,6 +5398,89 @@ mpt3sas_check_same_4gb_region(long reply_pool_start_address, u32 pool_sz)
return 0;
}
+/**
+ * _base_reduce_hba_queue_depth- Retry with reduced queue depth
+ * @ioc: Adapter object
+ *
+ * Return: 0 for success, non-zero for failure.
+ **/
+static inline int
+_base_reduce_hba_queue_depth(struct MPT3SAS_ADAPTER *ioc)
+{
+ int reduce_sz = 64;
+
+ if ((ioc->hba_queue_depth - reduce_sz) >
+ (ioc->internal_depth + INTERNAL_SCSIIO_CMDS_COUNT)) {
+ ioc->hba_queue_depth -= reduce_sz;
+ return 0;
+ } else
+ return -ENOMEM;
+}
+
+/**
+ * _base_allocate_pcie_sgl_pool - Allocating DMA'able memory
+ * for pcie sgl pools.
+ * @ioc: Adapter object
+ * @sz: DMA Pool size
+ * @ct: Chain tracker
+ * Return: 0 for success, non-zero for failure.
+ */
+
+static int
+_base_allocate_pcie_sgl_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
+{
+ int i = 0, j = 0;
+ struct chain_tracker *ct;
+
+ ioc->pcie_sgl_dma_pool =
+ dma_pool_create("PCIe SGL pool", &ioc->pdev->dev, sz,
+ ioc->page_size, 0);
+ if (!ioc->pcie_sgl_dma_pool) {
+ ioc_err(ioc, "PCIe SGL pool: dma_pool_create failed\n");
+ return -ENOMEM;
+ }
+
+ ioc->chains_per_prp_buffer = sz/ioc->chain_segment_sz;
+ ioc->chains_per_prp_buffer =
+ min(ioc->chains_per_prp_buffer, ioc->chains_needed_per_io);
+ for (i = 0; i < ioc->scsiio_depth; i++) {
+ ioc->pcie_sg_lookup[i].pcie_sgl =
+ dma_pool_alloc(ioc->pcie_sgl_dma_pool, GFP_KERNEL,
+ &ioc->pcie_sg_lookup[i].pcie_sgl_dma);
+ if (!ioc->pcie_sg_lookup[i].pcie_sgl) {
+ ioc_err(ioc, "PCIe SGL pool: dma_pool_alloc failed\n");
+ return -EAGAIN;
+ }
+
+ if (!mpt3sas_check_same_4gb_region(
+ (long)ioc->pcie_sg_lookup[i].pcie_sgl, sz)) {
+ ioc_err(ioc, "PCIE SGLs are not in same 4G !! pcie sgl (0x%p) dma = (0x%llx)\n",
+ ioc->pcie_sg_lookup[i].pcie_sgl,
+ (unsigned long long)
+ ioc->pcie_sg_lookup[i].pcie_sgl_dma);
+ ioc->use_32bit_dma = true;
+ return -EAGAIN;
+ }
+
+ for (j = 0; j < ioc->chains_per_prp_buffer; j++) {
+ ct = &ioc->chain_lookup[i].chains_per_smid[j];
+ ct->chain_buffer =
+ ioc->pcie_sg_lookup[i].pcie_sgl +
+ (j * ioc->chain_segment_sz);
+ ct->chain_buffer_dma =
+ ioc->pcie_sg_lookup[i].pcie_sgl_dma +
+ (j * ioc->chain_segment_sz);
+ }
+ }
+ dinitprintk(ioc, ioc_info(ioc,
+ "PCIe sgl pool depth(%d), element_size(%d), pool_size(%d kB)\n",
+ ioc->scsiio_depth, sz, (sz * ioc->scsiio_depth)/1024));
+ dinitprintk(ioc, ioc_info(ioc,
+ "Number of chains can fit in a PRP page(%d)\n",
+ ioc->chains_per_prp_buffer));
+ return 0;
+}
+
/**
* base_alloc_rdpq_dma_pool - Allocating DMA'able memory
* for reply queues.
@@ -5497,7 +5579,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
unsigned short sg_tablesize;
u16 sge_size;
int i, j;
- int ret = 0;
+ int ret = 0, rc = 0;
struct chain_tracker *ct;
dinitprintk(ioc, ioc_info(ioc, "%s\n", __func__));
@@ -5802,6 +5884,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
* be required for NVMe PRP's, only each set of NVMe blocks will be
* contiguous, so a new set is allocated for each possible I/O.
*/
+
ioc->chains_per_prp_buffer = 0;
if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) {
nvme_blocks_needed =
@@ -5816,43 +5899,11 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
goto out;
}
sz = nvme_blocks_needed * ioc->page_size;
- ioc->pcie_sgl_dma_pool =
- dma_pool_create("PCIe SGL pool", &ioc->pdev->dev, sz, 16, 0);
- if (!ioc->pcie_sgl_dma_pool) {
- ioc_info(ioc, "PCIe SGL pool: dma_pool_create failed\n");
- goto out;
- }
-
- ioc->chains_per_prp_buffer = sz/ioc->chain_segment_sz;
- ioc->chains_per_prp_buffer = min(ioc->chains_per_prp_buffer,
- ioc->chains_needed_per_io);
-
- for (i = 0; i < ioc->scsiio_depth; i++) {
- ioc->pcie_sg_lookup[i].pcie_sgl = dma_pool_alloc(
- ioc->pcie_sgl_dma_pool, GFP_KERNEL,
- &ioc->pcie_sg_lookup[i].pcie_sgl_dma);
- if (!ioc->pcie_sg_lookup[i].pcie_sgl) {
- ioc_info(ioc, "PCIe SGL pool: dma_pool_alloc failed\n");
- goto out;
- }
- for (j = 0; j < ioc->chains_per_prp_buffer; j++) {
- ct = &ioc->chain_lookup[i].chains_per_smid[j];
- ct->chain_buffer =
- ioc->pcie_sg_lookup[i].pcie_sgl +
- (j * ioc->chain_segment_sz);
- ct->chain_buffer_dma =
- ioc->pcie_sg_lookup[i].pcie_sgl_dma +
- (j * ioc->chain_segment_sz);
- }
- }
-
- dinitprintk(ioc,
- ioc_info(ioc, "PCIe sgl pool depth(%d), element_size(%d), pool_size(%d kB)\n",
- ioc->scsiio_depth, sz,
- (sz * ioc->scsiio_depth) / 1024));
- dinitprintk(ioc,
- ioc_info(ioc, "Number of chains can fit in a PRP page(%d)\n",
- ioc->chains_per_prp_buffer));
+ rc = _base_allocate_pcie_sgl_pool(ioc, sz);
+ if (rc == -ENOMEM)
+ return -ENOMEM;
+ else if (rc == -EAGAIN)
+ goto try_32bit_dma;
total_sz += sz * ioc->scsiio_depth;
}
@@ -6022,6 +6073,19 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc->shost->sg_tablesize);
return 0;
+try_32bit_dma:
+ _base_release_memory_pools(ioc);
+ if (ioc->use_32bit_dma && (ioc->dma_mask > 32)) {
+ /* Change dma coherent mask to 32 bit and reallocate */
+ if (_base_config_dma_addressing(ioc, ioc->pdev) != 0) {
+ pr_err("Setting 32 bit coherent DMA mask Failed %s\n",
+ pci_name(ioc->pdev));
+ return -ENODEV;
+ }
+ } else if (_base_reduce_hba_queue_depth(ioc) != 0)
+ return -ENOMEM;
+ goto retry_allocation;
+
out:
return -ENOMEM;
}
@@ -7682,6 +7746,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
ioc->rdpq_array_enable_assigned = 0;
ioc->use_32bit_dma = false;
+ ioc->dma_mask = 64;
if (ioc->is_aero_ioc)
ioc->base_readl = &_base_readl_aero;
else
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 315aee6..b86eced 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1371,6 +1371,7 @@ struct MPT3SAS_ADAPTER {
u16 thresh_hold;
u8 high_iops_queues;
u32 drv_support_bitmap;
+ u32 dma_mask;
bool enable_sdev_max_qd;
bool use_32bit_dma;
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/7] mpt3sas: Handle chain buffer DMA allocations in same 4G region
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
2021-03-05 10:28 ` [PATCH 1/7] mpt3sas: Handle PCIe sgl's " Suganath Prabu S
@ 2021-03-05 10:28 ` Suganath Prabu S
2021-03-05 10:29 ` [PATCH 3/7] mpt3sas: Handle sense " Suganath Prabu S
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:28 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 4236 bytes --]
According to MPI Specification Chain buffers should not cross
4GB boundary. So while allocating Chain buffers, if any buffer
crosses the 4GB boundary then,
* Release the already allocated memory pools and
* Reallocate them by changing the DMA coherent mask to 32 bit.
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 83 ++++++++++++++++++++---------
1 file changed, 57 insertions(+), 26 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index f9e6f8e..7542f7a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5481,6 +5481,52 @@ _base_allocate_pcie_sgl_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
return 0;
}
+/**
+ * _base_allocate_chain_dma_pool - Allocating DMA'able memory
+ * for chain dma pool.
+ * @ioc: Adapter object
+ * @sz: DMA Pool size
+ * @ctr: Chain tracker
+ * Return: 0 for success, non-zero for failure.
+ */
+static int
+_base_allocate_chain_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
+{
+ int i = 0, j = 0;
+ struct chain_tracker *ctr;
+
+ ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev,
+ ioc->chain_segment_sz, 16, 0);
+ if (!ioc->chain_dma_pool)
+ return -ENOMEM;
+
+ for (i = 0; i < ioc->scsiio_depth; i++) {
+ for (j = ioc->chains_per_prp_buffer;
+ j < ioc->chains_needed_per_io; j++) {
+ ctr = &ioc->chain_lookup[i].chains_per_smid[j];
+ ctr->chain_buffer = dma_pool_alloc(ioc->chain_dma_pool,
+ GFP_KERNEL, &ctr->chain_buffer_dma);
+ if (!ctr->chain_buffer)
+ return -EAGAIN;
+ if (!mpt3sas_check_same_4gb_region((long)
+ ctr->chain_buffer, ioc->chain_segment_sz)) {
+ ioc_err(ioc,
+ "Chain buffers are not in same 4G !!! Chain buff (0x%p) dma = (0x%llx)\n",
+ ctr->chain_buffer,
+ (unsigned long long)ctr->chain_buffer_dma);
+ ioc->use_32bit_dma = true;
+ return -EAGAIN;
+ }
+ }
+ }
+ dinitprintk(ioc, ioc_info(ioc,
+ "chain_lookup depth (%d), frame_size(%d), pool_size(%d kB)\n",
+ ioc->scsiio_depth, ioc->chain_segment_sz, ((ioc->scsiio_depth *
+ (ioc->chains_needed_per_io - ioc->chains_per_prp_buffer) *
+ ioc->chain_segment_sz))/1024));
+ return 0;
+}
+
/**
* base_alloc_rdpq_dma_pool - Allocating DMA'able memory
* for reply queues.
@@ -5578,9 +5624,8 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
u16 max_request_credit, nvme_blocks_needed;
unsigned short sg_tablesize;
u16 sge_size;
- int i, j;
+ int i;
int ret = 0, rc = 0;
- struct chain_tracker *ct;
dinitprintk(ioc, ioc_info(ioc, "%s\n", __func__));
@@ -5907,31 +5952,17 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
total_sz += sz * ioc->scsiio_depth;
}
- ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev,
- ioc->chain_segment_sz, 16, 0);
- if (!ioc->chain_dma_pool) {
- ioc_err(ioc, "chain_dma_pool: dma_pool_create failed\n");
- goto out;
- }
- for (i = 0; i < ioc->scsiio_depth; i++) {
- for (j = ioc->chains_per_prp_buffer;
- j < ioc->chains_needed_per_io; j++) {
- ct = &ioc->chain_lookup[i].chains_per_smid[j];
- ct->chain_buffer = dma_pool_alloc(
- ioc->chain_dma_pool, GFP_KERNEL,
- &ct->chain_buffer_dma);
- if (!ct->chain_buffer) {
- ioc_err(ioc, "chain_lookup: pci_pool_alloc failed\n");
- goto out;
- }
- }
- total_sz += ioc->chain_segment_sz;
- }
-
+ rc = _base_allocate_chain_dma_pool(ioc, ioc->chain_segment_sz);
+ if (rc == -ENOMEM)
+ return -ENOMEM;
+ else if (rc == -EAGAIN)
+ goto try_32bit_dma;
+ total_sz += ioc->chain_segment_sz * ((ioc->chains_needed_per_io -
+ ioc->chains_per_prp_buffer) * ioc->scsiio_depth);
dinitprintk(ioc,
- ioc_info(ioc, "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
- ioc->chain_depth, ioc->chain_segment_sz,
- (ioc->chain_depth * ioc->chain_segment_sz) / 1024));
+ ioc_info(ioc, "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
+ ioc->chain_depth, ioc->chain_segment_sz,
+ (ioc->chain_depth * ioc->chain_segment_sz) / 1024));
/* sense buffers, 4 byte align */
sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE;
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/7] mpt3sas: Handle sense buffer DMA allocations in same 4G region
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
2021-03-05 10:28 ` [PATCH 1/7] mpt3sas: Handle PCIe sgl's " Suganath Prabu S
2021-03-05 10:28 ` [PATCH 2/7] mpt3sas: Handle chain buffer DMA allocations " Suganath Prabu S
@ 2021-03-05 10:29 ` Suganath Prabu S
2021-03-05 10:29 ` [PATCH 4/7] mpt3sas: Handle reply pool " Suganath Prabu S
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:29 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 4751 bytes --]
According to MPI Specification Sense buffers should not cross
4GB boundary. So while allocating Sense buffers, if any buffer
crosses the 4GB boundary then,
* Release the already allocated memory pools and
* Reallocate them by changing the DMA coherent mask to 32 bit.
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 86 ++++++++++++++---------------
1 file changed, 40 insertions(+), 46 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 7542f7a..6ef4925 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5527,6 +5527,38 @@ _base_allocate_chain_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
return 0;
}
+/**
+ * _base_allocate_sense_dma_pool - Allocating DMA'able memory
+ * for sense dma pool.
+ * @ioc: Adapter object
+ * @sz: DMA Pool size
+ * Return: 0 for success, non-zero for failure.
+ */
+static int
+_base_allocate_sense_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
+{
+ ioc->sense_dma_pool =
+ dma_pool_create("sense pool", &ioc->pdev->dev, sz, 4, 0);
+ if (!ioc->sense_dma_pool)
+ return -ENOMEM;
+ ioc->sense = dma_pool_alloc(ioc->sense_dma_pool,
+ GFP_KERNEL, &ioc->sense_dma);
+ if (!ioc->sense)
+ return -EAGAIN;
+ if (!mpt3sas_check_same_4gb_region((long)ioc->sense, sz)) {
+ dinitprintk(ioc, pr_err(
+ "Bad Sense Pool! sense (0x%p) sense_dma = (0x%llx)\n",
+ ioc->sense, (unsigned long long) ioc->sense_dma));
+ ioc->use_32bit_dma = true;
+ return -EAGAIN;
+ }
+ ioc_info(ioc,
+ "sense pool(0x%p) - dma(0x%llx): depth(%d), element_size(%d), pool_size (%d kB)\n",
+ ioc->sense, (unsigned long long)ioc->sense_dma,
+ ioc->scsiio_depth, SCSI_SENSE_BUFFERSIZE, sz/1024);
+ return 0;
+}
+
/**
* base_alloc_rdpq_dma_pool - Allocating DMA'able memory
* for reply queues.
@@ -5620,7 +5652,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
u16 chains_needed_per_io;
u32 sz, total_sz, reply_post_free_sz, reply_post_free_array_sz;
u32 retry_sz;
- u32 rdpq_sz = 0;
+ u32 rdpq_sz = 0, sense_sz = 0;
u16 max_request_credit, nvme_blocks_needed;
unsigned short sg_tablesize;
u16 sge_size;
@@ -5963,58 +5995,20 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
ioc_info(ioc, "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n",
ioc->chain_depth, ioc->chain_segment_sz,
(ioc->chain_depth * ioc->chain_segment_sz) / 1024));
-
/* sense buffers, 4 byte align */
- sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE;
- ioc->sense_dma_pool = dma_pool_create("sense pool", &ioc->pdev->dev, sz,
- 4, 0);
- if (!ioc->sense_dma_pool) {
- ioc_err(ioc, "sense pool: dma_pool_create failed\n");
- goto out;
- }
- ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL,
- &ioc->sense_dma);
- if (!ioc->sense) {
- ioc_err(ioc, "sense pool: dma_pool_alloc failed\n");
- goto out;
- }
- /* sense buffer requires to be in same 4 gb region.
- * Below function will check the same.
- * In case of failure, new pci pool will be created with updated
- * alignment. Older allocation and pool will be destroyed.
- * Alignment will be used such a way that next allocation if
- * success, will always meet same 4gb region requirement.
- * Actual requirement is not alignment, but we need start and end of
- * DMA address must have same upper 32 bit address.
- */
- if (!mpt3sas_check_same_4gb_region((long)ioc->sense, sz)) {
- //Release Sense pool & Reallocate
- dma_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma);
- dma_pool_destroy(ioc->sense_dma_pool);
- ioc->sense = NULL;
-
- ioc->sense_dma_pool =
- dma_pool_create("sense pool", &ioc->pdev->dev, sz,
- roundup_pow_of_two(sz), 0);
- if (!ioc->sense_dma_pool) {
- ioc_err(ioc, "sense pool: pci_pool_create failed\n");
- goto out;
- }
- ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL,
- &ioc->sense_dma);
- if (!ioc->sense) {
- ioc_err(ioc, "sense pool: pci_pool_alloc failed\n");
- goto out;
- }
- }
+ sense_sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE;
+ rc = _base_allocate_sense_dma_pool(ioc, sense_sz);
+ if (rc == -ENOMEM)
+ return -ENOMEM;
+ else if (rc == -EAGAIN)
+ goto try_32bit_dma;
+ total_sz += sense_sz;
ioc_info(ioc,
"sense pool(0x%p)- dma(0x%llx): depth(%d),"
"element_size(%d), pool_size(%d kB)\n",
ioc->sense, (unsigned long long)ioc->sense_dma, ioc->scsiio_depth,
SCSI_SENSE_BUFFERSIZE, sz / 1024);
- total_sz += sz;
-
/* reply pool, 4 byte align */
sz = ioc->reply_free_queue_depth * ioc->reply_sz;
ioc->reply_dma_pool = dma_pool_create("reply pool", &ioc->pdev->dev, sz,
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/7] mpt3sas: Handle reply pool DMA allocations in same 4G region
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
` (2 preceding siblings ...)
2021-03-05 10:29 ` [PATCH 3/7] mpt3sas: Handle sense " Suganath Prabu S
@ 2021-03-05 10:29 ` Suganath Prabu S
2021-03-05 10:29 ` [PATCH 5/7] mpt3sas: Handle Reply post queue " Suganath Prabu S
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:29 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 3488 bytes --]
According to MPI Specification Reply buffers should not cross
4GB boundary. So while allocating Reply buffers, if any buffer
crosses the 4GB boundary then,
* Release the already allocated memory pools and
* Reallocate them by changing the DMA coherent mask to 32 bit
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 63 ++++++++++++++++++-----------
1 file changed, 40 insertions(+), 23 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 6ef4925..e94abce 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5559,6 +5559,41 @@ _base_allocate_sense_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
return 0;
}
+/**
+ * _base_allocate_reply_pool - Allocating DMA'able memory
+ * for reply pool.
+ * @ioc: Adapter object
+ * @sz: DMA Pool size
+ * Return: 0 for success, non-zero for failure.
+ */
+static int
+_base_allocate_reply_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
+{
+ /* reply pool, 4 byte align */
+ ioc->reply_dma_pool = dma_pool_create("reply pool",
+ &ioc->pdev->dev, sz, 4, 0);
+ if (!ioc->reply_dma_pool)
+ return -ENOMEM;
+ ioc->reply = dma_pool_alloc(ioc->reply_dma_pool, GFP_KERNEL,
+ &ioc->reply_dma);
+ if (!ioc->reply)
+ return -EAGAIN;
+ if (!mpt3sas_check_same_4gb_region((long)ioc->reply_free, sz)) {
+ dinitprintk(ioc, pr_err(
+ "Bad Reply Pool! Reply (0x%p) Reply dma = (0x%llx)\n",
+ ioc->reply, (unsigned long long) ioc->reply_dma));
+ ioc->use_32bit_dma = true;
+ return -EAGAIN;
+ }
+ ioc->reply_dma_min_address = (u32)(ioc->reply_dma);
+ ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz;
+ ioc_info(ioc,
+ "reply pool(0x%p) - dma(0x%llx): depth(%d), frame_size(%d), pool_size(%d kB)\n",
+ ioc->reply, (unsigned long long)ioc->reply_dma,
+ ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024);
+ return 0;
+}
+
/**
* base_alloc_rdpq_dma_pool - Allocating DMA'able memory
* for reply queues.
@@ -6008,32 +6043,14 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
"element_size(%d), pool_size(%d kB)\n",
ioc->sense, (unsigned long long)ioc->sense_dma, ioc->scsiio_depth,
SCSI_SENSE_BUFFERSIZE, sz / 1024);
-
/* reply pool, 4 byte align */
sz = ioc->reply_free_queue_depth * ioc->reply_sz;
- ioc->reply_dma_pool = dma_pool_create("reply pool", &ioc->pdev->dev, sz,
- 4, 0);
- if (!ioc->reply_dma_pool) {
- ioc_err(ioc, "reply pool: dma_pool_create failed\n");
- goto out;
- }
- ioc->reply = dma_pool_alloc(ioc->reply_dma_pool, GFP_KERNEL,
- &ioc->reply_dma);
- if (!ioc->reply) {
- ioc_err(ioc, "reply pool: dma_pool_alloc failed\n");
- goto out;
- }
- ioc->reply_dma_min_address = (u32)(ioc->reply_dma);
- ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz;
- dinitprintk(ioc,
- ioc_info(ioc, "reply pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n",
- ioc->reply, ioc->reply_free_queue_depth,
- ioc->reply_sz, sz / 1024));
- dinitprintk(ioc,
- ioc_info(ioc, "reply_dma(0x%llx)\n",
- (unsigned long long)ioc->reply_dma));
+ rc = _base_allocate_reply_pool(ioc, sz);
+ if (rc == -ENOMEM)
+ return -ENOMEM;
+ else if (rc == -EAGAIN)
+ goto try_32bit_dma;
total_sz += sz;
-
/* reply free queue, 16 byte align */
sz = ioc->reply_free_queue_depth * 4;
ioc->reply_free_dma_pool = dma_pool_create("reply_free pool",
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/7] mpt3sas: Handle Reply post queue DMA allocations in same 4G region
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
` (3 preceding siblings ...)
2021-03-05 10:29 ` [PATCH 4/7] mpt3sas: Handle reply pool " Suganath Prabu S
@ 2021-03-05 10:29 ` Suganath Prabu S
2021-03-05 10:29 ` [PATCH 6/7] mpt3sas: Handle reply post array " Suganath Prabu S
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:29 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 3426 bytes --]
According to MPI Specification Reply Post buffers should not cross
4GB boundary. So while allocating Reply Post buffers, if any buffer
crosses the 4GB boundary then,
* Release the already allocated memory pools and
* Reallocate them by changing the DMA coherent mask to 32 bit.
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 59 ++++++++++++++++++++---------
1 file changed, 42 insertions(+), 17 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index e94abce..bd180db 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5594,6 +5594,42 @@ _base_allocate_reply_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
return 0;
}
+/**
+ * _base_allocate_reply_free_dma_pool - Allocating DMA'able memory
+ * for reply free dma pool.
+ * @ioc: Adapter object
+ * @sz: DMA Pool size
+ * Return: 0 for success, non-zero for failure.
+ */
+static int
+_base_allocate_reply_free_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
+{
+ /* reply free queue, 16 byte align */
+ ioc->reply_free_dma_pool = dma_pool_create(
+ "reply_free pool", &ioc->pdev->dev, sz, 16, 0);
+ if (!ioc->reply_free_dma_pool)
+ return -ENOMEM;
+ ioc->reply_free = dma_pool_alloc(ioc->reply_free_dma_pool,
+ GFP_KERNEL, &ioc->reply_free_dma);
+ if (!ioc->reply_free)
+ return -EAGAIN;
+ if (!mpt3sas_check_same_4gb_region((long)ioc->reply_free, sz)) {
+ dinitprintk(ioc,
+ pr_err("Bad Reply Free Pool! Reply Free (0x%p) Reply Free dma = (0x%llx)\n",
+ ioc->reply_free, (unsigned long long) ioc->reply_free_dma));
+ ioc->use_32bit_dma = true;
+ return -EAGAIN;
+ }
+ memset(ioc->reply_free, 0, sz);
+ dinitprintk(ioc, ioc_info(ioc,
+ "reply_free pool(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n",
+ ioc->reply_free, ioc->reply_free_queue_depth, 4, sz/1024));
+ dinitprintk(ioc, ioc_info(ioc,
+ "reply_free_dma (0x%llx)\n",
+ (unsigned long long)ioc->reply_free_dma));
+ return 0;
+}
+
/**
* base_alloc_rdpq_dma_pool - Allocating DMA'able memory
* for reply queues.
@@ -6051,29 +6087,18 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
else if (rc == -EAGAIN)
goto try_32bit_dma;
total_sz += sz;
+
/* reply free queue, 16 byte align */
sz = ioc->reply_free_queue_depth * 4;
- ioc->reply_free_dma_pool = dma_pool_create("reply_free pool",
- &ioc->pdev->dev, sz, 16, 0);
- if (!ioc->reply_free_dma_pool) {
- ioc_err(ioc, "reply_free pool: dma_pool_create failed\n");
- goto out;
- }
- ioc->reply_free = dma_pool_zalloc(ioc->reply_free_dma_pool, GFP_KERNEL,
- &ioc->reply_free_dma);
- if (!ioc->reply_free) {
- ioc_err(ioc, "reply_free pool: dma_pool_alloc failed\n");
- goto out;
- }
- dinitprintk(ioc,
- ioc_info(ioc, "reply_free pool(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n",
- ioc->reply_free, ioc->reply_free_queue_depth,
- 4, sz / 1024));
+ rc = _base_allocate_reply_free_dma_pool(ioc, sz);
+ if (rc == -ENOMEM)
+ return -ENOMEM;
+ else if (rc == -EAGAIN)
+ goto try_32bit_dma;
dinitprintk(ioc,
ioc_info(ioc, "reply_free_dma (0x%llx)\n",
(unsigned long long)ioc->reply_free_dma));
total_sz += sz;
-
if (ioc->rdpq_array_enable) {
reply_post_free_array_sz = ioc->reply_queue_count *
sizeof(Mpi2IOCInitRDPQArrayEntry);
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/7] mpt3sas: Handle reply post array DMA allocations in same 4G region
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
` (4 preceding siblings ...)
2021-03-05 10:29 ` [PATCH 5/7] mpt3sas: Handle Reply post queue " Suganath Prabu S
@ 2021-03-05 10:29 ` Suganath Prabu S
2021-03-05 10:29 ` [PATCH 7/7] mpt3sas : Update driver version to 37.101.00.00 Suganath Prabu S
2021-03-19 3:46 ` [PATCH 0/7] Handle DMA allocations in same 4G region Martin K. Petersen
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:29 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 3119 bytes --]
According to MPI Specification Reply post Array buffer should not cross
4GB boundary. So while allocating Reply Post Array buffer, if it
crosses the 4GB boundary then,
* Release the already allocated memory pools and
* Reallocate them by changing the DMA coherent mask to 32 bit.
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 55 ++++++++++++++++++++---------
1 file changed, 39 insertions(+), 16 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index bd180db..a74aab9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5630,6 +5630,39 @@ _base_allocate_reply_free_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz)
return 0;
}
+/**
+ * _base_allocate_reply_post_free_array - Allocating DMA'able memory
+ * for reply post free array.
+ * @ioc: Adapter object
+ * @reply_post_free_array_sz: DMA Pool size
+ * Return: 0 for success, non-zero for failure.
+ */
+
+static int
+_base_allocate_reply_post_free_array(struct MPT3SAS_ADAPTER *ioc,
+ u32 reply_post_free_array_sz)
+{
+ ioc->reply_post_free_array_dma_pool =
+ dma_pool_create("reply_post_free_array pool",
+ &ioc->pdev->dev, reply_post_free_array_sz, 16, 0);
+ if (!ioc->reply_post_free_array_dma_pool)
+ return -ENOMEM;
+ ioc->reply_post_free_array =
+ dma_pool_alloc(ioc->reply_post_free_array_dma_pool,
+ GFP_KERNEL, &ioc->reply_post_free_array_dma);
+ if (!ioc->reply_post_free_array)
+ return -EAGAIN;
+ if (!mpt3sas_check_same_4gb_region((long)ioc->reply_post_free_array,
+ reply_post_free_array_sz)) {
+ dinitprintk(ioc, pr_err(
+ "Bad Reply Free Pool! Reply Free (0x%p) Reply Free dma = (0x%llx)\n",
+ ioc->reply_free,
+ (unsigned long long) ioc->reply_free_dma));
+ ioc->use_32bit_dma = true;
+ return -EAGAIN;
+ }
+ return 0;
+}
/**
* base_alloc_rdpq_dma_pool - Allocating DMA'able memory
* for reply queues.
@@ -6102,22 +6135,12 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
if (ioc->rdpq_array_enable) {
reply_post_free_array_sz = ioc->reply_queue_count *
sizeof(Mpi2IOCInitRDPQArrayEntry);
- ioc->reply_post_free_array_dma_pool =
- dma_pool_create("reply_post_free_array pool",
- &ioc->pdev->dev, reply_post_free_array_sz, 16, 0);
- if (!ioc->reply_post_free_array_dma_pool) {
- dinitprintk(ioc,
- ioc_info(ioc, "reply_post_free_array pool: dma_pool_create failed\n"));
- goto out;
- }
- ioc->reply_post_free_array =
- dma_pool_alloc(ioc->reply_post_free_array_dma_pool,
- GFP_KERNEL, &ioc->reply_post_free_array_dma);
- if (!ioc->reply_post_free_array) {
- dinitprintk(ioc,
- ioc_info(ioc, "reply_post_free_array pool: dma_pool_alloc failed\n"));
- goto out;
- }
+ rc = _base_allocate_reply_post_free_array(ioc,
+ reply_post_free_array_sz);
+ if (rc == -ENOMEM)
+ return -ENOMEM;
+ else if (rc == -EAGAIN)
+ goto try_32bit_dma;
}
ioc->config_page_sz = 512;
ioc->config_page = dma_alloc_coherent(&ioc->pdev->dev,
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/7] mpt3sas : Update driver version to 37.101.00.00
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
` (5 preceding siblings ...)
2021-03-05 10:29 ` [PATCH 6/7] mpt3sas: Handle reply post array " Suganath Prabu S
@ 2021-03-05 10:29 ` Suganath Prabu S
2021-03-19 3:46 ` [PATCH 0/7] Handle DMA allocations in same 4G region Martin K. Petersen
7 siblings, 0 replies; 9+ messages in thread
From: Suganath Prabu S @ 2021-03-05 10:29 UTC (permalink / raw)
To: linux-scsi, martin.petersen
Cc: Sathya.Prakash, sreekanth.reddy, Suganath Prabu S
[-- Attachment #1: Type: text/plain, Size: 906 bytes --]
Update driver version to 37.101.00.00
Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
---
drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index b86eced..98558d9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -77,9 +77,9 @@
#define MPT3SAS_DRIVER_NAME "mpt3sas"
#define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "37.100.00.00"
+#define MPT3SAS_DRIVER_VERSION "37.101.00.00"
#define MPT3SAS_MAJOR_VERSION 37
-#define MPT3SAS_MINOR_VERSION 100
+#define MPT3SAS_MINOR_VERSION 101
#define MPT3SAS_BUILD_VERSION 0
#define MPT3SAS_RELEASE_VERSION 00
--
2.27.0
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4245 bytes --]
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/7] Handle DMA allocations in same 4G region.
2021-03-05 10:28 [PATCH 0/7] Handle DMA allocations in same 4G region Suganath Prabu S
` (6 preceding siblings ...)
2021-03-05 10:29 ` [PATCH 7/7] mpt3sas : Update driver version to 37.101.00.00 Suganath Prabu S
@ 2021-03-19 3:46 ` Martin K. Petersen
7 siblings, 0 replies; 9+ messages in thread
From: Martin K. Petersen @ 2021-03-19 3:46 UTC (permalink / raw)
To: linux-scsi, Suganath Prabu S
Cc: Martin K . Petersen, Sathya.Prakash, sreekanth.reddy
On Fri, 5 Mar 2021 15:58:57 +0530, Suganath Prabu S wrote:
> According to MPI Specification PCIe SGL, Sense pool, Chain pool,
> reply pool, reply post pool & reply post array buffers should not cross
> 4GB boundary. So while allocating these buffers, if any of these
> pool buffer crosses the 4GB boundary then,
> * Release the already allocated memory pools and
> * Reallocate them by changing the DMA coherent mask to 32 bit.
>
> [...]
Applied to 5.13/scsi-queue, thanks!
[1/7] mpt3sas: Handle PCIe sgl's in same 4G region.
https://git.kernel.org/mkp/scsi/c/d6adc251dd2f
[2/7] mpt3sas: Handle chain buffer DMA allocations in same 4G region
https://git.kernel.org/mkp/scsi/c/7dd847dae1c4
[3/7] mpt3sas: Handle sense buffer DMA allocations in same 4G region
https://git.kernel.org/mkp/scsi/c/970ac2bb70e7
[4/7] mpt3sas: Handle reply pool DMA allocations in same 4G region
https://git.kernel.org/mkp/scsi/c/58501fd9375f
[5/7] mpt3sas: Handle Reply post queue DMA allocations in same 4G region
https://git.kernel.org/mkp/scsi/c/2e4e8587327b
[6/7] mpt3sas: Handle reply post array DMA allocations in same 4G region
https://git.kernel.org/mkp/scsi/c/c569de899bb4
[7/7] mpt3sas : Update driver version to 37.101.00.00
https://git.kernel.org/mkp/scsi/c/37067b979309
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 9+ messages in thread