Re: cma_remap when using dma_alloc_attr :- DMA_ATTR_NO_KERNEL_MAPPING

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

 



On 12/07/2019 19:30, Pankaj Suryawanshi wrote:
Hello,

When we allocate cma memory using dma_alloc_attr using
DMA_ATTR_NO_KERNEL_MAPPING attribute. It will return physical address
without virtual mapping and thats the use case of this attribute. but lets
say some vpu/gpu drivers required virtual mapping of some part of the
allocation. then we dont have anything to remap that allocated memory to
virtual memory. and in 32-bit system it difficult for devices like android
to work all the time with virtual mapping, it degrade the performance.

For Example :

Lets say 4k video allocation required 300MB cma memory but not required
virtual mapping for all the 300MB, its require only 20MB virtually mapped
at some specific use case/point of video, and unmap virtual mapping after
uses, at that time this functions will be useful, it works like ioremap()
for cma_alloc() using dma apis.

Hmm, is there any significant reason that this case couldn't be handled with just get_vm_area() plus dma_mmap_attrs(). I know it's only *intended* for userspace mappings, but since the basic machinery is there...

Robin.

/*
          * function call(s) to create virtual map of given physical memory
          * range [base, base+size) of CMA memory.
*/
void *cma_remap(__u32 base, __u32 size)
{
         struct page *page = phys_to_page(base);
         void *virt;

         pr_debug("cma: request to map 0x%08x for size 0x%08x\n",
                         base, size);

         size = PAGE_ALIGN(size);

         pgprot_t prot = get_dma_pgprot(DMA_ATTR, PAGE_KERNEL);

         if (PageHighMem(page)){
                 virt = dma_alloc_remap(page, size, GFP_KERNEL, prot,
__builtin_return_address(0));
         }
         else
         {
                 dma_remap(page, size, prot);
                 virt = page_address(page);
         }

         if (!virt)
                 pr_err("\x1b[31m" " cma: failed to map 0x%08x" "\x1b[0m\n",
                                 base);
         else
                 pr_debug("cma: 0x%08x is virtually mapped to 0x%08x\n",
                                 base, (__u32) virt);

         return virt;
}

/*
          * function call(s) to remove virtual map of given virtual memory
          * range [virt, virt+size) of CMA memory.
*/

void cma_unmap(void *virt, __u32 size)
{
         size = PAGE_ALIGN(size);
         unsigned long pfn = virt_to_pfn(virt);
         struct page *page = pfn_to_page(pfn);

                 if (PageHighMem(page))
                         dma_free_remap(virt, size);
                 else
                         dma_remap(page, size, PAGE_KERNEL);

         pr_debug(" cma: virtual address 0x%08x is unmapped\n",
                         (__u32) virt);
}

This functions should be added in arch/arm/mm/dma-mapping.c file.

Please let me know if i am missing anything.

Regards,
Pankaj





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux