page_alloc node_states
全局节点状态数组和几个与分配相关的全局变量。它们是内核内存管理初始化阶段的基础设施。逐块拆解。一、node_states[NR_NODE_STATES]—— 节点状态数组nodemask_t node_states[NR_NODE_STATES] __read_mostly { [N_POSSIBLE] NODE_MASK_ALL, [N_ONLINE] { { [0] 1UL } }, #ifndef CONFIG_NUMA [N_NORMAL_MEMORY] { { [0] 1UL } }, #ifdef CONFIG_HIGHMEM [N_HIGH_MEMORY] { { [0] 1UL } }, #endif [N_MEMORY] { { [0] 1UL } }, [N_CPU] { { [0] 1UL } }, #endif /* NUMA */ }; EXPORT_SYMBOL(node_states);1. 类型nodemask_tnodemask_t是节点位图每个 bit 对应一个 NUMA 节点。类似于cpumask_t之于 CPUnodemask_t描述哪些节点属于某个集合。通常定义为struct { DECLARE_BITMAP(bits, MAX_NUMNODES); }。2. 数组维度NR_NODE_STATESnode_states[]是按状态索引的数组每个元素是一个节点位图表示处于该状态的节点集合。NR_NODE_STATES是状态总数状态枚举通常包括状态含义N_POSSIBLE系统可能存在的节点由固件/ACPI 报告N_ONLINE已经上线的节点N_NORMAL_MEMORY有普通内存ZONE_NORMAL的节点N_HIGH_MEMORY有高端内存ZONE_HIGHMEM的节点N_MEMORY有任何可管理内存的节点N_CPU有CPU的节点具体枚举在include/linux/nodemask.h。3. 初始化值[N_POSSIBLE] NODE_MASK_ALL,NODE_MASK_ALL所有位都置 1表示所有可能的节点都可能存在。这是最宽松的初始假设后续启动过程中根据实际探测收紧例如node_set_online()、node_set_state()。[N_ONLINE] { { [0] 1UL } },只把节点 0置位[0] 1UL表示位图第一个unsigned long的第 0 位为 1。即初始只有节点 0 在线。后续启动时内核探测到其他节点再逐个node_set_online()。4.#ifndef CONFIG_NUMA分支——非 NUMA 系统的简化在非 NUMA单节点系统上这些状态都指向节点 0[N_NORMAL_MEMORY] { { [0] 1UL } }, #ifdef CONFIG_HIGHMEM [N_HIGH_MEMORY] { { [0] 1UL } }, #endif [N_MEMORY] { { [0] 1UL } }, [N_CPU] { { [0] 1UL } },非 NUMA 下只有一个节点node 0所以有普通内存、有高端内存、有内存、有 CPU都指 node 0。CONFIG_HIGHMEM只在某些 32 位架构如 x86_32存在所以N_HIGH_MEMORY有条件编译。NUMA 系统下这些状态不在这里初始化而是在启动时根据实际拓扑用node_set_state()动态设置。5.__read_mostly告诉内核这个变量读多写少应放在.data..read_mostly段。好处与经常写的变量分开减少 cache line 伪共享提高读性能。节点状态确实如此启动时设置运行期几乎只读。6.EXPORT_SYMBOL(node_states)导出给模块模块可以用node_state(node, state)等宏查询。7. 典型使用/* 遍历所有在线节点 */ for_each_node_state(n, N_ONLINE) { ... } /* 遍历有内存的节点 */ for_each_node_state(n, N_MEMORY) { ... } /* 查询某节点是否有 CPU */ if (node_state(n, N_CPU)) { ... }分配器如__alloc_pages选择节点、zone 时会用到这些状态。二、gfp_allowed_mask—— 全局 GFP 允许掩码gfp_t gfp_allowed_mask __read_mostly GFP_BOOT_MASK;1. 作用一个全局的 GFP 标志掩码用于在启动阶段限制哪些 GFP 标志可用。分配时实际使用的标志会被gfp_allowed_mask按位与gfp gfp_allowed_mask;或类似逻辑确保不会使用当前阶段还不允许的标志。2. 为什么需要它启动早期很多子系统还没初始化好不能睡眠调度器/中断未就绪不能做内存回收kswapd/vmscan 未就绪不能做直接回收、规整、OOM 等。GFP_BOOT_MASK就是启动阶段允许的标志集合去掉那些依赖未就绪子系统的标志如__GFP_DIRECT_RECLAIM、__GFP_KSWAPD_RECLAIM、__GFP_NOFAIL等。随着初始化推进通过set_gfp_allowed_mask()逐步放宽最终变成GFP_KERNEL等完整标志。3. 典型流程/* 启动早期 */ gfp_allowed_mask GFP_BOOT_MASK; /* 某个初始化节点后放宽 */ set_gfp_allowed_mask(__GFP_DIRECT_RECLAIM | __GFP_KSWAPD_RECLAIM | ...);__read_mostly启动后基本只读。全局单一变量非 per-CPU。三、pageblock_order—— 可变页块阶数#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE unsigned int pageblock_order __read_mostly; #endif1. 什么是 pageblockpageblock是伙伴系统之上、用于反碎片anti-fragmentation的页块粒度。页块的迁移类型migratetype按 pageblock 设置set_pageblock_migratetype()。内存规整compaction、CMA 等也以 pageblock 为单位。2.pageblock_order的含义表示一个 pageblock 是2^pageblock_order 个页。默认!CONFIG_HUGETLB_PAGE_SIZE_VARIABLE通常是编译期常量#define pageblock_order min(HUGETLB_PAGE_ORDER, MAX_ORDER - 1)即取大页阶数和伙伴系统最大阶减一的较小值保证 pageblock 至少能容纳一个大页。3.CONFIG_HUGETLB_PAGE_SIZE_VARIABLE某些架构如PPC64支持多种大页尺寸大页的阶数在运行时才知道取决于实际配置/硬件。这时pageblock_order不能是编译期常量必须是一个运行期变量在启动时根据实际大页尺寸设定。所以该配置开启时pageblock_order被定义为unsigned int __read_mostly而非宏。4.__read_mostly启动时确定运行期只读。与node_states、gfp_allowed_mask一样放在 read-mostly 段。5. 典型使用/* 一个 pageblock 的页数 */ 1UL pageblock_order /* 计算 PFN 所属 pageblock 的起始 PFN */ pfn ~((1UL pageblock_order) - 1) /* 判断是否对齐到 pageblock */ IS_ALIGNED(pfn, 1 pageblock_order)四、三个变量的共性变量类型作用写入时机node_statesnodemask_t[]各状态下的节点集合启动初始化 热插拔gfp_allowed_maskgfp_t启动阶段允许的 GFP 标志启动逐步放宽pageblock_orderunsigned int条件pageblock 的阶数启动根据大页尺寸设定共同点都是全局、启动时确定、运行期几乎只读都用__read_mostlynode_states显式标注另两个也是都服务于分配器的初始化与约束。五、小结代码含义node_states[NR_NODE_STATES]按状态索引的节点位图数组描述哪些节点可能/在线/有内存/有 CPUN_POSSIBLE NODE_MASK_ALL初始假设所有节点都可能存在N_ONLINE {[0]1}初始只有节点 0 在线#ifndef CONFIG_NUMA分支非 NUMA 下所有状态都指向节点 0EXPORT_SYMBOL(node_states)导出给模块gfp_allowed_mask启动阶段允许的 GFP 标志掩码初始GFP_BOOT_MASK逐步放宽pageblock_order条件大页尺寸可变时的 pageblock 阶数运行期变量而非宏一句话总结node_states以位图数组形式记录各状态下可能/在线/有内存/有 CPU的 NUMA 节点集合初始只让节点 0 在线、其余按启动探测填充gfp_allowed_mask在启动早期限制可用 GFP 标志并随初始化逐步放宽pageblock_order在大页尺寸可变的架构上是运行期变量决定 pageblock 的阶数——三者都是启动确定、运行期只读的分配器基础设施。

相关新闻

小白程序员轻松入门:如何本地运行并部署 Agent 大模型(附5条生产合同)|TaoToken 统一 Key 接入实践

小白程序员轻松入门:如何本地运行并部署 Agent 大模型(附5条生产合同)|TaoToken 统一 Key 接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 19:59:25 阅读更多 →
AI写论文软件怎么选?合规与专业度是关键

AI写论文软件怎么选?合规与专业度是关键

1. 别急着选工具,先定义“最好”:论文AI的合规范式与专业底线每年一到毕业季,“AI 写论文哪个软件最好?”这句话就像复读机一样,在论文互助群里反复出现。问这个问题的人,通常有两种:一种是被通…

2026/10/5 19:59:25 阅读更多 →
深度解读Work Agent长程任务的中间结果校验与迭代机制

深度解读Work Agent长程任务的中间结果校验与迭代机制

AI技术落地的前几年,大众对智能工具的普遍认知还停留在单轮问答的交互形态,用户输入明确指令后获得对应反馈,交互链路短、输出结果的边界清晰。随着大模型上下文理解能力的快速提升,多轮对话形态逐步普及,AI可以承接更…

2026/10/5 19:59:25 阅读更多 →

最新新闻

【笔记】codex+deepseek用ccswitch,支持插件:把settings改到TaoToken

【笔记】codex+deepseek用ccswitch,支持插件:把settings改到TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 20:37:48 阅读更多 →
MRAM工业存储实战:MR25H40CDF与PIC18F86K90的SPI驱动与掉电保护设计

MRAM工业存储实战:MR25H40CDF与PIC18F86K90的SPI驱动与掉电保护设计

MRAM 这东西,我第一次在项目里用的时候,心里是打鼓的。EEPROM 和 Flash 用了十几年,突然换一种"非易失但写起来像 SRAM"的存储器,总担心哪里藏着坑。后来在一个工业数据采集板上,用 MR25H40CDF 配 PIC18F86K…

2026/10/5 20:37:47 阅读更多 →
深度解析 Qwen3.6-35B-A3B:重塑 AI 编程代理的开源新标杆与 TaoToken 统一接入实践

深度解析 Qwen3.6-35B-A3B:重塑 AI 编程代理的开源新标杆与 TaoToken 统一接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 20:36:47 阅读更多 →
vscode插件之local history - 工具篇:把本地历史记录改到 TaoToken 统一管理

vscode插件之local history - 工具篇:把本地历史记录改到 TaoToken 统一管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 20:35:46 阅读更多 →
Elastic 基于 Agentic 架构与 MCP 的 Kubernetes 智能可观测性深度解析:把 Elasticsearch endpoint 改到 TaoToken

Elastic 基于 Agentic 架构与 MCP 的 Kubernetes 智能可观测性深度解析:把 Elasticsearch endpoint 改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 20:35:46 阅读更多 →
从2节点到8节点集群:spark-vllm-docker的DGX Spark组网拓扑完全指南(直连、3节点Mesh、交换机)

从2节点到8节点集群:spark-vllm-docker的DGX Spark组网拓扑完全指南(直连、3节点Mesh、交换机)

从2节点到8节点集群:spark-vllm-docker的DGX Spark组网拓扑完全指南(直连、3节点Mesh、交换机) 【免费下载链接】spark-vllm-docker Docker configuration for running VLLM on dual DGX Sparks 项目地址: https://gitcode.com/gh_mirrors/…

2026/10/5 20:33:45 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 20:14:29 阅读更多 →