日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux系统页面缓存,Linux缓存机制之页缓存

發布時間:2023/12/20 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux系统页面缓存,Linux缓存机制之页缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內核采用一種通用的地址空間方案,來建立緩存數據與其來源之間的關聯。

1)? 內存中的頁分配到每個地址空間。這些頁的內容可以由用戶進程或內核本身使用各式各樣的方法操作。這些數據表示了緩存中的內容;

2)? 后備存儲器struct backing_dev_info指定了填充地址空間中頁的數據的來源。地址空間關聯到處理器的虛擬地址空間,是由處理器在虛擬內存中管理的一個區域到設備device上對應位置之間的一個映射。

如果訪問了虛擬內存中的某個位置,該位置沒有關聯到物理內存頁,內核可根據地址空間結構來找到讀取數據的來源。

為支持數據傳輸,每個地址空間都提供了一組操作,以容許地址空間所涉及雙方面的交互。

地址空間是內核中最關鍵的數據結構之一,對該數據結構的管理,已經演變為內核面對的最關鍵的問題之一。 頁緩存的任務在于,獲得一些物理內存頁,以加速在塊設備上按頁為單位執行的操作。

內核使用了基數樹來管理與一個地址空間相關的所有頁,以便盡可能降低開銷。對于基數樹的理解在這里就不分析了,后面有空的時候再做分析。

地址空間操作

[cpp]

structaddress_space_operations?{

/*將地址空間的一頁或多頁寫回到底層設備

這是通過向塊層發出一個相應的請求來完成的*/

int(*writepage)(structpage?*page,structwriteback_control?*wbc);

/*從后備存儲器將一頁或多個連續的頁讀入頁幀*/

int(*readpage)(structfile?*,structpage?*);

/*對尚未回寫到后備存儲器的數據進行同步*/

void(*sync_page)(structpage?*);

/*?Write?back?some?dirty?pages?from?this?mapping.?*/

int(*writepages)(structaddress_space?*,structwriteback_control?*);

/*?Set?a?page?dirty.??Return?true?if?this?dirtied?it?*/

int(*set_page_dirty)(structpage?*page);

int(*readpages)(structfile?*filp,structaddress_space?*mapping,

structlist_head?*pages,?unsigned?nr_pages);

/*執行由write系統調用觸發的寫操作*/

int(*write_begin)(structfile?*,structaddress_space?*mapping,

loff_t?pos,?unsigned?len,?unsigned?flags,

structpage?**pagep,void**fsdata);

int(*write_end)(structfile?*,structaddress_space?*mapping,

loff_t?pos,?unsigned?len,?unsigned?copied,

structpage?*page,void*fsdata);

/*?Unfortunately?this?kludge?is?needed?for?FIBMAP.?Don't?use?it?*/

sector_t?(*bmap)(structaddress_space?*,?sector_t);

void(*invalidatepage)?(structpage?*,?unsignedlong);

int(*releasepage)?(structpage?*,?gfp_t);

ssize_t?(*direct_IO)(int,structkiocb?*,conststructiovec?*iov,

loff_t?offset,?unsignedlongnr_segs);

int(*get_xip_mem)(structaddress_space?*,?pgoff_t,int,

void**,?unsignedlong*);

/*?migrate?the?contents?of?a?page?to?the?specified?target?*/

int(*migratepage)?(structaddress_space?*,

structpage?*,structpage?*);

int(*launder_page)?(structpage?*);

int(*is_partially_uptodate)?(structpage?*,?read_descriptor_t?*,

unsignedlong);

int(*error_remove_page)(structaddress_space?*,structpage?*);

};

頁面緩存的實現基于基數樹,緩存屬于內核中性能要求最苛刻的部分之一,而且廣泛用于內核的所有子系統,實現也比較簡單。舉兩個例子,其他的暫時不做分析了。

分配頁面用于加入地址空間

[cpp]

/*從伙伴系統中分配頁面,頁面的標志根據地址空間中的標志進行設置*/

staticinlinestructpage?*page_cache_alloc(structaddress_space?*x)

{

return__page_cache_alloc(mapping_gfp_mask(x));

}

分配完了添加到基數樹中

[cpp]

/*

*?Like?add_to_page_cache_locked,?but?used?to?add?newly?allocated?pages:

*?the?page?is?new,?so?we?can?just?run?__set_page_locked()?against?it.

*/

staticinlineintadd_to_page_cache(structpage?*page,

structaddress_space?*mapping,?pgoff_t?offset,?gfp_t?gfp_mask)

{

interror;

__set_page_locked(page);

/*實際的添加工作*/

error?=?add_to_page_cache_locked(page,?mapping,?offset,?gfp_mask);

if(unlikely(error))

__clear_page_locked(page);

returnerror;

}

[cpp]

/**

*?add_to_page_cache_locked?-?add?a?locked?page?to?the?pagecache

*?@page:???page?to?add

*?@mapping:????the?page's?address_space

*?@offset:?page?index

*?@gfp_mask:???page?allocation?mode

*

*?This?function?is?used?to?add?a?page?to?the?pagecache.?It?must?be?locked.

*?This?function?does?not?add?the?page?to?the?LRU.??The?caller?must?do?that.

*/

intadd_to_page_cache_locked(structpage?*page,structaddress_space?*mapping,

pgoff_t?offset,?gfp_t?gfp_mask)

{

interror;

VM_BUG_ON(!PageLocked(page));

error?=?mem_cgroup_cache_charge(page,?current->mm,

gfp_mask?&?GFP_RECLAIM_MASK);

if(error)

gotoout;

/*樹的相關結構申請*/

error?=?radix_tree_preload(gfp_mask?&?~__GFP_HIGHMEM);

if(error?==?0)?{

page_cache_get(page);/*使用計數加一*/

page->mapping?=?mapping;

page->index?=?offset;

spin_lock_irq(&mapping->tree_lock);

/*實際的插入操作*/

error?=?radix_tree_insert(&mapping->page_tree,?offset,?page);

if(likely(!error))?{

mapping->nrpages++;

__inc_zone_page_state(page,?NR_FILE_PAGES);

if(PageSwapBacked(page))

__inc_zone_page_state(page,?NR_SHMEM);

spin_unlock_irq(&mapping->tree_lock);

}else{

page->mapping?=?NULL;

spin_unlock_irq(&mapping->tree_lock);

mem_cgroup_uncharge_cache_page(page);

page_cache_release(page);

}

radix_tree_preload_end();

}else

mem_cgroup_uncharge_cache_page(page);

out:

returnerror;

}

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的linux系统页面缓存,Linux缓存机制之页缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。