☰
page_alloc pcp_allowed_order
2026/10/7 15:22:59 网站建设 项目流程

判断某个阶数(order)的页是否允许走 PCP(Per-CPU Pages)缓存路径。它是 PCP 分配/释放入口的第一道"门槛"检查,用static inline强制内联。


一、函数签名

static inline bool pcp_allowed_order(unsigned int order)

参数

参数类型含义
orderunsigned int分配阶数(0 ~MAX_ORDER-1)

返回值

  • bool:true表示该阶数允许走 PCP 路径;false表示不允许,应直接走伙伴系统。

static inline

  • 文件内私有 + 强制内联。

  • 在rmqueue()、free_unref_page()等极热路径的入口调用,必须零开销。


二、背景:为什么 PCP 只允许低阶页?

  • PCP 缓存的是低阶页(order ≤PAGE_ALLOC_COSTLY_ORDER,通常为 3)。

  • 更高阶的页(order > 3)直接走伙伴系统,不进 PCP。

原因

1. 高阶页数量少、不"热"

  • 系统运行中,绝大多数分配是order 0(单页),少量是 order 1/2/3。

  • order ≥ 4 的分配("costly order")很少,缓存它们收益不大。

2. 缓存高阶页会浪费内存

  • PCP 是每个 CPU、每个 zone一份。

  • 如果缓存高阶页,一个 CPU 可能囤积几十上百页的大块,乘以 CPU 数 × zone 数,浪费巨大。

  • 低阶页缓存代价小(单页/几页),收益高。

3. 高阶页释放/合并复杂

  • 高阶页释放时涉及伙伴合并,走伙伴系统更自然。

  • 放进 PCP 再取出会打乱合并时机。

PAGE_ALLOC_COSTLY_ORDER

  • 内核常量,通常为3。

  • 含义:order > PAGE_ALLOC_COSTLY_ORDER的分配被视为"代价高(costly)",分配器会更谨慎、更努力避免失败。

  • PCP 允许的最大阶数就是PAGE_ALLOC_COSTLY_ORDER。


三、典型实现

static inline bool pcp_allowed_order(unsigned int order) { if (order <= PAGE_ALLOC_COSTLY_ORDER) return true; #ifdef CONFIG_PCP_BATCH_SCALE_MAX /* 某些配置下允许更大阶数走 PCP? */ #endif return false; }

或更简洁地:

static inline bool pcp_allowed_order(unsigned int order) { return order <= PAGE_ALLOC_COSTLY_ORDER; }

可能的变体

不同内核版本/配置下,实现可能略有差异:

1. 基础版本

return order <= PAGE_ALLOC_COSTLY_ORDER;
  • 最直接:order ≤ 3 允许,否则不允许。

2. 带配置的版本

  • 某些内核可能引入配置项,允许调整 PCP 支持的最大阶数。

  • 但主流实现就是order <= PAGE_ALLOC_COSTLY_ORDER。

3. 与MIGRATE_PCPTYPES配合

  • 除了阶数,PCP 还限制迁移类型(只缓存MIGRATE_PCPTYPES种)。

  • pcp_allowed_order()只管阶数,迁移类型的限制在order_to_pindex()里处理。

  • 两者共同决定"某次分配/释放能否走 PCP"。


四、调用场景

1. 分配路径:rmqueue()

static inline struct page *rmqueue(struct zone *zone, unsigned int order, ...) { if (likely(pcp_allowed_order(order))) { page = rmqueue_pcplist(zone, order, ...); // 走 PCP if (page) return page; } /* 否则走伙伴系统 */ return __rmqueue(zone, order, ...); }
  • 先判断阶数是否允许走 PCP;

  • 允许则尝试从 PCP 取页

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询