Cache一致性問題,主要是指由於某些操作導致Cache和內存(如DDR)之間的數據不一致,且我們無法正確取到最新的數據。
正常情況下,Cache控制器有一套完善協議去保證我們對內存讀寫操作的正確性。但在某些復雜場景下,會發生cache一致性問題,此問題常發生在多核之間或使用DMA進行數據搬運前后。
本文主要討論DMA搬運數據前后的cache一致性問題。考慮如下場景:
1)讀0x80000000地址的數據
2)經過一系列操作后,我們通過DMA將結果拷貝到0x80000000地址所在的內存
3)讀上一步中的結果
分析:
第1步,讀操作會將內存中數據先加載到對應的cache(cache-line)中(cache操作都是以cache-line為最小單元進行操作的,常見的大小為64bytes),假設此時此地址的數據為0xFF,即cache中數據為0xFF;
第2步,DMA對地址0x80000000寫數據,由於DMA操作都是直接對物理內存進行操作的,即跳過cache,直接將內存中數據改寫,假設為0x55。那么此時便產生了cache一致性問題(cache中數據和內存中數據不一致,且cache並未更新數據狀態(dirty))。
第3步,我們在代碼中去訪問此地址,由於cache狀態未更新(cache控制器以為cache中數據是最新數據),從而讀到錯誤數據。
解決:
一般的,在遇到這種情況的時候,需要對cache進行flush或者invalidate操作。
通常可以在DMA寫數據之前進行flush或者DMA寫數據之后invalidate,具體需要看當時的實際情況。但需要特別注意cache的invalidate操作,有較大風險引起“把有效數據無效掉”的問題。
備注:了解cache機制,推薦閱讀下一章“Cache的幾種讀寫機制”。