Linux 3.x 内核学习笔记——页面的周转

linux 内存页面交换 在Linux中,**页面交换(PagingSwap)**是操作系统内存管理的一部分,涉及将内存中的数据页移动到硬盘或其他交换空间中(称为交换区或交换文件),以便释放物理内存供其他进程使用。这是一种管理内存资源的技术,用于应对物理内存不足的情况。以下是页面交换的关键点:基本概念交换空间(SwapSpace):这是一个专门的磁盘空间或文件,Linux系统用它来存储从内存中移出的数据页。交换空间可以是独立的分区(交换分区)或交换文件。页面(Page):内存被分割成固定大小的块,称为页面。 阅读详情

页面周转

本文以Linux-3.11.0为例。

内核中所有物理内存都有其对应的page结构,这些page在整个系统的运行中,会处于下图的5个状态中。

Freeze Page:并非所有内存都可以用于分配,有些内存被内核所保留使用,例如:内核映像本身所处的内存空间、一些硬件要求需要保留的地址区间、内核中一些固有的数据结构(如page结构本身)等。系统在初始化阶段将这些内存所对应的地址标识为reserve,在初始化完成时,并不会将这些reserve的地址对应的page结构释放入空闲页面管理区。因此这部分page始终处于Freeze Page状态,它们既不会被分配,也不会被释放。

流程1:在初始化完成时,将没有reserve的page结构通过__free_pages函数直接释放到空闲页面管理区中(通过free_all_bootmem触发)。这些页面就可以在系统运行过程中被分配、释放。

Hot Cold:为了便于单个页面的快速分配和释放,内核为每个cpu建立了一个冷热队列(Hot Cold List)。

Free Area:每个区间(Zone)对应一组(通常为11个)Free Area队列,每个队列用于管理大小为2^n的连续物理页面。

流程2:释放单个页面时,直接挂入冷热队列(__free_pages -> free_hot_cold_page)。

流程3:释放多个页面(2^n个页面,且n >= 1 )时,挂入对应的Free Area队列(__free_pages -> __free_pages_ok)。同时如果满足页面合并的条件,还会将页面合并后挂入更高阶的Free Area队列。

流程4:页面挂入冷热队列后,如果发现队列中的页面数量超过一定的阀值,则将部分页面移到相应的Free Area队列中(free_pcppages_bulk)。

流程5:分配单个页面时,直接从冷热队列中获取(buffered_rmqueue)。

流程6:分配单个页面时,如果冷热队列中的页面不足,则从Free Area队列中再获取一些(buffered_rmqueue -> rmqueue_bulk)。

流程7:分配多个页面时,从某个Zone的Free Area队列中寻找满足条件的页面进行分配(buffered_rmqueue ->__rmqueue)。

Common Page:普通页面,这类页面使用周转很简单,就是一个简单的分配(流程10)、使用、释放(流程11)的过程。如vmalloc/kmalloc分配的页面属于这一类型。

Lru List:不同于普通页面,有些页面在使用时进行分配(流程8),而在系统内存紧张时将其内容交换到磁盘上,并将其page释放(流程9)以作它用。当需要再次使用这些内容时,再分配新的页面(流程8)并将内容从磁盘上读入。这样的页面包括:映射用户空间的页面、文件的读写缓冲页面等。上图中的Lru List是一个复合状态,其具体流程如下图。

 

Lru队列的页面周转

Linux内核为每个Zone建立了5个Lru队列。用做盘区交换的页面,都挂入Active / Inactive Anon队列中;用于文件读写缓冲区的页面,都挂入Active / Inactive File队列中。这4个队列中的页面都是可被换出的,即可回收的(evictable)。与之相对应,还有一个队列是不可回收的(Unevictable),其内的页面不能换出。

需要注意,一个页面从Inactive Anon转到Unevictable队列后,当其再次变为evictable时,还是只能回到Inactive Anon队列,而不会进入Inactive File队列。File队列中的页面也是如此,上图中的状态变迁示意不要引起误解。

下面以盘区交换页面的周转为例,简要介绍一下Lru队列的页面周转流程。

用户空间的页面由缺页异常首次创建时,在do_anonymous_page 中通过page_add_new_anon_rmap将其挂入Active Anon队列。

Linux内核为每个内存节点(node)创建了一个kswapd进程(在kswapd_init中实现),kswapd周期运行,其首先扫描node下的zone的Active Anon队列(shrink_active_list)。

shrink_active_list中将部分处于Active Anon队列中的页面移出,并将其对应的页面映射pte表项的ACCESS标志置0,然后再将其移到Inactive Anon队列中。

此后通过shrink_inactive_lists扫描Inactive Anon队列,并将其中部分页面移出,并尝试进行解除映射,这是在shrink_page_list中通过try_to_unmap进行的。

页面映射pte表项的ACCESS标志是由cpu硬件进行设置的,当cpu通过MMU访问过一个页面时,就会将其对应的pte表项的ACCESS标志置1。而在try_to_unmap的调用过程中,会检测这个标志,如果这个标志为0,就表明距上次置0以后cpu没有访问过这个页面,那么就说明可以将其解除映射,以备换出;如果这个标志为1,则try_to_unmap返回失败,并将该页面放回到Active Anon队列中。

对于成功解除映射的页面,若其内容为dirty,则通过pageout将其内容写到磁盘。

最后将该页面释放。

当该页面对应的地址再次被cpu访问时,由于页面不在内存,缺页异常处理流程会来到do_swap_page中,将新换入的页面挂入Inactive Anon队列(在swapin_readahead ->  read_swap_cache_async -> lru_cache_add_anon 中实现)。这次该页面虽然挂到了Inactive队列,但是由于cpu刚刚访问过相应页面,因此pte表项的ACCESS标志为1,其实是不会立即被换出的。

另外,Linux提供了系统调用mlock和mlockall用于将页面固定于内存中,不让其被换出。

当调用mlock / mlockall时,仅仅是将相应的vma->vm_flags加上一个VM_LOCKED标志(mlock_fixup中实现)。当kswapd在扫描某个页面试图将其换出时,如果发现相应的vma->vm_flags有VM_LOCKED标志,则会将其移入Unevictable队列,不让其换出。

当调用munlock或munlockall时,不仅要将相应的vma->vm_flags的VM_LOCKED标志清除,还要将其移入Inactive队列(munlock_vma_pages_range -> munlock_vma_page)。

 

全面解析Linux 内核 3.10.x - 如何开始 From: ongoingcre 我寻寻觅觅,寻寻觅觅,一个温暖的怀抱 - 我是一只小小鸟万事开头难 - 如何开始?人总是对未知的事物充满恐惧!就像航海一样,在面对危难的时候,船员和船长是一样心中充满恐惧的!只是船员始终充满恐惧,而船长却能压抑恐惧并从当前找出突破口! 我没有船长之能,但也算入行两年的老船员,我会追随船长一起寻找突破口!而内核如此庞然大物不知从何入手这真的很正常,那么应该的入口在 阅读详情

相关推荐

【Note】《Linux 内核深度解析:基于 ARM64 架构的 Linux 4.x 内核》 第三章:内存管理(Memory Management)

ARM64 使用64 位虚拟地址空间配置虚拟地址空间页表级别每页大小4KB 页48-bit VA4 级页表4KB16KB 页48-bit VA3 级页表16KB64KB 页42-bit VA2 级页表64KBLinux 采用基于页(Page)的虚拟内存管理方式,每个页的大小通常为 4KB,通过页表完成虚拟地址到物理地址的映射。页表结构,每一级页表映射更多地址。用户空间地址段内核空间地址段ARM64 的内核地址空间以开始,一般为。

YZJincsdn的博客 1262

Page in/Page out/Page fault

Paging refers to writing portions, termed pages, of a process' memory to disk. Swapping, strictly speaking, refers to writing the entire process, not just part, to disk. In Linux, true swapping is ex...

weixin_34072637的博客 789

在Linux 2.4.x内核中,如何从一个page找到所有映射该页面的VMA?反向映射可以带来哪些便利?

2.4.x内核中要查找映射特定页面的VMA是相对低效的,需要通过遍历进程和页表实现。查找映射页面的VMA O(N^2) 遍历所有进程和页表 通过struct page->mapping直接访问 性能从O(N)提升到O(1)在Linux 2.4.x中,没有直接的方法可以从一个struct page找到所有映射它的VMA。通过理解反向映射的演变,我们可以更好地把握Linux内存管理的设计哲学,以及为现代大型系统设计高效数据结构的重要性。进程映射页面时,调用page_add_rmap()添加反向映射项。

sinat_37817094的博客 1111

linux内存管理中的page

内核中最初勾引我好奇心的还是内存管理方面,我们平时编写应用程序时,一个进程所能拥有的内存大小几乎可以趋近于物理内存最大值或是超越这个值,虽然知道内核做内存方面的映射或是swap然后向我们的用户空间呈现出所谓的虚拟内存,但还是对其中实现疑惑甚多,一些关于内存的名词也是有许多,什么虚拟地址,内核线性地址,内核逻辑地址,balablabla… 屁话不讲了,我们直接来看内核底层是如何来管理物

shenhuxi_yu的专栏 1407

[AbutionGraph] 报表制作-使用Grafana动态可视化知识图谱指标

使用开源报表可视化工具Grafana实时监控时序知识图谱数据仓库AbutionGraph中的数据,实时性报表查询, 满足单次百万千万级的数据查询,毫秒级查询延迟,亚秒级对千亿数据量汇总统计,每日过亿报表查询/多维分析/日志分析等数据指标...

图特摩斯科技-博客 4277

基于CNN对抗嵌入的图像隐写——CNN-Based Adversarial Embedding for Image Steganography

CNN-Based Adversarial Embedding for Image Steganography https://ieeexplore.ieee.org/abstract/document/8603808 这篇论文发表在TIFS( IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY),TIFS是网络与信息安全领域的国际两大顶级期刊之一,中国计算机学会(CCF)推荐的A类期刊,SCI一区TOP期刊,目前影响因子有7多了。 1 概

weixin_48654804的博客 2278

linux 系统调用

  系统调用  目 录 系统调用 系统调用简述 宏 系统调用表 系统调用入口函数

menuconfig的专栏 2015

CAN收发器TJA1145A休眠唤醒应用

TJA1145的唤醒工作原理主要依赖于其内部的唤醒机制和外部硬件的配合,主要涉及低功耗状态、选择性唤醒功能。TJA1145是一款CAN收发器,它支持多种工作模式,包括NormalStandbySleep等。在这些模式中,Sleep模式是最低功耗状态,而Normal模式则是最活跃的状态,其中Standby模式处于两者之间,允许一定的功能操作但功耗较低。TJA1145可以通过接收特定的唤醒源从Sleep或Standby模式唤醒到Standby或Normal模式。唤醒源的检测与处理。

radix关于mcu的博客,持续更新中... 5949

《图解Linux内核 基于6.x》学习导读

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨。

优快云站内信: https://i.youkuaiyun.com/#/msg/chat/qyj19920704 3万+

fins协议握手信号服务器响应,欧姆龙FinsTCP与FinsUDP协议解析 —— 利用Wireshark对报文逐字节进行解析详细解析附含报文模拟器等...

前言 – Fins欧姆龙这个协议网上极少有相关的模拟器、Tcp的这一块倒是有但是Udp的基本都是不可用1、 Fins协议结构也很简单 协议分为两种 一种tcp一种udp2、 Tcp比Udp的报文会多一层tcp的head头部3、 Udp回应报文在Wireshark中是解析不到(因为他按照UDP的格式去解那指定是解不到)好长时间没有更新过博客了、也比较懒= = 。一、Read(TCP)发包那么这个就很...

weixin_32491317的博客 4437

华为OD机试双机位C卷:采购订单 (Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 采购订单,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,并提供在线OJ模拟做题。华为OD机试真题【采购订单】

qq_45776114的博客 3534

全面解析Linux 内核 3.10.x - Device Tree 详解

From: 全面解析Linux 内核 3.10.x - 本文章完全基于MIPS架构 如果你觉得累,那么就继续吧 - 佚名一、Device Tree简介Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。在PPC 平台,已使用很长时间!.使用一种特殊语言来书写,通过Device Tree Compiler编译为Device Tree Blob.在Linux 2

何文的专栏 1万+

【100%通过率】华为od统一考试B卷【需要打开多少监视器】JAVA&Go 实现

某长方形停车场,每个车位上方都有对应监控器,当且仅当在当前车位或者前后左右四个方向任意一个车位范围停车时,监控器才需要打开:给出某一时刻停车场的停车分布,请统计最少需要打开多少个监控器

MISAYAONE的博客 1万+

全面解析Linux 内核 3.10.x - 内核进程

From: 全面解析Linux 内核 3.10.x - 进程管理 三千大世界,五千小世界,却是由生命组成 - XXXX进程类似于人类,它们被产生,有或多或少的有效生命。可以产生一个或者多个子进程,最终都要走向”死亡”。为什么说进程是操作系统的灵魂?因为它之于操作系统就犹如生命对于自然,犹如人之于家。一、透过现象看本质从用户程序的角度看,进程就是一次运行活动,是程序的执行实体! 从内核的角度看,进程

何文的专栏 2298

红队内网攻防渗透:内网渗透之内网对抗:实战项目&VPC1打靶&PHP-RCE&三层代理路由&防火墙上线&密码喷射&域控提权

上面已经抓取到了密码,但是我们通过拓扑分析看,要想上线win10只能通过正向shell,因为win7的防火墙是开的,win10反向主动连接肯定入站规则拦截,而win10自己没有开防火墙,所以win7主动正向连接就可以上线。win7开启了防火墙,入站规则肯定是会拦截我们的请求的,所以我们需要反向上线,让win7主动来连接我们。这里扫描发现是存在ms17010漏洞的,但是想上线192.168.2.142的话,我们没有路由是上线不了的,这里有两种办法:一种msf直接生成后门,另一种cs移植后门到msf。

HACKONE的博客 909

YOLOv7独家原创改进:多种新颖的改进方式 | 保持原始信息-深度可分离卷积(MDSConv) | 全局感受野的空间金字塔 (Improve-SPPF)算法 | CA注意力改进版

多种新颖的改进方式 | 保持原始信息-深度可分离卷积(MDSConv) | 全局感受野的空间金字塔 (Improve-SPPF)算法 | CA注意力改进版

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1666

linux 3.x内核系统调用表

本文列出了Linux 3.x内核(x86_64架构)的主要系统调用,涵盖了文件I/O、内存管理、信号处理等功能分类。核心系统调用包括文件操作(read/write/open/close)、内存管理(mmap/mprotect/munmap)、信号处理(sigaction/sigprocmask)等,每个调用都标注了内核函数名、用户接口名及功能说明。该清单综合了常见资源和内核源码信息,反映了3.x版本的普遍情况,但具体实现可能因小版本略有差异。

悟空看八戒烤熟了没的专栏c)4Upqt4SeVk 1490

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

全面解析Linux 内核 3.10.x - 内核入口函数__kernel_entry

From: 全面解析Linux 内核 3.10.x - 本文章完全基于MIPS架构 找对了入口,才有可能找对出口 – 佚名在前面几节内容中我简单将Linux ,以及Linux Kernel的概念做了总结,然后又将编译以及内核镜像也做了也总结! 从本节内容开始,我将真正的进入到内核代码中去!加油吧,Keven! 从上一节中我已经知道了vmlinux.lds链接文件中指定了内核的入口函数kernel_

何文的专栏 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

MAC OS X 技术内幕 学习笔记之三 MAC内核和LINUX内核的区别

MAC OS X 技术内幕 学习笔记之三 MAC内核和LINUX内核的区别 网上看到很多资料说 macOS 和 Linux 内核是很相近的东西,甚至有人说MAC OS就是linux的,因为它们可以处理类似的命令和类似的软件。其实是大错特错,事实上是,两个内核有着截然不同的历史和特征。 下面我们来看看macOS 和 Linux 的内核之间的区别。 一、起源和发展历史不同: m...

jyl_sh的专栏 2616

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

linux内核3.x升级至5.x

官方升级步骤 参考官方的升级步骤,实践了一下。 环境如下: [root@bogon src]# uname -sr Linux 3.10.0-862.el7.x86_64 从网上下载了linux-5.1.15.tar.xz,101M。提前准备好环境,确保根目录有足够的空间和足够的内存进行安装,空间大约11G,内存最少也得2G吧。本人失败了2次,一次根目录空间不足,一次内存不足,只能呵呵了。 其实...

运维狗的备忘录 2089

全面解析Linux 内核 3.10.x - 开始编译<一>

From: ongoingcre 一切手工技艺,皆由口传心授 - 夏奈尔首席鞋匠 1、内核编译体系 - Kbuild貌似是从2.6开始,内核编译就开始采用Kbuild体系! Kbuild几点观念: 1.一个配置文件对应一个自动包含的子目录树! 2.目标配置文件模板是简化Makefile的主要机制! 3.工具和SDK使得模板具有灵活性! 4.子Makefiles来实现非递归Makefile方

何文的专栏 8483

全面解析Linux 内核 3.10.x - start_kernel()

From: 全面解析Linux 内核 3.10.x - 本文章完全基于MIPS架构 赶得早,不如赶得巧 - 古语start_kernel前几年穿越题材很火爆,如神话,宫,步步惊心等,可是这些剧都有一些共性,那就是总是穿越到了过去! 为什么穿越一定要到过去呢?在我看来无非就是觉得回到过去题材丰富,因为在中国科幻题材很难火爆,题材有限!换言之就是,中国人总是喜欢活在过去,我祖上怎样怎样..我去年买了个表

何文的专栏 3281

S3C2440移植linux3.4.2内核之内核框架介绍及简单修改

uboot启动内核分析 进入cmd_bootm.c,找到对应的bootm命令对应的do_bootm(): int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { boot_os_fn *boot_fn; //boot_fn是个数组函数 ... .. boot_fn(0, argc...

嵌入式与Linux那些事的博客 2832

浅谈Linux内核页面换入换出

当检测是页面短缺时,根据某些规则挑选一些页面,调用refill_inactive_scan和swap_out,把活跃的页面变成不活跃脏的页面。2、把活跃的页面变成不活跃脏的页面。匿名映射当发生缺页中断时,也会调用do_no_page,然后调用do_anonymous_page,分配内页,建立映射,加入了活跃队列active_list。之后还会调用page_launder,把不活跃脏的页面变成不活跃干净的页面,从inactive_dirty队列移除,并加入到inactive_clean队列。

m0_74282605的博客 751
上一篇: Linux 3.x 内核学习笔记——x86 64位内存管理
下一篇: 写代码的目的
林 文
博客等级 码龄18年 14粉丝 29原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值