Page Cache

编辑:学习号互动百科 时间:2019-09-26 14:00:06
编辑 锁定
本词条缺少概述名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!
中文名
高速缓冲存储器
外文名
Page Cache
简????称
页高缓
大????小
一页
一、page cache简介
page cache,又称pcache,其中文名称为页高速缓冲存储器,简称页高缓。page cache的大小为一页,通常为4K。在linux读写文件时,它用于缓存文件的逻辑内容,从而加快对磁盘上映像和数据的访问。
二、page cache的功能详解
在从外存的一页到内存的一页的映射过程中,page cache与buffer cache、swap cache共同实现了高速缓存功能,以下是其简单映射图,
外存的一页(分解为几块,可能不连续)
|
|
物理磁盘的磁盘块
|
|
内存的buffer cache
|
|
内存的一页(由一个页框划分的几个连续buffer cache构成)
|
|
页高缓系统
在这个过程中,内存管理系统和VFS与page cache交互,内存管理系统负责维护每项page cache的分配和回收,同时在使用memory map方式访问时负责建立映射;VFS负责page cache与用户空间的数据交换。
三、page cache的管理
在Linux内核中,文件的每个数据块最多只能对应一个page cache项,它通过两个数据结构来管理这些cache项,一个是radix tree,另一个是双向链表
Radix tree是一种搜索树,Linux内核利用这个数据结构,快速查找脏的(dirty)和回写的(writeback)页面,得到其文件内偏移,从而对page cache进行快速定位。图1是radix tree的一个示意图,该radix tree的分叉为4(22),树高为4,用来快速定位8位文件内偏移。
另一个数据结构是双向链表,Linux内核为每一片物理内存区域(zone)维护active_list和 inactive_list两个双向链表,这两个list主要用来实现物理内存的回收。这两个链表上除了文件Cache之外,还包括其它匿名 (Anonymous)内存,如进程堆栈等。
四、page cache相关API及其实现
Linux内核中与文件Cache操作相关的API有很多,按其使用方式可以分成两类:一类是以拷贝方式操作的相关接口,如read/write/sendfile等,其中sendfile在2.6系列的内核中已经不再支持;另一类是以地址映射方式操作的相关接口,如mmap等。
第一种类型的API在不同文件的Cache之间或者Cache与应用程序所提供的用户空间buffer之间拷贝数据,其实现原理如图2所示。
第二种类型的API将Cache项映射到用户空间,使得应用程序可以像使用内存指针一样访问文件,Memory map访问Cache的方式在内核中是采用请求页面机制实现的,其工作过程如图3所示。
首先,应用程序调用mmap(图中1),陷入到内核中后调用do_mmap_pgoff(图中2)。该函数从应用程序的地址空间中分配一段区域作为映射的内存地址,并使用一个VMA(vm_area_struct)结构代表该区域,之后就返回到应用程序(图中3)。当应用程序访问mmap所返回的地址指针时(图中4),由于虚实映射尚未建立,会触发缺页中断(图中5)。之后系统会调用缺页中断处理函数(图中6),在缺页中断处理函数中,内核通过相应区域的 VMA结构判断出该区域属于文件映射,于是调用具体文件系统的接口读入相应的Page Cache项(图中7、8、9),并填写相应的虚实映射表。经过这些步骤之后,应用程序就可以正常访问相应的内存区域了。

Page Cache加入/离开page cache还涉及到如下几个函数

编辑
add_page_to_hash_queue /*加入pache cache hash表*/
add_page_to_inode_queue /*加入inode queue即address_space*/
remove_page_from_inode_queue
remove_page_from_hash_queue
__remove_inode_page /*离开inode queue和hash 表*/
remove_inode_page /*同上*/
add_to_page_cache_locked /*加入inode queue,hash 和lru cache*/
__add_to_page_cache /*同上*/
仅罗列函数add_page_to_hash_queue,以示完整:<>
color=green>
static void add_page_to_hash_queue(struct page * page, struct page **p)
{
struct page *next = *p;
*p = page; /* page->newNode */
page->next_hash = next; /* +-----+ */
page->pprev_hash = p; /* p--> |hashp|-->|oldNode| */
if (next) /* next----+ */
next->pprev_hash = &page->next_hash;
if (page->buffers)
PAGE_BUG(page); /*证明page 不会同时存在于page cache
和 buffer cache*/
/*2.6 已经与此不同了*/
atomic_inc(&page_cache_size);
}

Page Cachepage cache 和 inode

编辑
page cache 在代码中又称 inode page cache, 足以显示page cache 和inode紧密关联.加入page cache 和加入inode cache是同一个意思.加入page cache意味着同时加入page cache hash表和inode queue(也建立了page和addr sapce的关系). 见函数add_to_page_cache_locked,__add_to_page_cache即可取证.从page cache 删除在程序中叫__remove_inode_page,再次显示inode 和page cache的"一体化".
词条标签:
计算机学