内核采用一种通用的地址空间方案,来建立缓存数据与其来源之间的关联。

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缓存机制之页缓存相关推荐

  1. Linux系统运行级与启动机制剖析

    一 系统运行级windows系统有安全运行模式和正常运行模式,这是两个不同的运行级,同样,linux也有系统运行级别,并且linux系统的运行级别更加灵活,更加多样化. 在讲述运行级别前,先讲述下li ...

  2. linux系统清理内存,Linux实验室:五个清理磁盘空间小妙招

    1删除安装包:清空系统APT缓存 玩儿电脑最怕的就是卡慢,那么电脑卡慢应该怎么解决呢?对于windows系统来说,你可能有各种免费的杀毒软件.全家桶帮你清空系统空间,那么Linux系统怎么办?今天笔者 ...

  3. linux系统程序PPT,Linux 系统应用与程序设计 问题.ppt

    <Linux 系统应用与程序设计 问题.ppt>由会员分享,可在线阅读,更多相关<Linux 系统应用与程序设计 问题.ppt(14页珍藏版)>请在人人文库网上搜索. 1.Li ...

  4. 连接linux系统的mysql,Linux系统MySQL开启远程连接

    1.远程连接上Linux系统,确保Linux系统已经安装上了MySQL数据库.登陆数据库.mysql -uroot -p(密码). 2.创建用户用来远程连接 GRANT ALL PRIVILEGES ...

  5. imx6ull移植Linux系统第二篇——Linux内核的移植

    imx6ull移植Linux系统第二篇--Linux内核的移植 花了大概两周的时间,把Linux的移植认真学了一遍,期间踩了不少坑,花费了不少时间去解决各种奇奇怪怪的问题,最终完成了uboot.系统镜 ...

  6. Alpine linux 小内存版,Alpine Linux系统-Alpine Linux系统【轻量级Linux】下载v3.11.0 最新版-西西软件下载...

    Alpine Linux系统[轻量级Linux],Alpine Linux其实就是一个清凉版的Linux系统,通过牺牲一些不常用的功能和特性来达到更加轻巧的体积以及更快的响应速度.Alpine Lin ...

  7. linux系统的笔记本,Linux:开源的免费操作系统_笔记本电脑_笔记本评测-中关村在线...

    ■linux Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协议 ...

  8. Linux系统之部署Linux管理面板1Panel

    Linux系统之部署Linux管理面板1Panel 一.1Panel介绍 1.1Panel简介 2.1Panel特点 二.本地环境规划 1.本此实践目的 2.本地环境规划 三.检查本地环境 1.检查操 ...

  9. linux系统页面缓存,Linux 页缓存

    (虚拟地址空间是相对磁盘空间到物理内存空间的映射而言来说的). 经内存映射的文件每次只读取一页内容,读取后的页保存在页缓存中,利用页缓存,可提高文件的访问速度.如图 10-6 所示,页缓存由 page ...

最新文章

  1. 调研字节码插桩技术,用于系统监控设计和实现
  2. 进程的创建-fork
  3. 第一行冻结_EXCEL函数tips(4) 数据冻结和查找
  4. w10计算机运行特别卡,电脑卡是什么问题?导致Win10正式版卡顿的原因及解决方法...
  5. The Tail at Scale
  6. FL的萌新之路,开始了!
  7. aix系统java堆_浅谈AIX环境下的Java性能调优
  8. ambari 自定义组件安装
  9. python 导入包 作用域_Python 包、模块、函数、变量作用域
  10. python最新版安装图集_通过python简单的实现了plist、json图集的切割
  11. React-组件的生命周期
  12. 句柄泄漏与应用程序体验查找服务(AELookupSvc)
  13. 关于位域如何节省内存(C++)
  14. Android5.1开机LOGO与开机动画【转】
  15. 2020年最好用的手机是哪一款_2020最好用的5G手机是哪一款?热销2020年5g手机推荐及点评...
  16. OpenMP: sections分段并行
  17. 时间观——《天行九歌》第51集《一叶知秋》台词与典故
  18. 格林纳达常驻WTO大使孙宇晨会见法国驻联合国日内瓦办事处代表
  19. window系统上安装oracle
  20. JAVA编写FCFS(先来先服务算法) 和 SJF(最短进程优先调度算法)

热门文章

  1. 转型从思维习惯的转变开始
  2. 函数式编程语言天生就慢吗?
  3. H.264解码器ffmpeg完整优化代码(包括PC和Windows Mobile版本)
  4. Vuejs:组件 slot 内容分发
  5. IntelliJ IDEA 配置JDK
  6. ResourceDictionary主题资源替换(二) :编译期间,替换主题资源
  7. HDU 6071 Lazy Running
  8. Android selector中的item的顺序
  9. python基础之01数据类型-变量-运算浅解
  10. 李洋疯狂C语言之将”you are come from shanghai ”倒置为”shanghai from come are you”,将句子中的单词位置倒置,而不改变单词内部结构