您的位置:首页 > 运维架构 > Linux

[深入理解文件系统之九] Linux 中页高速缓存的实现

2017-03-10 14:06 519 查看
深入理解Page
Cache要求对Unix/Linux系统内存管理有深入的了解。以Linux为例,在x86系统上它提供了基于三级页表和TLB的虚拟内存管理方式。实现了虚拟地址到物理地址的转换,同时为上层的内核态和用户态调用提供了统一的接口。对于内核态的调用,内核自身除了代码段、静态数据之外的内存的申请和是否而言,它提供了基于页框管理的API;
对应用户态的应用,在申请和使用内存的时候,提供了基于缺页异常的内存描述符合线性区对象的管理。具体需要阅读《深入理解Linux内核》。而和文件系统相关的一部分是内核中的线性区数据结构vm_area_struct。
Page Cache中的内容

Linux 系统中 page
cache可以支持多种不同类型的页,比如下面的几种:a.页中包含普通文件的数据和基于磁盘文件系统的目录;b.特殊设备和文件基于内存映射后的页;c.页中的数据是直接从块设备读到的数据(跳过了文件系统层@@@)d.页中还包含已经交换到磁盘上的数据e.
IPC共享的存储区,比如share
memory
页缓存数据结构
上述不同类型的页,对应了在调入和替换的时候不同的操作,为此需要为不同类型的页定义和实现不同的操作,为此引入了address_space作为桥梁,保证具体不同页的操作各自能实现期望的功能,同时向上提供统一的接口。涉及到的数据结构包括: inode/address_space:
struct
inode { ….. struct
address_space * i_mapping; struct
address_space i_data; ….}
struct
address_space { struct
list_head clean_pages; struct
list_head dirty_pages; struct
list_head locked_pages; unsigned
long nrpages;
…... struct
address_space_operations * a_ops; // 属主页上的操作的方法 strcut
indoe * host; //point to host nodestruct
vm_area_struct * i_mmap; // 指向私有的内存映射区域 struct
vm_area_struct * i_mmap_shared; // 指向公有的内存映射区域 ……. int
gfp_mask; // 属主页的内存分配器标志}
可以看到上面两个数据结构可以相互指向,同时在address_space送还有一个统一的struct
a_ops, 看看它里面的具体内容可以看到,它包括下面的操作方法:.
writepage(): 从页写入属主的磁盘映像.
readpage(): 从属主的磁盘映像读到页.sync_page():启动在页上已经安排的I/O数据传送操作.prepare_write():准备针对基于磁盘文件的写操作.commit_write():完成磁盘文件的写操作.bmap():从文件块索引获得逻辑块号(很重要的一个函数,在IO路径上很关键).flushpage():准备删除来自属的磁盘映射的页.releasepage():由日志文件系统来准备释放页.direct_IO():数据页的直接传送 (SDDK/nvme上应该考虑用到过,以便充分释放硬件性能)
页散列表
考虑到对大文件的处理过程,页高速缓存里装了许多和这个文件相关的页,此时为了查找指定偏移的文件内容,就需要扫描长长的页描述符链表,这可能变成了一个很耗时的操作,反而影响了page
cache设计的初衷。为此,引入了页散列表(hash值)来加快查找。Linux内核中用page_hash_table【】的页描述符指针散列表,以address_space对象的地址和偏移量作为index来找到页表中指定文件偏移的内容。

可以看到,其实SVR4中的实现和Linux中的实现还是很像的,都有数据结构来实现程序中的段,然后基于段进行数据的缓存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux VM Page