当前位置: 首页 > news >正文

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 内存热插拔&#xff08;Memory Hotplug&#xff09;是指在运行时动态增…...

『C语言初阶』第八章 -结构体

前言 今天小羊又来给铁汁们分享关于C语言的结构体&#xff0c;在C语言中&#xff0c;结构体类型属于一种构造类型&#xff08;其他的构造类型还有&#xff1a;数组类型&#xff0c;联合类型&#xff09;&#xff0c;今天我们主要简单了解一下结构体。 一、结构体是什么&#x…...

chatgpt汇编,两个关于chatgpt的问题

1.用C写一个高级的可自主学习的AI语言模型 编写一个高级的可自主学习的AI语言模型是一个复杂且庞大的工程&#xff0c;需要深入的专业知识和大量的时间精力。下面是一个简化的示例&#xff0c;演示如何使用C实现一个基本的可自主学习的AI语言模型。 首先&#xff0c;你需要定…...

ps丢失d3dcompiler_47.dll怎么办,启动无反应,分享三个解决方法

d3dcompiler_47.dll64位是windows系统中重要的dll文件&#xff0c;缺少了它可能会引起部分软件或者游戏不能运行。 如果系统出现“找不到d3dcompiler_47.dll”或“d3dcompiler_47.dll丢失”等错误信息&#xff0c;那么我们就该着手修复它。 先带了解一下d3dcompiler_47.dll是什…...

第三章nginx详解

nginx&#xff1a;高性能&#xff0c;轻量级的web服务软件。 特点&#xff1a; 1&#xff0c;稳定性高。&#xff08;没有apache稳定&#xff09; 2&#xff0c;系统资源消耗地较低。&#xff08;处理http请求的并发能力非常高&#xff0c;单台物理服务器可以处理30000-5000…...

【二叉树前沿篇】树

【二叉树前沿篇】树 1 树的概念2. 树的相关概念3. 树的表示4. 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 1 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是…...

python3 0基础学习----数据结构(基础+练习)

python 0基础学习笔记之数据结构 &#x1f4da; 几种常见数据结构列表 &#xff08;List&#xff09;1. 定义2. 实例&#xff1a;3. 列表中常用方法.append(要添加内容) 向列表末尾添加数据.extend(列表) 将可迭代对象逐个添加到列表中.insert(索引&#xff0c;插入内容) 向指定…...

计算机科学中的“旅行商问题”

题目&#xff1a;旅行商问题&#xff08;Traveling Salesman Problem&#xff09; 当初为何收藏&#xff1a;我收藏了这个题目是因为它是一个经典而富有挑战性的组合优化问题&#xff0c;涉及到计算机科学、算法设计和实际应用领域。我认为这个问题可以展示出算法设计的重要性…...

QT:自定义控件(Connect使用,子控件连接)

自定义控件封装&#xff1a; 1.添加新文件&#xff08;设计师界面类&#xff09;&#xff0c;创建子页面 &#xff0c;放自己想要的控件 2.在主页面中使用子控件 :新建一个widget-![在这里插入图片描述](https://img-blog.csdnimg.cn/95ed8015343e4c56a3914853950eff4c.png#pi…...

目录——车载网络安全

本文主要汇总车载网络安全专栏文章,以方便各位读者阅读。 ISO21434 概述(一) ISO21434 组织网络安全管理(二) ISO21434 项目网络安全管理(三) ISO21434 分布式网络安全(四) SO21434 持续进行的网络安全(五) ISO21434 概念阶段网络安全(六)...

Visual Studio 如何放大代码字体的大小

1.打开Visual Studio&#xff0c;新建一个程序&#xff0c;一段代码&#xff0c;为接下去的操作做好准备。单击菜单栏的【工具】选项。 2.在跳出来菜单中找到【选项】&#xff08;一般在最后一项&#xff09;&#xff0c;然后单击。跳出新的窗口。 3.跳出新的窗口后&#xff…...

Verilog同步FIFO设计

同步FIFO(synchronous)的写时钟和读时钟为同一个时钟&#xff0c;FIFO内部所有逻辑都是同步逻辑&#xff0c;常常用于交互数据缓冲。 异步FIFO&#xff1a;数据写入FIFO的时钟和数据读出FIFO的时钟是异步的(asynchronous) 典型同步FIFO有三部分组成: &#xff08;1&#xff0…...

Php“牵手”lazada商品详情页数据采集方法,lazadaAPI接口申请指南

lazada详情接口 API 是开放平台提供的一种 API 接口&#xff0c;它可以帮助开发者获取商品的详细信息&#xff0c;包括商品的标题、描述、图片等信息。在电商平台的开发中&#xff0c;详情接口API是非常常用的 API&#xff0c;因此本文将详细介绍详情接口 API 的使用。 一、la…...

Sentinel 规则持久化

文章目录 Sentinel 规则持久化一、修改order-service服务1.引入依赖2.配置nacos地址 第二步修改非常麻烦&#xff0c;可以略过&#xff0c;直接使用已经打好包的来使用二、修改sentinel-dashboard源码1. 解压2. 修改nacos依赖3. 添加nacos支持4. 修改nacos地址5. 配置nacos数据…...

元宇宙时代超高清视音频技术白皮书关于流媒体协议和媒体传输解读

流媒体协议 元宇宙业务场景对流媒体传输的实时性和互动性提出了更高的要求&#xff0c;这就需要在传统的 RTMP、SRT、 HLS 等基础上增加实时互动的支持。实时互动&#xff0c;指在远程条件下沟通、协作&#xff0c;可随时随地接入、实时地传递虚实融合的多维信息&#xff0c;身…...

【计算机设计大赛】国赛一等奖项目分享——基于多端融合的化工安全生产监管可视化系统

文章目录 一、计算机设计大赛国赛一等奖二、项目背景三、项目简介四、系统架构五、系统功能结构六、项目特色&#xff08;1&#xff09;多端融合&#xff08;2&#xff09;数据可视化&#xff08;3&#xff09;计算机视觉&#xff08;目标检测&#xff09; 七、系统界面设计&am…...

深入理解【二叉树】

&#x1f4d9;作者简介&#xff1a; 清水加冰&#xff0c;目前大二在读&#xff0c;正在学习C/C、Python、操作系统、数据库等。 &#x1f4d8;相关专栏&#xff1a;C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…...

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是一款跨平台的前端框架&#xff0c;可以用于开发同时运行在多个平台&#xff08;如微信小程序、H5、App等&#xff09;的应用程序。本文将详细介…...

Opencv 图像的读取与写入

目录 导入cv2 读取图像数据 创建一个窗口 waitKey方法 关闭所有窗口 完整示例 保存图片 示例 导入cv2 # 导入opencv包 import cv2 读取图像数据 cv2.imread(path, flag) 参数说明&#xff1a; path&#xff1a;要读取的图像文件的路径。 flag&#xff08;可选&#…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...