dma記憶體一致性

2021-10-20 10:01:18 字數 2813 閱讀 2193

核心的dma一般在平台初始化的時候已經分配好了。但是對於一些有內部dma的硬體ip,比如usb ip、video加速ip,他們可能由ip廠商封裝好的,沒辦法繫結到cpu端,這時候在核心使用dma就要注意了,因為dma只認識實體地址哦。

當然,辦法還是有的,look:

以下來自:

這兩天在做 dma 相關開發, 遇到一對分配 dma buffer 的函式,dma_alloc_coherent 與 dma_alloc_writecombine。 不知其區別。 google 一下也沒有得到資訊。只好自己看**。

原來 dma_alloc_coherent 在 arm 平台上會禁止頁表項中的 c (cacheable) 域以及 b (bufferable)域。

而 dma_alloc_writecombine 只禁止 c (cacheable) 域.

#define pgprot_noncached(prot)  __pgprot(pgprot_val(prot) & ~(l_pte_cacheable | l_pte_bufferable))

#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~l_pte_cacheable)

進一步查詢 arm 書籍, 原來 c 代表是否使用高速緩衝儲存器, 而 w 代表是否使用寫緩衝區。

這樣, dma_alloc_writecombine  分配出來的記憶體不使用快取,但是會使用寫緩衝區。

而 dma_alloc_coherent 則二者都不適用。

由此,再去理解ldd3上講解的一致性dma對映 與流式dma 對映就比較容易了,一致性dma對映(dma_alloc_coherent )呼叫的是上面的函式,由於關閉了cache/buffer,效能自然比較低。 而流式則通過複雜的同步機制,沒有付出效能的代價。

所以我們要盡量使用流式dma來程式設計。

再去看看mmc驅動裡使用的分散/聚集對映,原來也是一種流式dma對映。

【補充】

講了那麼多沒用,總結下用法:

1、頁對齊記憶體大小:dma_map_size = page_align(my_data_size + page_size);

my_data_size是你想分配的大小.

2、呼叫

a =dma_alloc_writecombine(b,c,d,gfp_kernel);

含義:a: 記憶體的虛擬起始位址,在核心要用此位址來操作所分配的記憶體

b: struct device指標,可以平台初始化裡指定,主要是dma_mask之類,可參考framebuffer

c: 實際分配大小,傳入dma_map_size即可

d: 返回的記憶體實體地址,dma就可以用。

所以,a和d是一一對應的,只不過,a是虛擬位址,而d是實體地址。對任意乙個操作都將改變緩衝區內容。當然要注意操作環境。

核心的dma一般在平台初始化的時候已經分配好了。但是對於一些有內部dma的硬體ip,比如usb ip、video加速ip,他們可能由ip廠商封裝好的,沒辦法繫結到cpu端,這時候在核心使用dma就要注意了,因為dma只認識實體地址哦。

當然,辦法還是有的,look:

以下來自:

這兩天在做 dma 相關開發, 遇到一對分配 dma buffer 的函式,dma_alloc_coherent 與 dma_alloc_writecombine。 不知其區別。 google 一下也沒有得到資訊。只好自己看**。

原來 dma_alloc_coherent 在 arm 平台上會禁止頁表項中的 c (cacheable) 域以及 b (bufferable)域。

而 dma_alloc_writecombine 只禁止 c (cacheable) 域.

#define pgprot_noncached(prot)  __pgprot(pgprot_val(prot) & ~(l_pte_cacheable | l_pte_bufferable))

#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~l_pte_cacheable)

進一步查詢 arm 書籍, 原來 c 代表是否使用高速緩衝儲存器, 而 w 代表是否使用寫緩衝區。

這樣, dma_alloc_writecombine  分配出來的記憶體不使用快取,但是會使用寫緩衝區。

而 dma_alloc_coherent 則二者都不適用。

由此,再去理解ldd3上講解的一致性dma對映 與流式dma 對映就比較容易了,一致性dma對映(dma_alloc_coherent )呼叫的是上面的函式,由於關閉了cache/buffer,效能自然比較低。 而流式則通過複雜的同步機制,沒有付出效能的代價。

所以我們要盡量使用流式dma來程式設計。

再去看看mmc驅動裡使用的分散/聚集對映,原來也是一種流式dma對映。

【補充】

講了那麼多沒用,總結下用法:

1、頁對齊記憶體大小:dma_map_size = page_align(my_data_size + page_size);

my_data_size是你想分配的大小.

2、呼叫

a =dma_alloc_writecombine(b,c,d,gfp_kernel);

含義:a: 記憶體的虛擬起始位址,在核心要用此位址來操作所分配的記憶體

b: struct device指標,可以平台初始化裡指定,主要是dma_mask之類,可參考framebuffer

c: 實際分配大小,傳入dma_map_size即可

d: 返回的記憶體實體地址,dma就可以用。

所以,a和d是一一對應的,只不過,a是虛擬位址,而d是實體地址。對任意乙個操作都將改變緩衝區內容。當然要注意操作環境。

Linux記憶體管理 DMA和一致性快取

cpu寫記憶體的時候有兩種方式 1.write through cpu直接寫記憶體,不經過cache。2.write back cpu只寫到cache中。cache的硬體使用lru演算法將cache裡面的內容替換到記憶體。通常是這種方式。dma可以完成從記憶體到外設直接進行資料搬移。但dma不能訪問...

強一致性 弱一致性 最終一致性

這種方式在es等分布式系統中也有體現,可以設定主shard提交即返回成功,或者需要replica shard提交成功再返回。提到分布式架構就一定繞不開 一致性 問題,而 一致性 其實又包含了資料一致性和事務一致性兩種情況,本文主要討論資料一致性 事務一致性指acid 複製是導致出現資料一致性問題的唯...

記憶體一致性模型

cache coherence 本文主要討論的是記憶體一致性問題 memory consistency 和快取一致性 cache coherence 是不同的。在 計算機體系結構 量化方法研究 第五章中,memory consistency是由cache coherence引出的,所以我們就先來說說...