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.mzph.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;