Linux 内核内存管理 pfn_to_online_page宏
文章目录
- 一、Memory Hotplug
- 1.1 简介
- 1.2 热插拔事件通知机制
- 二、pfn_to_online_page
- 2.1 pfn_to_online_page
- 2.2 pfn_to_section_nr
- 2.3 online_section_nr
- 参考资料
一、Memory Hotplug
1.1 简介
Linux 内存热插拔(Memory Hotplug)是指在运行时动态增加或移除物理内存模块,而不需要重新启动系统。这个功能允许管理员根据系统需要增加或减少内存容量,以满足应用程序的需求或进行硬件维护。
内存热插拔在服务器环境中尤为重要,因为它允许在不中断系统运行的情况下灵活地管理内存资源。
Linux 内核提供了内存热插拔的支持,具体包括以下方面:
(1)内存热插拔事件检测:内核通过硬件或固件接口检测到内存模块的插入或移除事件。这些事件通常通过总线、ACPI(高级配置与电源接口)或其他平台特定的机制进行通知。
(2)内存热插拔事件处理:一旦内核检测到内存插入或移除事件,它会启动相应的处理过程。这包括检测新插入的内存模块的属性和容量,并相应地更新内核的内存管理数据结构。
(3)内存段管理:内核将物理内存划分为多个内存段,每个内存段包含一定数量的物理页框。内存热插拔过程中,内核会根据内存模块的插入或移除来更新内存段的映射关系。
(4)内存热插拔事件通知:内核通过系统事件通知机制(如UEVENT)或文件系统接口(如/sys/devices/system/memory)向用户空间发送内存热插拔事件的通知。
(5)内存管理:内核通过内存热插拔支持可以动态地分配和释放新增的内存容量。这使得系统可以根据需要动态调整内存资源的分配,以提高性能和灵活性。
Linux 内存热插拔支持允许在运行时动态增加或移除物理内存模块,通过更新内核的内存管理数据结构和内存段映射关系,实现对内存资源的动态管理,并提供相应的事件通知机制,以便用户空间和应用程序可以响应内存热插拔事件。
1.2 热插拔事件通知机制
在 Linux 中,内存热插拔事件通知是通过以下机制之一向用户空间发送的:
(1)UEVENT:UEVENT 是 Linux 内核中一种通用的事件传递机制,用于向用户空间发送设备相关事件。内存热插拔事件通常以 UEVENT 的形式发送。当内核检测到内存插入或移除事件时,会生成相应的 UEVENT 消息,并通过 netlink 接口将该消息发送到用户空间。用户空间可以通过监听 netlink socket,并解析收到的 UEVENT 消息来获取内存热插拔事件相关的信息。
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
NETLINK_KOBJECT_UEVENT:提供内核广播 uevent 的接口,通常由 udev 使用,是内核通用模型向用户层发送信息所采用的协议(内核热插拔机制的基础)。
(2)sysfs 文件系统接口:Linux 内核提供了 sysfs 文件系统,其中包含了设备、驱动程序和其他内核对象的信息。对于内存热插拔事件,内核会在 sysfs 文件系统中相应的目录下创建或删除相应的文件或目录节点来表示内存的插入或移除。用户空间可以通过监视 sysfs 文件系统中相应的路径并检测文件或目录的创建或删除来获取内存热插拔事件的通知。
内存热插拔事件相关的信息通常位于 /sys/devices/system/memory 目录下。
这些机制提供了不同的接口和方式,供用户空间应用程序或守护进程监听和接收内存热插拔事件的通知。用户空间可以根据具体的需求选择适合的机制来接收和处理内存热插拔事件。
二、pfn_to_online_page
2.1 pfn_to_online_page
通常 pfn与 struct page 之间的转化都是 pfn_to_page 宏,这里介绍下pfn_to_online_page 宏。
# cat /boot/config-4.19.90-23.8.v2101.ky10.x86_64 | grep CONFIG_MEMORY_HOTPLUG
CONFIG_MEMORY_HOTPLUG=y
// linux-4.19.90/include/linux/memory_hotplug.h#ifdef CONFIG_MEMORY_HOTPLUG
/** Return page for the valid pfn only if the page is online. All pfn* walkers which rely on the fully initialized page->flags and others* should use this rather than pfn_valid && pfn_to_page*/
#define pfn_to_online_page(pfn) \
({ \struct page *___page = NULL; \unsigned long ___pfn = pfn; \unsigned long ___nr = pfn_to_section_nr(___pfn); \\if (___nr < NR_MEM_SECTIONS && online_section_nr(___nr) && \pfn_valid_within(___pfn)) \___page = pfn_to_page(___pfn); \___page; \
})
pfn_to_online_page用于获取 online 的 struct page 。
宏定义的实现逻辑如下:
(1)使用pfn_to_section_nr宏将___pfn转换为对应的内存段号(section number)。内存段是物理内存的分段单位。
(2)过online_section_nr函数判断内存段号___nr是否在线(online)。online_section_nr函数用于检查指定内存段号是否为在线状态。
(3)如果内存段号___nr小于总内存段数(NR_MEM_SECTIONS)并且该内存段号在线,并且___pfn在有效范围内(通过pfn_valid_within宏判断),则执行下面的代码块。
(4)在代码块中,通过pfn_to_page宏将___pfn转换为对应的struct page指针。
2.2 pfn_to_section_nr
// linux-4.19.90/include/linux/mmzone.h/* PFN_SECTION_SHIFT pfn to/from section number */
#define PFN_SECTION_SHIFT (SECTION_SIZE_BITS - PAGE_SHIFT)static inline unsigned long pfn_to_section_nr(unsigned long pfn)
{return pfn >> PFN_SECTION_SHIFT;
}
函数的实现逻辑非常简单,它使用位移操作符(>>)将物理页框号右移 PFN_SECTION_SHIFT 位,然后返回结果作为内存段号。
PFN_SECTION_SHIFT 是一个宏定义,表示物理页框号和内存段号之间的位移量。这个值是根据系统的物理内存布局和内存段的大小来确定的。
通过这个函数,可以将物理页框号转换为对应的内存段号,从而在内核中进行内存段相关的操作和管理。
备注:内存热插拔(Memory Hotplug):内存热插拔是指在运行时动态增加或移除物理内存模块。内核使用内存段号来管理和跟踪物理内存的热插拔操作。通过将物理页框号转换为对应的内存段号,内核可以准确地定位和操作要插入或移除的物理内存段。
其对应还有一个函数:
static inline unsigned long section_nr_to_pfn(unsigned long sec)
{return sec << PFN_SECTION_SHIFT;
}
2.3 online_section_nr
static inline int online_section(struct mem_section *section)
{return (section && (section->section_mem_map & SECTION_IS_ONLINE));
}static inline int online_section_nr(unsigned long nr)
{return online_section(__nr_to_section(nr));
}
(1)
online_section该函数接受一个指向 struct mem_section 结构体的指针 section,表示要检查的内存段。struct mem_section 是内核中用于表示物理内存段的数据结构。SECTION_IS_ONLINE 是一个标志位,表示内存段是否在线的标识。
函数的作用是检查给定的内存段是否有效且在线。通过检查 section 是否为非空指针,并且检查 section->section_mem_map 中的 SECTION_IS_ONLINE 标志位,来确定内存段是否在线。如果内存段有效且在线,则返回非零值,否则返回零。
(2)
online_section_nr函数接受一个无符号长整型参数 nr,表示要检查的内存段号。__nr_to_section(nr) 是一个宏定义,用于将内存段号转换为对应的内存段结构体(struct mem_section)指针。
函数的作用是通过调用 online_section 函数,检查给定内存段号对应的内存段是否在线。它将内存段号转换为对应的内存段结构体指针,并将该指针作为参数传递给 online_section 函数进行检查。
参考资料
Linux 4.19.90
相关文章:
Linux 内核内存管理 pfn_to_online_page宏
文章目录 一、Memory Hotplug1.1 简介1.2 热插拔事件通知机制 二、pfn_to_online_page2.1 pfn_to_online_page2.2 pfn_to_section_nr2.3 online_section_nr 参考资料 一、Memory Hotplug 1.1 简介 Linux 内存热插拔(Memory Hotplug)是指在运行时动态增…...
『C语言初阶』第八章 -结构体
前言 今天小羊又来给铁汁们分享关于C语言的结构体,在C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型),今天我们主要简单了解一下结构体。 一、结构体是什么&#x…...
chatgpt汇编,两个关于chatgpt的问题
1.用C写一个高级的可自主学习的AI语言模型 编写一个高级的可自主学习的AI语言模型是一个复杂且庞大的工程,需要深入的专业知识和大量的时间精力。下面是一个简化的示例,演示如何使用C实现一个基本的可自主学习的AI语言模型。 首先,你需要定…...
ps丢失d3dcompiler_47.dll怎么办,启动无反应,分享三个解决方法
d3dcompiler_47.dll64位是windows系统中重要的dll文件,缺少了它可能会引起部分软件或者游戏不能运行。 如果系统出现“找不到d3dcompiler_47.dll”或“d3dcompiler_47.dll丢失”等错误信息,那么我们就该着手修复它。 先带了解一下d3dcompiler_47.dll是什…...
第三章nginx详解
nginx:高性能,轻量级的web服务软件。 特点: 1,稳定性高。(没有apache稳定) 2,系统资源消耗地较低。(处理http请求的并发能力非常高,单台物理服务器可以处理30000-5000…...
【二叉树前沿篇】树
【二叉树前沿篇】树 1 树的概念2. 树的相关概念3. 树的表示4. 树在实际中的运用(表示文件系统的目录树结构) 1 树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是…...
python3 0基础学习----数据结构(基础+练习)
python 0基础学习笔记之数据结构 📚 几种常见数据结构列表 (List)1. 定义2. 实例:3. 列表中常用方法.append(要添加内容) 向列表末尾添加数据.extend(列表) 将可迭代对象逐个添加到列表中.insert(索引,插入内容) 向指定…...
计算机科学中的“旅行商问题”
题目:旅行商问题(Traveling Salesman Problem) 当初为何收藏:我收藏了这个题目是因为它是一个经典而富有挑战性的组合优化问题,涉及到计算机科学、算法设计和实际应用领域。我认为这个问题可以展示出算法设计的重要性…...
QT:自定义控件(Connect使用,子控件连接)
自定义控件封装: 1.添加新文件(设计师界面类),创建子页面 ,放自己想要的控件 2.在主页面中使用子控件 :新建一个widget- ISO21434 组织网络安全管理(二) ISO21434 项目网络安全管理(三) ISO21434 分布式网络安全(四) SO21434 持续进行的网络安全(五) ISO21434 概念阶段网络安全(六)...
Visual Studio 如何放大代码字体的大小
1.打开Visual Studio,新建一个程序,一段代码,为接下去的操作做好准备。单击菜单栏的【工具】选项。 2.在跳出来菜单中找到【选项】(一般在最后一项),然后单击。跳出新的窗口。 3.跳出新的窗口后ÿ…...
Verilog同步FIFO设计
同步FIFO(synchronous)的写时钟和读时钟为同一个时钟,FIFO内部所有逻辑都是同步逻辑,常常用于交互数据缓冲。 异步FIFO:数据写入FIFO的时钟和数据读出FIFO的时钟是异步的(asynchronous) 典型同步FIFO有三部分组成: (1࿰…...
Php“牵手”lazada商品详情页数据采集方法,lazadaAPI接口申请指南
lazada详情接口 API 是开放平台提供的一种 API 接口,它可以帮助开发者获取商品的详细信息,包括商品的标题、描述、图片等信息。在电商平台的开发中,详情接口API是非常常用的 API,因此本文将详细介绍详情接口 API 的使用。 一、la…...
Sentinel 规则持久化
文章目录 Sentinel 规则持久化一、修改order-service服务1.引入依赖2.配置nacos地址 第二步修改非常麻烦,可以略过,直接使用已经打好包的来使用二、修改sentinel-dashboard源码1. 解压2. 修改nacos依赖3. 添加nacos支持4. 修改nacos地址5. 配置nacos数据…...
元宇宙时代超高清视音频技术白皮书关于流媒体协议和媒体传输解读
流媒体协议 元宇宙业务场景对流媒体传输的实时性和互动性提出了更高的要求,这就需要在传统的 RTMP、SRT、 HLS 等基础上增加实时互动的支持。实时互动,指在远程条件下沟通、协作,可随时随地接入、实时地传递虚实融合的多维信息,身…...
【计算机设计大赛】国赛一等奖项目分享——基于多端融合的化工安全生产监管可视化系统
文章目录 一、计算机设计大赛国赛一等奖二、项目背景三、项目简介四、系统架构五、系统功能结构六、项目特色(1)多端融合(2)数据可视化(3)计算机视觉(目标检测) 七、系统界面设计&am…...
深入理解【二叉树】
📙作者简介: 清水加冰,目前大二在读,正在学习C/C、Python、操作系统、数据库等。 📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 👍…...
RequestRespons
文章目录 Request&Respons1 Request和Response的概述2 Request对象2.1 Request继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数的通用方式 2.3 IDEA快速创建Servlet2.4 请求参数中文乱码问题2.4.1 POST请…...
UniApp 使用命令创建页面的详细指南
系列文章目录 文章目录 系列文章目录前言一、安装Uni-CLI二、创建页面三、页面创建命令四、页面结构五、页面使用总结 前言 UniApp是一款跨平台的前端框架,可以用于开发同时运行在多个平台(如微信小程序、H5、App等)的应用程序。本文将详细介…...
Opencv 图像的读取与写入
目录 导入cv2 读取图像数据 创建一个窗口 waitKey方法 关闭所有窗口 完整示例 保存图片 示例 导入cv2 # 导入opencv包 import cv2 读取图像数据 cv2.imread(path, flag) 参数说明: path:要读取的图像文件的路径。 flag(可选&#…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
