我正在尝试通过FPGA板中的DMA内核在Linux用户空间中分配一块内存块。
到目前为止,我在用户空间应用程序中使用 posix_memalign()分配内存,然后将其指针传递给我的内核驱动程序。
在我的内核驱动程序中,我使用 get_user_pages()来获取用户空间内存中的页面列表。 下面的代码表示我创建分散/收集列表的后续步骤:
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]);
}
获得分散/收集列表后,我将其提供给DMA。
为了测试它是否正常运行,我将数据从用户空间应用程序写入我的用户空间分配的内存。 然后我强制DMA在相同的分配内存中写入不同的数据,但应用程序继续读取与DMA传输之前相同的数据。
我理解,假设DMA传输成功,是应用程序将数据写入缓存。 当回读数据时,它会不断地从缓存中读取数据,因此,它不知道DMA在我分配的内存块中写入的数据。
我相信,如果我是正确的,我将面临缓存一致性问题。
我的建议是我应该清除写入数据的缓存范围,然后使相同范围的缓存无效。
我尝试了多个功能,例如 flush_cache_range(), flush_cache_all(), cleancache_invalidate_page()和 dma_sync_sg_for_cpu
不幸的是,他们都没有像我预期的那样工作。
有什么建议可以解决我的问题吗?
是否有任何内存分配器功能(在用户空间中),例如 posix_memalign() 和malloc()是不可缓存的?
这可能不是缓存一致性问题吗?
到目前为止,我已经搜索了很多,但我不清楚我可能做错了什么。
提前谢谢!