文件系统学习之八:SVR4中的Page Cache

在SVR4中,所有文件的读写都会经过Page
Cache。不同于有固定长度的物理cache,或者buffer
cache, 或者DNLC. PageCache和其他cache的区别在于:它可以根据软件需求换进或者换出。另外也和buffer
cache不同:buffer
cache用设备和块号来索引cache,而page
cache用vnode和offset来索引。

  • page
    cache的构成

一个支持seg_map操作(比如当前段的缺页异常处理)的段;

一个具有多种用途的空闲页表链表(list)

当用到的page
of file data 从memory
cache中换出来(离开cache)的时候,它被加入空闲页表;

反正也可从空闲页表中取走。但有一点需要特别注意的是,尽管这个页在free
list上,但它的标识符和数据还在,这样一旦内核想再次读那份数据,不用再从磁盘上去取,而直接把个页从free
lis中移除即可。

在unix系统上,实际是按照下面chunk的方式组织的:

The
segmap structure is part of the kernel address space and is
underpinned by
the segmap_datastructure
that describes the properties of the segment. The size of the segment
is tunable and is split into MAXBSIZE(8KB)
chunks where each 8KB chunk represents an 8KB window into a file.
Each chunk is referenced by an smapstructure
that contains a pointer to a vnode for the file and the offset within
the file.

可以看到实际chunks的容量和条目有限,当都用尽的时候,就需要把一些smap搬出去。但考虑到后面可能还有对它的访问,因此就放在一个free
list表上,这样下次读的时候,就也不需要再从磁盘读了。由此可见,Page
Cache实际也是实现了两层的cache。这可能是后来zfs两级cache的前世了吧。SVR4中Page
Cache 相关的数据结构整体的框图如下:

由上图可以看到,每个进程描述符号proc数据结构中的address
space 成员 as指向当前进程的一个段表,每个段对应一个用来记录页映射的segmap_data数据结构,其中的smd_sm指向一组包含vnode和偏移的数据结构的链表。

  • PageCache 的操作

申请PageCache的时候:类似buffer
cache中getblk()的调用,在page
cache中是调用segmap_getmap()来实现的。

addr_tsegmap_getmap(struct seg *seg, vnode_t *vp, uint_t *offset);

这个函数从seg数据结构中s_base 到s_base
+
s_size的范围内,往其成员segmap_data所指向的smd_sm链表中新增一个表示其起始虚拟地址和长度的节点,然后把这个虚拟地址返回。这里需要注意,在这里只分配了内核虚拟地址,并没有内核上的物理页框和其对应。

而在释放PageCache的时候,调用类似buffer
cache 中的brelse()函数。

int
segmap_release(struct seg *seg, addr_t addr, u_int flags)

注意:这是SVR4中的Page
Cache 和早期其他内核中的page
cache 不一样的一个重要区别,在SVR4中segmap_getmap()返回的地址并没有真实物理页框和其对应,而是在后面真正有读操作发生的时候才有物理页框的资源。具体的实现过程,可以通过下面一个完整读的例子看到。

在从文件系统读数据过程中,在Page
Cache层会执行一端下面的代码:

...............

kaddr
= segmap_getmap(segkmap, vp, 8192);

uiomove(kaddr,
1024, UIO_READ, uiop);

segmap_release(segkmap,
kaddr, SM_FREE);

...............

segmap_getmap返回的虚拟地址会传递给uiomove(),
这个函数根据UIO_READ标志开始执行具体的读操作。首先,当它访问kaddr的时候,由于并没有物理页和其对应,于是会触发一个缺页中断,它会从内核中kernel
address space
(kas)已记录的所有的段的起始地址和长度的信息,索引到当前地址对应的段,进而调用这个段对应的缺页处理程序,核心的示意代码如下:

segkmap->s_ops->fault(seg,
addr, ssize, type, rw);

根据传递到fault句柄的s_base和addr参数,
可以从smap数据结构中找到对饮的vnode,然后调用对用的VOP_GETPAGE()函数,他会申请合适的页并从磁盘读回数据。等这些做完之后,page
fault 函数才处理完,然后继续执行uiomove()后续的工作。更详细的过程可以参考下面的流程图:

通过上面的流程可以看到,SVR4通过在真正读的时候才出发page
fault的机制实现了页只有在真正发生读的时候才分配(延时分配)。而文件写的过程在segmap_release()函数之前和读操作的流程差不多,可能的区别在于它的flags参数,此时可能包括下面的多种:

SM_WRITE:页应该写回到文件,通过VOP_PUTPAGE()

SM_ASYNC:页可以异步写

SM_FREE:页可以释放了

SM_INVAL:无效的页

SM_DONTNEED:文件系统不会再访问该页了

看上去,上面的操作是不是物理cache的基本操作很像呢?

时间: 2025-01-02 14:07:29

文件系统学习之八:SVR4中的Page Cache的相关文章

Linux系统中的Page cache和Buffer cache

Linux系统中的Page cache和Buffer cache Free命令显示内存 首先,我们来了解下内存的使用情况: Mem:表示物理内存统计 total:表示物理内存总量(total = used + free) used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用. free:未被分配的内存. shared:共享内存. buffers:系统分配但未被使用的buffers 数量. cached:系统分配但未被使用的cache 数量.

关于OS Page Cache的简单介绍

在现代计算机系统中,CPU,RAM,DISK的速度不相同.CPU与RAM之间,RAM与DISK之间的速度差异常常是指数级.为了在速度和容量上折中,在CPU与RAM之间使用CPU cache以提高访存速度,在RAM与磁盘之间,操作系统使用page cache提高系统对文件的访问速度. 操作系统在处理文件时,需要考虑两个问题: 1.相对于内存的高速读写,缓慢的硬盘驱动器,特别是磁盘寻道较为耗时. 2.文件加载到物理内存一次,并在多个程序间共享. 幸运的是,操作系统使用page cache机制解决了上

文件系统学习之七:SVR4文件系统和虚拟内存接口

随着SVR4集成了SunOS的Virtual Memory System (VM),SVR4虚拟文件系统对之前的I/O路径做了非常大的改进,这些变化包括buffer cache的用法以及为支持基于page-cached的IO而对内核.VM乃至磁盘驱动的改动. (With the inclusion of the SunOS VM subsystem in SVR4, and the integration between the filesystem and the Virtual Memory

Linux中的Buffer Cache和Page Cache

http://wenku.baidu.com/view/dd677d2fcfc789eb172dc868.html http://bbs.chinaunix.net/thread-3759086-1-1.html http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=4189715&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline%26orderby%3Ddateline 了解下

Java并发学习之八——在线程中处理不受控制的异常

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.Java里有2种异常: 检查异常:这些异常必须强制捕获她们或在一个方法里的throws子句中. 未检查异常:这些异常不用强制捕获它们. 2.在一个线程对象的run()方法里抛出一个检查异常,我们必须捕获并处理她们.因为run()方法不接受throws子句.当一个非检查异常抛出,默认的的行为是在控制台写下stack trace并退出程序. package chapter; public class Main8 { /** * <p> *

[深入理解文件系统之十] ext2中重要的数据结构

如果把文件系统比作一个大楼的话,它的数据布局方式和内部数据结构就是高楼的基础和框架,因此理解了它的数据布局方式和数据结构就能对数据结构有一个整体的认识.ext2作为一个经典的文件系统,不失作为一个号的入口 1. ext2文件系统的数据拓扑结构: 2. ext2重要的数据结构如下 3. ext2 数据结构内部关系 4. Linux  文件系统中的cache: inode cache, Directory cache,buffer cache, 上面这些cache再加上内存里面的 file tabl

Unix文件系统学习笔记之二: 文件描述符、inode和打开文件表

Unix文件系统学习笔记之二: 文件描述符.inode和打开文件表 系统盘上数据的布局 文件系统无非是关于数据在磁盘上的组织以及存储空间管理的,为此,首先需要知道磁盘上数据的总体布局方式.以Unix为例,最重要的一张表如下: Unix 进程管理中和用户文件.io 最相关的数据结构:usr 数据结构 The procstructure does not record information related to file access.  However the userstructure con

page cache 与free

我们经常用free查看服务器的内存使用情况,而free中的输出却有些让人困惑,如下: 先看看各个数字的意义以及如何计算得到: free命令输出的第二行(Mem):这行分别显示了物理内存的总量(total).已使用的 (used).空闲的(free).共享的(shared).buffer(buffer大小). cache(cache的大小)的内存.我们知道Total.free.buffers.cached这几个字段是从/proc/meminfo中获取的,而used = total – free.S

linux free命令中buffer与cache的区别

linux free命令中buffer与cache的区别 ~$ free total             used           free     shared   buffers     cached Mem:       1025204     981636      43568          0      38244     387808 -/+ buffers/cache:       555584      469620 Swap:      1931256    162