2014-02-24 252 views
4

我正在爲SPI連接的LCD寫幀緩衝驅動程序。我使用kmalloc分配緩衝區,這是相當大的 - 150KB。考慮到kmalloc分配緩衝區的方式,ksize報告說,更多的內存正在被使用 - 大約256KB左右。kmalloc中的緩衝區是否也是DMA安全緩衝區?

SPI spi_transfer結構需要指向tx和rx緩衝區的指針,它們都必須是DMA安全的。因爲我希望tx緩衝區大約爲16KB,我可以在kmalloced視頻緩衝區內分配緩衝區,並仍然是DMA安全的嗎?

這可能被認爲是不成熟的優化,但視頻緩衝區中有太多的空閒空間,所以感覺不好不要使用它!本質上存在之間分配的內存沒有任何區別:

kmalloc(videosize) 

kmalloc(PAGE_ALIGN(videosize) + txbufsize) 

這樣一個可以採取kptr返回,並做到:

txbuf = (u8 *)kptr + PAGE_ALIGN(videosize); 

我知道的那部分「DMA安全」的要求是適當的對齊 - CPU緩存線的大小,我相信... - 但不應該頁面對齊爲這個好嗎?

順便說一句,我不確定tx和rx是否可以指向相同的地方。 spi.h標題也不清楚(實際上明確不清楚)。由於rx緩衝區永遠不會超過幾個字節,因此試圖找出問題將會很麻煩!

+0

也許嘗試構建你的代碼直接寫入到內存DMA'ble,而不是一個kmalloc的緩衝? – tangrs

+0

你爲什麼使用'kmalloc'作爲視頻緩衝區? –

+0

與__get_free_pages相反?應該沒有什麼區別......他們都是DMA安全的。我可以半回答我自己的問題 - 如果我對齊一個頁面,我相信會排除任何緩存一致性問題的可能性,即使它是過度殺毒,也不會查看TLB的東西。 – carveone

回答

2

答案似乎是與provisos是。 (具體而言,「它比這更復雜」)

如果通過__get_free_page *()或通用內存分配器(kmalloc)獲取內存,則可以使用從這些例程返回的地址來DMA /從該內存DMA。其基本含義是,kmalloc中的頁面對齊緩衝區,甚至跨越多個頁面,將是DMA安全的,因爲底層物理內存保證是連續的,並且頁面對齊緩衝區保證位於緩存線邊界。

一個附帶條件是設備是否能夠驅動全部總線寬度(例如:ISA)。因此,內存的物理地址必須位於設備的dma_mask內。

另一個是緩存一致性要求。這些以緩存行寬的粒度進行操作。爲了防止兩個獨立的內存區域共享一個高速緩存行,dma內存必須準確地從高速緩存行邊界開始,並完全在一個邊界上結束。鑑於這可能是未知的,建議(DMA API文檔)僅映射以頁面邊界開始和結束的虛擬區域(因爲這些也保證如上所述是緩存行邊界)。

在這種情況下,DMA驅動程序可以使用dma_alloc_coherent()分配DMA可用空間,以確保DMA區域不可緩存。由於這可能是昂貴的,所以還存在流式方法 - 用於單向通信 - 其中一致性限於寫入時緩存刷新。在先前分配的緩衝區上使用dma_map_single()。

在我的情況下,將tx和rx緩衝區傳遞給沒有dma_map_single的spi_sync很好 - spi例程會爲我做到這一點。我可以將dma_map_single與unmap或dma_sync_single_for_cpu()一起使所有內容保持同步。我現在不打擾 - 性能調整司機的作品是一個更好的策略。

參見: