首页 / 资讯中心 / 文章详情

page_alloc __zone_set_pageset_high_and_batch

page_alloc __zone_set_pageset_high_and_batch ★ FEATURED ARTICLE
__zone_set_pageset_high_and_batch()是 PCPPer-CPU Pages缓存配置更新的批量执行函数负责将一个 zone 的新high_min、high_max和batch值分发到该 zone 的所有 CPU 的 PCP 结构上。核心实现static void __zone_set_pageset_high_and_batch(struct zone *zone, unsigned long high_min, unsigned long high_max, unsigned long batch) { struct per_cpu_pages *pcp; int cpu; for_each_possible_cpu(cpu) { pcp per_cpu_ptr(zone-per_cpu_pageset, cpu); pageset_update(pcp, high_min, high_max, batch); } }逐步解析1. 遍历所有可能的 CPUfor_each_possible_cpu(cpu)使用for_each_possible_cpu而非for_each_online_cpu确保所有可能上线的 CPU包括当前离线的都得到更新。这样当离线 CPU 上线时其 PCP 配置已经是正确的无需额外处理。2. 获取每个 CPU 的 PCP 指针pcp per_cpu_ptr(zone-per_cpu_pageset, cpu);zone-per_cpu_pageset是 per-CPU 变量的基址per_cpu_ptr()加上 CPU 偏移得到该 CPU 的struct per_cpu_pages地址。3. 调用pageset_update()写入pageset_update(pcp, high_min, high_max, batch);pageset_update()用WRITE_ONCE原子地写入三个字段。设计考量1. 为什么用for_each_possible_cpu而不是for_each_online_cpufor_each_online_cpu只遍历当前在线的 CPU会跳过离线 CPU。离线 CPU 的 PCP 结构仍然存在per_cpu_pageset数组为所有 possible CPU 分配了空间。如果跳过离线 CPU它们上线时会使用过期的配置需要额外的修正逻辑。用for_each_possible_cpu一次性更新所有简化了 CPU 热插拔的处理。2. 为什么不用锁pageset_update()内部用WRITE_ONCE保证单字段写入的原子性。这些字段是低频更新的只在 zone 初始化、CPU 热插拔、sysctl 修改时无需额外锁保护。并发读者即使读到旧值也只是暂时影响性能决策不影响正确性。3. 调用前提调用方必须已经持有pcp_batch_high_lock全局互斥锁/* prevent 1 _updater_ of zone percpu pageset -high and -batch fields */ static DEFINE_MUTEX(pcp_batch_high_lock);这确保同一时间只有一个更新者避免多个更新者并发修改导致配置不一致。在调用链中的位置zone_set_pageset_high_and_batch(zone, cpu_online) ├── new_batch max(1, zone_batchsize(zone)) ├── new_high_min / new_high_max zone_highsize(...) ├── 检查是否与当前值相同相同则返回 ├── zone-pageset_high_min new_high_min ├── zone-pageset_high_max new_high_max ├── zone-pageset_batch new_batch └── __zone_set_pageset_high_and_batch(zone, new_high_min, new_high_max, new_batch) // ← 这里 └── for_each_possible_cpu(cpu): pageset_update(pcp, high_min, high_max, batch)zone_set_pageset_high_and_batch()先计算新值、检查是否需要更新再调用本函数分发。调用场景zone 初始化setup_zone_pageset()为每个 zone 设置初始 PCP 配置CPU 热插拔CPU 上线/下线时重新分配 PCP 份额内存热插拔zone 大小变化时重新计算highsysctl 修改用户调整vm.percpu_pagelist_high_fraction时。总结__zone_set_pageset_high_and_batch()是 PCP 配置的批量分发器它遍历所有可能 CPU将 zone 的新high_min、high_max、batch值通过pageset_update()原子写入每个 CPU 的 PCP 结构。它使用for_each_possible_cpu确保离线 CPU 也能获得正确配置调用方必须持有pcp_batch_high_lock以保证更新的串行化。
阅读完成 · 觉得有帮助?
咨询建站