考虑这个同时DMA到用户存储器
线程1在用户程序:
buf = malloc(9000);
memset(buf, 0xee, 9000);
read(buf, 9000); //for example gives pages [part of 7, 8, 9, part of 10]
线程2在用户程序:
buf = malloc(9000); //for example gives pages [part of 4, 6, 5, part of 7]
memset(buf, 0xee, 9000);
read(buf, 9000);
驱动读:
get_user_pages();
//build dma sg list from pages
//...
//the platform demands a cachesync
for(all pages) {
dma_cache_wback_inv();
}
//start dma and wait for it to be done
//...
wait_event_interruptible_timeout(); //blocks calling thread until dma done
for(all pages) {
if(read) SetPageDirty();
page_cache_release();
}
请注意,第7页由两者使用转移,这是一个很大的问题,有时会导致错误的数据(0xee在一个buf的末尾被发现)。为了清楚起见,这两个读取运行在不同的DMA通道上,因此它们可以同时运行。
我的解决方案是页面对齐用户程序中的缓冲区,以便2驱动程序DMA永远不会共享相同页面的部分。
我想知道是否还有其他解决方案? 我也想知道为什么这是一个大问题。
这可能是相当具体的平台 - 缓存失效的要求表明你正在嵌入式系统上运行。两个缓冲区足够接近以共享缓存线,还是在平台勘误中还存在其他限制? – 2012-03-02 09:49:44
是的,这是一个ppc440ep,并且缓冲区可能足够接近。缓存行是32个字节,我只看到4-12个字节被破坏/不变。缓存中是否存在2个不同版本的相同物理内存?当我在一个线程中执行wback时,它是否可以销毁另一个线程的数据?据我所知没有任何错误。但是get_user_pages呢?当它返回2个不同版本的同一页面时会发生什么?如果来自不同线程的get_user_pages和page_cache_release变为交织。 – Ronnie 2012-03-02 10:43:39
我不完全清楚get_user_pages/page_cache_release是干什么的,除非给予页面的物理地址。在这个系统上没有光盘缓存或任何东西,只有内存和cpu-cache。 – Ronnie 2012-03-02 10:50:58