考慮這個同時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