文档章节

内存管理之9:磁盘页面的抽象

我叫半桶水
 我叫半桶水
发布于 07/14 11:56
字数 1824
阅读 3
收藏 0

date: 2014-10-01 19:09

在讲《x86页式内存管理》中提到过“页面交换”。一个系统的物理内存总是有限的,但是运行在其上的进程却不敢不顾的一味“索取”,为了解决这种困境,在计算机的发展史上很早就有将内存中的内容与一个专用的磁盘空间交换的技术,即把内存中暂时不用的内容存到磁盘上,为其他急用的内容腾出内存空间,到需要时再将磁盘上的内容读到内存中。

在继续之前,要明确几个概念。首先“虚存页面”指虚拟地址空间中一个固定大小,边界与页面大小(4KB)对齐的区间及内容。“虚存页面”最终要落实(映射)到某种物理存储介质上,这就是“物理页面”。根据介质的不同,“物理页面”分为“内存页面”(在内存中)和“磁盘页面”(在磁盘上)。当我们谈及(物理)内存页面的分配和释放时,指的仅是物理介质;而在谈及页面的换入换出时,指的是页面中的内容。

我们在讨论(物理)内存页面时提到page结构就是内存页面的户口,系统在初始化阶段,内核根据检测到的内存的大小,为每一个页帧建立page结构,形成一个page结构的数组,并用全局变量mem_map指向这个数组,mem_map就像是物理内存的户口簿,有了这个户口簿系统就可以跟踪到每一个页帧。

那么“磁盘页面”呢?“磁盘页面”是如何管理的呢?

1 交换设备的抽象swap_info_struct

首先,对“磁盘页面”内核并没有对应的结构体,因为磁盘页面要依附在“交换设备”(通常是磁盘,也可以是普通文件,设备即文件)上,从内核管理磁盘页面角度来看,只需知道它在交换设备上的位置,以及该页面的使用计数(表示该页面是否被使用,以及有几个用户在共享该页面)即可。一个交换设备上的磁盘页面肯定具有相同的属性,这些属性信息从交换设备上获取即可。因而,内核对磁盘页面的管理是按交换设备来进行的。交换设备对应的抽象为swap_info_struct结构,而“磁盘页面”的定义也是依附在swap_info_struct结构体中。

swap_info_struct结构定义如下:

    <include/linux/swap.h>
    struct swap_info_struct {
    	unsigned int flags;
    	kdev_t swap_device;
    	spinlock_t sdev_lock;
    	struct dentry * swap_file;
    	struct vfsmount *swap_vfsmnt;
    	unsigned short * swap_map;
    	unsigned int lowest_bit;
    	unsigned int highest_bit;
    	unsigned int cluster_next;
    	unsigned int cluster_nr;
    	int prio;			/* swap priority */
    	int pages;
    	unsigned long max;
    	int next;			/* next entry on swap list */
    };
  • swap_file、swap_vfsmnt与文件系统相关。
  • swap_map指向一个unsigned short型的数组,数组中的每一个元素代表一个磁盘页面:元素对应的unsigned short值代表该磁盘页面的引用计数;而下标则表示磁盘页面在文件中或者磁盘上的位置。其中第一个元素即swap_map[0]所代表的那个磁盘页面是不用做页面交换的,它包含了该交换文件或设备自身的信息以及一个代表哪些页面可供使用的位图,这个页面相当于该交换设备的“控制块”。数组的大小由成员pages表示,它表示该页面交换设备的大小。由于交换设备上某些页面是不用做交换的,而这些页面大都集中在交换设备的开头和结尾,所以lowest_bit和highest_bit分别表示交换设备上用户交换的页面的“起始”和“终止”。另一成员max则表示该交换设备上最大的磁盘页面号,也就是设备或文件的物理大小。

linux内核允许使用多个交换设备,所以在内核中还有一个swap_info_struct结构数组swap_info,其定义如下:

    <include/linux/swap.h>
    #define MAX_SWAPFILES 8
    <mm/swapfile.c>
    struct swap_info_struct swap_info[MAX_SWAPFILES];

可见,最多可以使用8个交换设备。注意这个全局数组swap_info,内核就是通过这个全局数组找到对应的交换设备的。

2 磁盘页面的“页面表项”的抽象swp_entry_t

就像虚存页面通过页面表项pte_t与物理内存页面建立映射关系一样,磁盘页面也有类似的“页面表项”swp_entry_t。swp_entry_t的定义如下:

    <include/linux/shmem_fs.h>
    
     /*
     * A swap entry has to fit into a "unsigned long", as
     * the entry is hidden in the "index" field of the
     * swapper address space.
     *
     * We have to move it here, since not every user of fs.h is including
     * mm.h, but m.h is including fs.h via sched .h :-/
     */
    typedef struct {
        unsigned long val;
    } swp_entry_t;

可见,swp_entry_t也为32位的整数,与pte_t一样,swp_entry_t也将32位分段使用,这里分成的3段,示意如下:

swp_entry_t

  • type段指示该页面在哪个交换设备(文件)中,是个序号,其实就是全局数组swap_info的下标。
  • offset段表示页面在交换设备(文件)的位置,也是一个序号,其实就是swap_info_struct结构中数组swap_map的下标。
  • swp_entry_t的bit0必须为0。其实swp_entry_t就是pte_t的“变身”。回忆前面pte_t的定义,当bit0为1,表示页面在内存中,而其余各bit表示该内存页面的起始地址以及页面属性。而当页面在磁盘上时,则相应的页面表项pte_t不再指向一个物理内存页面,而是“变身”为swp_entry_t,其bit0为0,表示页面不在内存中,所以MMU对其余各bit都忽略不顾,留待内核自由支配,内核也就顺势利用其余的bit指明了这个页面的去向,何乐而不为呢。

需要说明:当内存页面交换到磁盘页面上之后,对应的页面表项pte_t就“变身”为swp_entry_t,“变身”后仍驻留在之前的页表中,此时虚存页面被映射到一个磁盘页面上了。当在用户空间访问虚存页面时,根据CR3一步步找到这个页面表项(swp_entry_t),MMU发现其bit0为0,了解到该页面不在内存中,于是触发页面异常。我们在前面分析过页面异常的处理程序do_page_fault,此种情况又对应另一种场景:出错地址没有落在空洞中,而且就落在某个虚存区间vma中,内核通过读取对应的swp_entry_t可以知道该虚存页面的去向,然后将其换入到内存中。有兴趣的同学可以自行一观。

pte_t与swp_entry_t的关系是如此的密切,内核为此定义了一组宏:

    /* Encode and de-code a swap entry */
    #define SWP_TYPE(x)			(((x).val >> 1) & 0x3f)
    #define SWP_OFFSET(x)			((x).val >> 8)
    #define SWP_ENTRY(type, offset)	((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
    #define pte_to_swp_entry(pte)		((swp_entry_t) { (pte).pte_low })
    #define swp_entry_to_pte(x)		((pte_t) { (x).val })

© 著作权归作者所有

共有 人打赏支持
我叫半桶水
粉丝 0
博文 26
码字总数 71642
作品 0
西安
私信 提问
kswapd和pdflush

首 先,它们存在的目的不同,kswap的作用是管理内存,pdflush的作用是同步内存和磁盘,当然因为数据写入磁盘前可能会换存在内存,这些缓存真正写 入磁盘由三个原因趋势:1.用户要求缓存马上写...

晨曦之光
2012/04/10
437
0
Linux 内核的文件 Cache 管理机制介绍

1 前言 自从诞生以来,Linux 就被不断完善和普及,目前它已经成为主流通用操作系统之一,使用得非常广泛,它与 Windows、UNIX 一起占据了操作系统领域几乎所有的市场份额。特别是在高性能计算...

满小茂
2016/11/24
22
0
Java NIO基本概念

I/O就是把数据移入/出缓冲区,用户(JVM,针对操作系统来说)进程执行IO操作的大约步骤如下: JVM进程向操作系统发出请求,让操作系统把缓冲区里的数据排干(写),或把数据填满缓冲区(读)...

克温s
2015/12/12
205
0
OS学习笔记五:存储模型

一、地址重定位 1、已知内容 程序装载到内存才可以运行 多道程序设计模型 每个进程有自己的地址空间 进程中 的地址 不是 最终的物理 地址 在进程运行 前无法计算出物理地址 2、地址重定位REL...

xunzaosiyecao
2017/10/07
0
0
第3章 内存管理

  分层存储体系:高速缓存—>内存—>外存,造价从高到低,速度由快到慢,容量由小到大,这样的存储体系。   存储管理器:OS中管理分层存储体系的部分,任务是管理内存,记录已使用和未使...

liao20081228
2017/11/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

linux之自定义命令

本人使用的是ubuntu系统,不喜欢建各种桌面快捷链接,但是每次启动个软件,去查找又麻烦,所以自定义了命令,来快捷的启动应用: 1、修改/etc/bash.bashrc,在文件末尾,加上如下List-1中的内...

克虏伯
20分钟前
3
0
linux基础

系统安全 sudo su chmod setfacl 进程管理 w top ps kill pkill pstree killall 用户管理 id usermod useradd groupad userdel 文件系统 mount umount fsck df du 网络应用 curl telnet mail......

关元
22分钟前
2
0
Caffe-源码分析(一)

CHECK_X函数,用于比较两个blob之间的值 CHECK_EQ(x,y)<<"x!=y",EQ即equation,意为“等于”,当x!=y时,函数打印出x!=y。 CHECK_NE(x,y)<<"x=y",NE即not equation,意为“不等于”,,...

Pulsar-V
22分钟前
1
0
三星Galaxy S10可能会配备TOF 3D摄像头

12月3日消息,据Phone Arena报道,三星Galaxy S10可能会配备TOF 3D摄像头。 Phone Arena报道称三星Galaxy S10一共有五颗摄像头(前置双摄+后置三摄),而5G版本的Galaxy S10后置四颗摄像头,...

问题终结者
45分钟前
10
0
fabric增删改查Mac

备份1.3版本,重新下载1.1版本到fabric文件夹 /opt/gopath/src/github.com/hyperledger/fabric -> /opt/gopath/src/github.com/hyperledger/fabric1.3 新建/opt/gopath/src/github.com/hype......

八戒八戒八戒
今天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部