核心中與驅動相關的記憶體操作之十 記憶體屏障

2021-06-20 09:45:29 字數 1473 閱讀 6232

雖然實際驅動中不常用

,但是閱讀核心比較深層的**經常會遇到

.為什麼存在記憶體屏障呢

?先看一下下面的場景:

編譯器和處理器為了提高效率

,可能對讀和寫操作重新進行了排序,例如

: 在某些處理器上

,以下**:

a = 1;

b = 2;

有可能在

a中存放新值之前就在

b中存放新值.

但是,我們在操作記憶體或者和硬體互動時

,常常需要確保乙個給定的順序

.所有可能重新排序和寫的處理器提供了機器指令來確保順序要求

,同樣也可以提示編譯器不要對給定點周圍的指令序列進行重新排序

.這些確保順序的指令叫做"屏障

". 記憶體屏障的存在意義就是為了解決編譯器和處理器對**的順序訪問問題.

核心中用於記憶體屏障的

api有

:

rmb():
提供"讀

"記憶體屏障

,確保跨越

rmb()

的載入動作不會發生重排序

.就是說

,rmb()

之前的載入操作不會被重新排在

rmb()

之後去;

wmb():
方法提供了"寫

"記憶體屏障

,功能和

rmb()

函式類似

.區別僅僅是針對儲存而非載入

--確保跨越屏障的儲存不發生排序

;

mb():
提供了讀屏障也提供了寫屏障

.相當於上述

rmb()

函式和wmb()

函式的功能和

.

read_barrier_depends():

rmb()

的變種,

可以理解成

rmb()

一種優化

.該屏障確保屏障前的讀操作在屏障後的讀操作之前完成

,即那些相互依賴的讀操作.例項

:下面這個例項,其中

a的初始值是

1,b的初始值是

2.

執行緒1         執行緒2

a = 3; -

mb(); -

b = 4; c = b;

- rmb();

- d = a;

如果不使用記憶體屏障

,c可能接受了

b的新值,而

d接收了

a原來的值

.c可能等於

4(我們期望的),而

d可能等於

1(不是我們期望的

).因此

,針對一些有順序要求的暫存器操作的話

,記憶體屏障是必須考慮的

.

核心中與驅動相關的記憶體操作之十一 IO記憶體

裝置通常會提供一組暫存器用於控制裝置 讀定裝置和獲取裝置狀態 即控制暫存器 資料暫存器和狀態暫存器 這些暫存器可能位於 i o空間 也可能位於記憶體空間 當位於 i o空間時 通常被稱為 i o埠 位於記憶體空間時 對應的記憶體空間被稱為 i o記憶體 在嵌入式 linux中,我們接觸最多的就是 i...

核心中與驅動相關的記憶體操作之八 面向頁的記憶體分配

1.概述 當我們在核心驅動 中需要用到大量記憶體時,一般建議採用面向頁的記憶體管理.面向頁的記憶體管理有如下優點 高效利用記憶體,避免記憶體碎片的產生.因為核心都是基於頁為基本單位去管理記憶體的.面向頁的記憶體管理,顧名思義,就是以頁為基本單位來操作記憶體的.它比kmalloc 對記憶體使用上效率會...

Linux核心裝置驅動之核心中煉表的使用筆記整理

核心中煉表的應用 1 介紹 在linux核心中使用了大量的鍊錶結構來組織資料,包括裝置列表以及各種功能模組中的資料組織。這些鍊錶大多採用在include linux list.h實現的乙個相當精彩的鍊錶資料結構。鍊錶資料結構的定義很簡單 struct list head list head結構包含兩...