Re: [PATCH] mpt3sas: don't change the dma coherent mask after allocations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jan 17, 2020 at 7:15 PM Christoph Hellwig <hch@xxxxxx> wrote:
>
> The DMA layer does not allow changing the DMA coherent mask after
> there are outstanding allocations.  Stop doing that and always
> use a 32-bit coherent DMA mask in mpt3sas.

Our HBA hardware has a requirement that each set of RDPQ reply
descriptor pools should be within the 4gb region. so to accommodate
this requirement driver is first setting the DMA coherent mask to 32
bit then allocating the RDPQ pools and then resetting the DMA coherent
make to 64 and allocating the remaining pools.

if we completely set the DMA coherent mask to 32 bit then there are
chances that sometimes driver may not get requested memory within the
first 4gb region and HBA initialization may fail. So instead of
setting the DMA coherent mask to 32 bit, we follow the same below
logic which megaraid_sas driver is doing now. i.e we first allocate
set of rdpq pools at once and check this allocated block is within the
4gb region, if not then free this block and allocate a new block from
aligned pci pool.

                 /* reply desc pool requires to be in same 4 gb region.
                 * Below function will check this.
                 * In case of failure, new pci pool will be created with updated
                 * alignment.
                 * For RDPQ buffers, driver always allocate two
separate pci pool.
                 * Alignment will be used such a way that next allocation if
                 * success, will always meet same 4gb region requirement.
                 * rdpq_tracker keep track of each buffer's physical,
                 * virtual address and pci pool descriptor. It will help driver
                 * while freeing the resources.
                 *
                 */
                if (!megasas_check_same_4gb_region(instance, rdpq_chunk_phys[i],
                                                   chunk_size)) {
                        dma_pool_free(fusion->reply_frames_desc_pool,
                                      rdpq_chunk_virt[i],
                                      rdpq_chunk_phys[i]);

                        rdpq_chunk_virt[i] =

dma_pool_alloc(fusion->reply_frames_desc_pool_align,
                                               GFP_KERNEL, &rdpq_chunk_phys[i]);
                        if (!rdpq_chunk_virt[i]) {
                                dev_err(&instance->pdev->dev,
                                        "Failed from %s %d\n",
                                        __func__, __LINE__);
                                return -ENOMEM;
                        }
                        fusion->rdpq_tracker[i].dma_pool_ptr =
                                        fusion->reply_frames_desc_pool_align;
                } else {
                        fusion->rdpq_tracker[i].dma_pool_ptr =
                                        fusion->reply_frames_desc_pool;
                }

Next week I will post the patch with above logic implemented in mpt3sas driver.

Regards,
Sreekanth


>
> Reported-by: Abdul Haleem <abdhalee@xxxxxxxxxxxxxxxxxx>
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> Tested-by: Abdul Haleem <abdhalee@xxxxxxxxxxxxxxxxxx>
> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.c | 67 ++++++++---------------------
>  drivers/scsi/mpt3sas/mpt3sas_base.h |  2 -
>  2 files changed, 19 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
> index fea3cb6a090b..3b51bed05008 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_base.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
> @@ -2706,58 +2706,38 @@ _base_build_sg_ieee(struct MPT3SAS_ADAPTER *ioc, void *psge,
>  static int
>  _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
>  {
> -       u64 required_mask, coherent_mask;
>         struct sysinfo s;
> -       /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
> -       int dma_mask = (ioc->hba_mpi_version_belonged > MPI2_VERSION) ? 63 : 64;
> -
> -       if (ioc->is_mcpu_endpoint)
> -               goto try_32bit;
> +       int dma_mask;
>
> -       required_mask = dma_get_required_mask(&pdev->dev);
> -       if (sizeof(dma_addr_t) == 4 || required_mask == 32)
> -               goto try_32bit;
> -
> -       if (ioc->dma_mask)
> -               coherent_mask = DMA_BIT_MASK(dma_mask);
> +       if (ioc->is_mcpu_endpoint ||
> +           sizeof(dma_addr_t) == 4 ||
> +           dma_get_required_mask(&pdev->dev) <= 32)
> +               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;
>         else
> -               coherent_mask = DMA_BIT_MASK(32);
> +               dma_mask = 64;
>
>         if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(dma_mask)) ||
> -           dma_set_coherent_mask(&pdev->dev, coherent_mask))
> -               goto try_32bit;
> -
> -       ioc->base_add_sg_single = &_base_add_sg_single_64;
> -       ioc->sge_size = sizeof(Mpi2SGESimple64_t);
> -       ioc->dma_mask = dma_mask;
> -       goto out;
> -
> - try_32bit:
> -       if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
> +           dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)))
>                 return -ENODEV;
>
> -       ioc->base_add_sg_single = &_base_add_sg_single_32;
> -       ioc->sge_size = sizeof(Mpi2SGESimple32_t);
> -       ioc->dma_mask = 32;
> - out:
> +       if (dma_mask > 32) {
> +               ioc->base_add_sg_single = &_base_add_sg_single_64;
> +               ioc->sge_size = sizeof(Mpi2SGESimple64_t);
> +       } else {
> +               ioc->base_add_sg_single = &_base_add_sg_single_32;
> +               ioc->sge_size = sizeof(Mpi2SGESimple32_t);
> +       }
> +
>         si_meminfo(&s);
>         ioc_info(ioc, "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n",
> -                ioc->dma_mask, convert_to_kb(s.totalram));
> +                dma_mask, convert_to_kb(s.totalram));
>
>         return 0;
>  }
>
> -static int
> -_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc,
> -                                     struct pci_dev *pdev)
> -{
> -       if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(ioc->dma_mask))) {
> -               if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
> -                       return -ENODEV;
> -       }
> -       return 0;
> -}
> -
>  /**
>   * _base_check_enable_msix - checks MSIX capabable.
>   * @ioc: per adapter object
> @@ -5030,14 +5010,6 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
>                 total_sz += sz;
>         } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count));
>
> -       if (ioc->dma_mask > 32) {
> -               if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) {
> -                       ioc_warn(ioc, "no suitable consistent DMA mask for %s\n",
> -                                pci_name(ioc->pdev));
> -                       goto out;
> -               }
> -       }
> -
>         ioc->scsiio_depth = ioc->hba_queue_depth -
>             ioc->hi_priority_depth - ioc->internal_depth;
>
> @@ -6965,7 +6937,6 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
>         ioc->smp_affinity_enable = smp_affinity_enable;
>
>         ioc->rdpq_array_enable_assigned = 0;
> -       ioc->dma_mask = 0;
>         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 faca0a5e71f8..e57cade1155c 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_base.h
> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
> @@ -1011,7 +1011,6 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc);
>   * @ir_firmware: IR firmware present
>   * @bars: bitmask of BAR's that must be configured
>   * @mask_interrupts: ignore interrupt
> - * @dma_mask: used to set the consistent dma mask
>   * @pci_access_mutex: Mutex to synchronize ioctl, sysfs show path and
>   *                     pci resource handling
>   * @fault_reset_work_q_name: fw fault work queue
> @@ -1185,7 +1184,6 @@ struct MPT3SAS_ADAPTER {
>         u8              ir_firmware;
>         int             bars;
>         u8              mask_interrupts;
> -       int             dma_mask;
>
>         /* fw fault handler */
>         char            fault_reset_work_q_name[20];
> --
> 2.24.1
>



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux