Cache coherency issues when accessing user space memory from DMA

I am trying to make a block of memory allocated in Linux user space available via PCIe by the DMA core in an FPGA board.

What I have been doing so far is allocating memory using posix_memalign () in a user-space application and then passing a pointer to my kernel driver.

In my kernel driver, I use get_user_pages () to get a list of pages from user space memory. The code below presents the following steps I follow to create a scatter / collect list:

merged_entries = get_user_pages(current, current->mm, (unsigned long)buffer, entries, 1, 1, page_array, vma_array /*NULL*/);


if(merged_entries)
{

    for(repeat = 0; repeat < merged_entries; repeat++)
    {
        (u32 *)kmap(page_array[repeat]);
    }       

    sg_init_table(scatter_list_array, merged_entries);

    for(repeat = 0; repeat < merged_entries; repeat++)
    {
        sg_set_page(&scatter_list_array[repeat], page_array[repeat], 4096, 0);

    }

    dma_buffers = pci_map_sg(dev, scatter_list_array, merged_entries, PCI_DMA_BIDIRECTIONAL);


    for(repeat = 0; repeat < dma_buffers; repeat++)
    {
        dma_address_array[repeat] = sg_dma_address(&scatter_list_array[repeat]);
        dma_buffers_length_array[repeat] = sg_dma_len(&scatter_list_array[repeat]);

    }

      

As soon as I get the scatter / collect list, I give it to the DMA.

To test if it works properly, I write data from a user-space application to my allocated memory. I then force the DMA to write different data to the same allocated memory, but the application continues to read the same data as before the DMA transfer.

What I understand, assuming the DMA transfer is successful, is that the application is writing data to the cache. When it comes to reading data, it continues reading from the cache, so it is not known for the data that is being written by DMA in the allocated block of memory.

I believe that if I am correct, I am facing a cache consistency issue.

I was suggested that I should clear the cache range where the data is written and then invalidate the same cache range.

I've tried several functions like flush_cache_range () , flush_cache_all () , cleancache_invalidate_page () and dma_sync_sg_for_cpu .

Unfortunately none of them worked as I expected.

Are there any suggestions to solve my problem?

Is there any memory allocation function (in user space) like posix_memalign () and malloc () that is not available?

Could this be a cache consistency issue?

I've searched a lot so far, but I'm not very clear on what I might be doing wrong.

Thank you in advance!

+3


source to share





All Articles