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;

}0b1331709591d260c1c78e86d0c51c18.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/454671.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/454671.shtml
英文地址,請注明出處:http://en.pswp.cn/news/454671.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

十月百度,阿里巴巴,迅雷搜狗最新面試七十題(更新至10.17)

十月百度,阿里巴巴,迅雷搜狗最新面試十一題 引言 當即早已進入10月份,十一過后,招聘,筆試,面試,求職漸趨火熱。而在這一系列過程背后浮出的各大IT公司的筆試/面試題則蘊含著諸多思想與設計&…

python threading 結束線程

python threading 啟動的線程,并沒有提供終止線程的方法,現總結一下在網上找到的方法 1、通過threading.Thread._Thread__stop()結束線程 import time import threading def f():while 1:time.sleep(0.1)print(1)t threading.Thread(targetf) t.start…

快讀模板

快速讀入字符 inline char readc(){ static char buf[1 << 18], *fs, *ft;return (fs ft && (ft (fs buf) fread(buf, 1, 1 << 18, stdin)), fs ft) ? EOF : *fs; } 快速讀入數字 inline int readint(){register char creadc();register int res0;re…

fasttext 文本分類_4種常見的NLP實踐思路【特征提取+分類模型】

越來越多的人選擇參加算法賽事&#xff0c;為了提升項目實踐能力&#xff0c;同時也希望能拿到好的成績增加履歷的豐富度。期望如此美好&#xff0c;現實卻是&#xff1a;看完賽題&#xff0c;一點思路都木有。那么&#xff0c;當我們拿到一個算法賽題后&#xff0c;如何破題&a…

Angular4學習筆記(六)- Input和Output

概述 Angular中的輸入輸出是通過注解Input和Output來標識&#xff0c;它位于組件控制器的屬性上方。 輸入輸出針對的對象是父子組件。 演示 Input 新建項目connInComponents:ng new connInComponents.新增組件stock:ng g component stock.在stock.component.ts中新增屬性stockN…

Python 常見加密方式和實現

Python 加密與解密小結 這篇文章主要介紹了Python 加密與解密,使用base64或pycrypto模塊 前言 據記載&#xff0c;公元前400年&#xff0c;古希臘人發明了置換密碼。1881年世界上的第一個電話保密專利出現。在第二次世界大戰期間&#xff0c;德國軍方啟用“恩尼格瑪”密碼機…

jenkins日志亂碼linux,Jenkins控制臺中亂碼問題解決

由于服務器環境及應用層各版本的不同、編碼方式的不同因此會有很多種情況會出現亂碼問題。由于Jenkins中的job運行的是獨立的一個shell環境&#xff0c;許多的環境變量與服務器中是不一樣的&#xff0c;因此在job中執行的命令也就會有所差異。因此可以在job中執行env命令&#…

13,反轉鏈表《劍指offer》

題目&#xff1a; 輸入一個鏈表&#xff0c;反轉鏈表后&#xff0c;輸出鏈表的所有元素。 思路&#xff1a; 反轉鏈表&#xff0c;對于片段 1--->2--->3循環操作&#xff1b; 要反轉鏈表需要兩步&#xff1a; 一&#xff0c;將2->next指向1 &#xff08;如果不保存3那…

什么是面試的關鍵?資深HR告訴你!

求職指南、面試寶典、應聘手冊……到任何一個書店去轉轉&#xff0c;總能發現一兩本這樣的書&#xff0c;有關面試應聘的包裝技巧實在太多&#xff0c;既讓應聘者眼花繚亂、無所適從&#xff0c;也讓人事經理頭疼&#xff0c;總擔心會被應聘者的包裝所蒙騙。東方控股集團有限公…

windows商店_Windows記事本應用現在可以從Microsoft Store中獲得

早在2019年8月&#xff0c;微軟就宣布將把人們最常用的Windows記事本應用搬到應用商店&#xff0c;讓這款深受用戶喜愛的應用更新速度更快、響應更靈敏。12月晚些時候&#xff0c;微軟卻放棄了這一計劃&#xff0c;也沒有給出太多理由。但現在&#xff0c;這一計劃已經完成&…

.net core linux 編譯,.NET Core 源碼編譯的問題解析

引言&#xff1a; .NET Core 源碼編譯https://github.com/dotnetgit clone https://github.com/dotnet/runtime.git一&#xff1a;Windows 編譯VS 2019 16.6(不要安裝預覽版)Win 10 專業版&#xff0c;最新版本 (1903/2004)長路徑支持&#xff1a;組策略(gpedit.msc) > 計算…

jmeter 壓測duobbo接口,施壓客戶端自己把自己壓死了

jmeter 壓測duobbo接口&#xff0c;jmeter代碼不合理&#xff0c;導致每執行一次請求&#xff0c;會調用一次消耗內存的實例化。導致越壓越慢&#xff0c;請求發不出去。這個時候需要考慮修改代碼了。 截圖中&#xff0c;tps越來越少。 原來初始化的代碼放在 runTest中執行。修…

oracle pl/sql 包

包用于在邏輯上組合過程和函數&#xff0c;它由包規范和包體兩部分組成。1)、我們可以使用create package命令來創建包&#xff0c;如&#xff1a;i、創建一個包sp_packageii、聲明該包有一個過程update_saliii、聲明該包有一個函數annual_income --聲明該包有一個存儲過程和一…

MySQL 之 explain

explain 介紹 explain顯示了MySQL如何使用索引來處理select語句以及連接表。可以幫助選擇更好的索引和寫出更優化的查詢語句。簡單講&#xff0c;它的作用就是分析查詢性能。explain 查詢SQL - 用于顯示SQL執行信息參數&#xff0c;根據參考信息可以進行SQL優化 示例&#x…

[置頂]微軟面試智力題

這個笑話反映了兩個公司不同的企業文化。很多人都知道微軟的企業文化是寬松和自由&#xff0c;給員工一個充分發揮創造力的空間&#xff0c;這也是微軟能吸引很多人才的原因之一。但是&#xff0c;要想進微軟工作可不容易&#xff0c;微軟在招聘工作上一點也不馬虎&#xff0c;…

背單詞軟件 單詞風暴 分享id_周一考研高效背單詞系列(一):利用單詞軟件如何背好單詞...

高效背單詞考研單詞作為考研路上的第一大難關&#xff0c;相信很多小伙伴都在這上面吃過不少苦&#xff0c;有同學更是看到密密麻麻的大綱詞匯就頭疼&#xff0c;但只要是學習就是有方法的&#xff0c;今天&#xff0c;我們開始推出高效背單詞系列——墨墨背單詞。另&#xff1…

linux c++ 編譯 庫,LINUX C/C++ 編譯庫關系

在LINUX 下安裝個啥,都要涉及到編譯,尤其是開源軟件. 那么編譯就涉及到C/C 和對應的庫. 我們理一理之間的關系有助于MYSQL8源碼編譯libc glibc libc libstdc eglibc GCC G CMakeGDB從libc說起。libc是Linux下原來的標準C庫&#xff0c;也就是當初寫hello world時包含的頭文件#…

Linux_學習_Day3_bash

Shell bash是外部程序&#xff1a;type/whichis bash。 shell&#xff0c; 子shell。可以利用bash打開另一個bash。即打開一個子shell。并且每個進程是獨立存在的。對于子shell而言&#xff0c;bash并不認知其他bash的存在。 執行了多次bash&#xff0c;要退出只需exit。用pst…

mysql 之 優化 (收集于網絡)

&#xff08;以下內容均來自于網絡&#xff0c;如果有版權限制&#xff0c;請聯系我0.0&#xff09; Mysql存儲千億級的數據&#xff0c;是一項非常大的挑戰。Mysql單表可以存儲10億級的數據&#xff0c;只是這個時候性能非常差&#xff0c;項目中大量的實驗證明&#xff0c;M…

hadoop-09-安裝資源上傳

hadoop-09-安裝資源上傳 在/software/www/html 下面上傳 ambari HDP HDP-UTILS-1.1.0.21 文件&#xff0c;之后解壓&#xff1b;