Linux快取記憶體詳解(二)

2021-06-11 20:54:49 字數 3080 閱讀 6664

[快取記憶體的寫操作]

對快取記憶體的寫操作,主要來自於其它函式對快取記憶體的使用。寫操作的使用方式很多,例如在inode.c的write_node函式。write_node函式在呼叫是需要傳遞乙個指向inode節點的指標,並且設定好這個i節點的對應的裝置號和節點號。write_node函式的作用是將乙個i節點的資訊寫入裝置中(其實是寫入快取記憶體中)。這裡摘抄部分與快取記憶體相關的部分 if

(!(sb=get_super(inode->i_dev)))

panic(

"trying to write inode without device"

);block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +

(inode->i_num-1)/inodes_per_block;

if(!(bh=bread(inode->i_dev,block)))

panic(

"unable to read i-node block"

);/*前面部分是得到了i節點所在邏輯塊的快取記憶體,bh指向這個快取記憶體頭*/

((struct

d_inode *)bh->b_data)

[(inode->i_num-1)%inodes_per_block] =

*(struct

d_inode *)inode;

bh->b_dirt=1;

inode->i_dirt=0;

brelse(bh);

對快取記憶體進行寫操作的部分為

((struct

d_inode *)bh->b_data)

[(inode->i_num-1)%inodes_per_block] =

*(

struct

d_inode *)inode;

由於之前讀入快取記憶體的資料是i節點所在的邏輯塊的整塊資料,而這個邏輯塊是由許多的裝置i節點組成的。因此可以將這個邏輯塊的資料看成裝置上i節點的陣列。所以(struct d_inode*)bd->b_data,將快取資料塊當作裝置i節點陣列來了解。inode->i_num%inodes_per_block,根據i節點號計算這個i節點在裝置i節點陣列上的索引。最後

((struct

d_inode *)bh->b_data)

[(inode->i_num-1)%inodes_per_block] =*( 

struct

d_inode *)inode;將i節點資料寫入了快取中。在對快取寫操作結束之後,bh->b_dirt=1設定快取資訊,表明快取中資料被修改,其它程序如果需要使用這個快取,就需要先把資料同步到裝置中。brelse(bh)在快取使用結束後釋放快取,在後面將會介紹這個函式的**實現。

[快取記憶體的管理函式]

快取記憶體的管理包括快取記憶體佇列的管理,即在前面getblk中看到的

insert_into_queues和remove_from_queues;釋放乙個快取記憶體塊函式brelse函式;指定某裝置對應的快取記憶體失效的invalidate_buffers函式;將高速快取資料與裝置同步的sync_dev函式。其它與快取記憶體相關的操作函式這裡就不多做說明了。

insert_into_queues是將快取塊插入到佇列中,將快取塊插入到空閒鍊錶的尾部。根據快取塊中是否設定了裝置號來決定是否要將其插入到雜湊表中。**如下

static

inline

void

insert_into_queues(

struct

buffer_head * bh)

remove_from_queues是將快取塊從鍊錶中移除去。同時從空閒鍊錶和雜湊陣列的鍊錶中移走。**如下

static

inline

void

remove_from_queues(

struct

buffer_head * bh)

brelse釋放程序使用的乙個快取塊,主要工作是將這個快取塊的應用數減一,注意這裡只是將應用次數減一,並沒***釋放後將這個快取塊變為空閒的。然後喚醒等待在快取上的程序。**如下

void

brelse(

struct

buffer_head * buf)

喚醒等待程序函式wake_up在sched.c中定義,呼叫這個函式需要傳遞乙個執行程序的指標的位址,這個函式很短。只是將程序的狀態變為可執行的,然後將指標置為空。**如下

void

wake_up(

struct

task_struct **p) //p是指向程序的指標的位址

}

在brelse中呼叫wake_up之後的效果是buffer_wait指向的程序的狀態變為可執行,然後buffer_wait=null

invalidate_buffers有個裝置號的引數,invalidate_buffers的作用是將指定裝置號上的快取變成無效狀態。**如下

void

inline

invalidate_buffers(

intdev)

}

sync_dev函式需要有個引數指定要同步的裝置號,它的作用是將快取記憶體中的資料同步到裝置中去。所有與此裝置相關的快取記憶體的資料都要同步。**如下

int sync_dev(

intdev)

sync_inodes(); //同步快取中的i節點資訊,將i節點資料寫入裝置

bh = start_buffer;

/*

再次同步一次,同步i節點時可能影響快取中資料。

*/

for(i=0 ; i

if(bh->b_dev != dev)

continue

;wait_on_buffer(bh);

if(bh->b_dev == dev && bh->b_dirt)

ll_rw_block(write,bh);

}

return

0;}

sys_sync函式與sync_dev功能相近,只不過sys_sync是將所有的快取資料都進行同步。而不像sync_dev那樣,只針對某乙個裝置的快取塊進行操作

頁快取記憶體 二

五 把塊放在頁快取記憶體中 在舊的linux核心版本中,有兩種不同的磁碟快取記憶體,分別是頁快取記憶體和緩衝區快取記憶體,前者用來存放訪問磁碟檔案內容時生成的磁碟資料頁,後者把通過vfs訪問的塊的內容保留在記憶體中。從2.4.10版本開始,緩衝區快取記憶體不存在了,把它們存放在叫做 緩衝區頁 的專門...

Linux快取記憶體概述

資料緩衝區快取記憶體 核心通過儲存乙個稱為資料緩衝區快取記憶體的內部資料緩衝區池來試圖減小對磁碟的訪問頻率。高速緩衝含有最近被使用過的磁碟塊的資料 在linux核心0.11中,它預設最多支援16m的物理記憶體。對系統記憶體的分配情況如下 linux核心占用物理記憶體最前段的一部分。隨後是高速緩衝區,...

Linux的快取記憶體 Cache Memory詳解

ps 前天有童鞋問我,為啥我的linux系統沒執行多少程式,顯示的可用記憶體這麼少?其實linux與win的記憶體管理不同,會盡量快取記憶體以提高讀寫效能,通常叫做cache memory。有時候你會發現沒有什麼程式在執行,但是使用top或free命令看到可用記憶體free項會很少,此時檢視系統的 ...