【内存管理】6.6内核 - Vmalloc机制 - __purge_vmap_area_lazy
这段代码的作用是 根据当前延迟释放的 vmap 区域数量,动态计算需要启动的 helper 线程数量(nr_purge_helpers
),并确保该数量不超过系统可用的处理节点数(nr_purge_nodes
)。以下是逐行解析:
1. 代码逻辑解析
第 2283 行:计算初步的 helper 数量
nr_purge_helpers = atomic_long_read(&vmap_lazy_nr) / lazy_max_pages();
vmap_lazy_nr
:
一个atomic_long_t
类型的变量,记录当前延迟释放的vmap_area
数量(即未被合并或插入空闲链表的 VA 区域数量)。lazy_max_pages()
:
返回每个 helper 线程能够处理的最大页面数(即每个 helper 能处理的vmap_area
的最大数量)。- 例如,若每个 helper 最多处理 100 个页面,则
lazy_max_pages()
返回 100。
- 例如,若每个 helper 最多处理 100 个页面,则
atomic_long_read()
:
原子读取vmap_lazy_nr
的值,确保多线程环境下的线程安全。/
操作:
计算需要多少个 helper 线程来处理所有延迟释放的vmap_area
。- 例如,若
vmap_lazy_nr = 500
且lazy_max_pages() = 100
,则500 / 100 = 5
,表示需要 5 个 helper。
- 例如,若
第 2284 行:限制 helper 数量并调整
nr_purge_helpers = clamp(nr_purge_helpers, 1U, nr_purge_nodes) - 1;
clamp(nr_purge_helpers, 1U, nr_purge_nodes)
:
将nr_purge_helpers
限制在[1, nr_purge_nodes]
范围内。- 若计算出的
nr_purge_helpers
超过nr_purge_nodes
,则取nr_purge_nodes
。 - 若小于 1,则取 1(确保至少有一个 helper)。
- 若计算出的
- 1
:
最终结果减去 1,可能是为了 预留一个 helper 作为备用或协调者。- 例如,若
nr_purge_helpers = 5
且nr_purge_nodes = 4
,则clamp(5, 1, 4) = 4
,再减 1 得到 3 helper。
- 例如,若
2. 注释解释
/* One extra worker is per a lazy_max_pages() full set minus one. */
- 注释含义:
每个满的lazy_max_pages()
页面集合需要一个额外的 worker(helper 线程),但最终减去 1。- 例如,若
lazy_max_pages()
表示每个 helper 能处理 100 个页面,而vmap_lazy_nr
有 150 个页面,则需要 2 个 helper(100 + 50)。但通过clamp
和-1
调整后,可能只启动 1 个 helper,避免过度分配。
- 例如,若
3. 关键变量和函数
(1) vmap_lazy_nr
- 作用:
跟踪当前延迟释放的vmap_area
数量。- 在
__merge_or_add_vmap_area
中,当vmap_area
被释放但未合并时,会增加vmap_lazy_nr
。
- 在
- 原子操作:
使用atomic_long_read()
和atomic_long_inc()
确保并发安全。
(2) lazy_max_pages()
- 实现逻辑:
可能基于系统配置或动态计算,例如:static inline unsigned long lazy_max_pages(void) {return max(1UL, (unsigned long)global_zone_page_state(NR_FREE_PAGES) / 10); }
- 每个 helper 处理的页面数与系统空闲内存成正比。
(3) nr_purge_nodes
- 来源:
通常由cpumask_weight(&purge_nodes)
统计,表示可用的 CPU 核心数或工作队列节点数。- 例如,
nr_purge_nodes = 4
表示最多启动 4 个 helper。
- 例如,
4. 典型应用场景
- 延迟释放的 vmap 区域处理
- 当
vmalloc()
/vfree()
频繁调用时,vmap_lazy_nr
会增加,触发更多 helper 线程清理延迟释放的区域。
- 当
- 动态负载均衡
- 根据系统负载(
vmap_lazy_nr
和lazy_max_pages()
)动态调整 helper 数量,避免资源浪费或不足。
- 根据系统负载(
- 多核并行处理
- 利用
nr_purge_nodes
控制 helper 数量,确保多核 CPU 的并行处理效率。
- 利用
5. 示例分析
假设:
vmap_lazy_nr = 300
(300 个延迟释放的vmap_area
)lazy_max_pages() = 100
(每个 helper 处理 100 个)nr_purge_nodes = 4
(4 个可用节点)
计算过程:
nr_purge_helpers = 300 / 100 = 3;
nr_purge_helpers = clamp(3, 1, 4) - 1 = 3 - 1 = 2;
- 结果:启动 2 个 helper 线程处理 300 个
vmap_area
。
6. 总结
这段代码的核心逻辑是 根据延迟释放的 vmap 区域数量和系统负载,动态计算并限制 helper 线程数量,以实现高效的内存管理。通过原子操作、动态调整和并发控制,确保内核在高负载下仍能高效处理虚拟地址映射的合并与释放。