Re: dma_alloc_coherent

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

 





On Wed, Oct 12, 2011 at 11:47 PM, bob jonny <ilikepie420@xxxxxxxx> wrote:
In dma_alloc_coherent(), where is it allocating memory from, and how does it know that that memory is cache coherent? Does every device have it's cache coherent memory? I got lost at function pointer struct dma_map_ops ops, is there an easy way to figure out what ops->alloc_coherent() points to?

_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

Hi Bob,

dma_alloc_coherent() invokes the alloc_coherent method for the particular device which is the first parameter.

So to see from where the memory is getting allocated, you need to see that device's dma_map_op's alloc_coherent method.

I went through some of them, they tend to alloc memory by calling either __get_free_pages() or alloc_pages() functions.

To maintain cache coherency, the pages which are allocated in these functions have to be uncached and if they where cached earlier then they have to be flushed.

Following function explains all these : -

void *dma_generic_alloc_coherent(struct device *dev, size_t size,
                                 dma_addr_t *dma_handle, gfp_t gfp)
{
        void *ret, *ret_nocache;
        int order = get_order(size);

        gfp |= __GFP_ZERO;

        ret = (void *)__get_free_pages(gfp, order);
        if (!ret)
                return NULL;

        /*
         * Pages from the page allocator may have data present in
         * cache. So flush the cache before using uncached memory.
         */
        dma_cache_sync(dev, ret, size, DMA_BIDIRECTIONAL);

        ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size);
        if (!ret_nocache) {                 
                free_pages((unsigned long)ret, order);
                return NULL;
        }      

        split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);

        *dma_handle = virt_to_phys(ret);

        return ret_nocache;
}

Regards,
Rohan Puri
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux