我有一個基於7000賽靈思ZYNQ板與在具有DMA能力的FPGA架構的外圍(上賽靈思/ ARM的SoC(ZYNQ 7000)DMA緩衝區AXI總線)。我們開發了一個電路並在ARM內核上運行Linux。硬件填充後,我們遇到性能問題,從用戶空間訪問DMA緩衝區。需要幫助映射預先保留** **緩存上
摘要:
在啓動時我們已預先保留DRAM的部分用作大DMA緩衝區。我們顯然使用錯誤的API來映射此緩衝區,因爲它看起來沒有緩存,並且訪問速度很糟糕。
使用它,甚至作爲一個反彈緩衝是慢難以維持,由於可怕的性能。 IIUC,ARM高速緩存不連貫的DMA,所以我會很感激關於如何做到以下一些見解:
- 地圖DRAM的一個區域到內核的虛擬地址空間,但確保它是緩存。
- 確保將它映射到用戶空間並不會產生不良影響,即使這需要我們通過我們自己的驅動程序提供mmap調用。
- 在執行DMA之前,從緩存層次結構中顯式地使物理內存區域無效,以確保一致性。
更多信息:
我一直在試圖詢問之前仔細研究這個。不幸的是,這是一個ARM SoC/FPGA,這方面的信息很少,所以我必須直接詢問專家。
因爲這是一個系統級芯片,很多東西是硬編碼的u-boot。例如,在將控制交給內核之前,內核和ramdisk被加載到DRAM中的特定位置。我們利用這個優勢爲DMA緩衝區預留了64MB的DRAM部分(它的確需要那麼大,這就是我們預先保留它的原因)。沒有任何擔心內存類型衝突或內核在內存中跺腳,因爲引導參數告訴內核哪個區域的DRAM可以控制。
最初,我們嘗試使用ioremap將此物理地址範圍映射到內核空間,但似乎標記區域不可緩存,並且訪問速度非常糟糕,即使我們試圖使用memcpy使其成爲反彈緩衝區。我們使用/ dev/mem將其映射到用戶空間中,並將memcpy的時間定義爲70MB/sec左右。
基於對這個主題的大量搜索,似乎有一半的人希望像這樣使用ioremap(這可能是我們從中得到的想法),ioremap不應該用於這個目的以及應該使用DMA相關的API來代替。不幸的是,似乎DMA緩衝區分配是完全動態的,我還沒有想出如何告訴它,「這是一個已經分配的物理地址 - 使用它。」我看着
一號文件是這一個,但它的方式太x86和PC爲中心的: https://www.kernel.org/doc/Documentation/DMA-API-HOWTO.txt
而且這個問題也是在我的搜索上面來了,但沒有真正的答案: get the physical address of a buffer under Linux
望着標準要求,dma_set_mask_and_coherent和家人不會採取預先定義的地址,並希望爲PCI設備結構。我沒有這樣的結構,因爲這是沒有PCI的ARM SoC。我可以手動填充這樣的結構,但是這對我來說就像濫用API一樣,而不是按照預期使用它。
BTW:這是一個環形緩衝區,我們DMA數據塊到不同的偏移,但我們對齊緩存行邊界,所以沒有虛假分擔風險。
非常感謝您爲您提供的任何幫助!
更新:看來,如果以正常方式進行操作,ARM上不存在可緩存的DMA緩衝區。也許如果我不進行ioremap調用,該區域不會被標記爲不可緩存,但是我必須弄清楚如何在ARM上進行緩存管理,這是我無法弄清楚的。其中一個問題是用戶空間中的memcpy顯得非常糟糕。是否有一個memcpy實現爲我可以使用的未緩存內存進行了優化?也許我可以寫一個。我必須弄清楚這個處理器是否有Neon。
您正在使用哪個版本的Linux內核?您是否嘗試過使用**連續內存分配器**?... – TheCodeArtist
@ TheCodeArtist「Linux(none)3.17.0-xilinx-dirty#13 SMP PREEMPT Mon Aug 3 12:10:57 MDT 2015 armv7l GNU/Linux」 另外,我沒有看過CMA。如果我能正確映射這個緩衝區,它不應該要求CMA,除非完全不可能從預保留的物理地址指定DMA緩衝區。 –
獲取Linux下的緩衝區的物理地址(這是來自用戶空間)http://stackoverflow.com/a/28987409/1163019。對於DMA/uncached東西afaik,老實說我不記得所有的細節,並且我沒有成功完成我的不同任務,但是我能從代碼中看到的是我正在嘗試「dma_alloc_coherent」 - >「update vma-> vm_page_prot作爲寫通過「 - > dma_mmap_from_coherent - > remap_pfn_range。也可能是這個演示文稿的幫助? http://events.linuxfoundation.org/sites/events/files/slides/20141015-dma.pdf – auselen