news 2026/10/11 6:57:39

page_alloc rmqueue_pcplist

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
page_alloc rmqueue_pcplist

rmqueue_pcplist()是 PCP(Per-CPU Pages)缓存分配路径的锁封装入口,负责在持有 PCP 锁的前提下,从当前 CPU 的 PCP 链表中取出一个页块。

核心作用与定位

它是__rmqueue_pcplist()的外层封装。两者的分工非常明确:

函数职责
rmqueue_pcplist()获取 PCP 锁、计算链表指针、调用__rmqueue_pcplist()、释放锁
__rmqueue_pcplist()在持锁状态下执行实际的取页逻辑

核心逻辑

static struct page *rmqueue_pcplist(struct zone *preferred_zone, struct zone *zone, unsigned int order, int migratetype, unsigned int alloc_flags) { struct per_cpu_pages *pcp; struct list_head *list; struct page *page; unsigned long flags; /* 1. 获取当前 CPU 的 PCP 结构 */ pcp = pcp_spin_lock_irqsave(zone->per_cpu_pageset); /* 2. 计算目标链表指针 */ list = &pcp->lists[order_to_pindex(migratetype, order)]; /* 3. 调用内部函数取页 */ page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list); /* 4. 释放 PCP 锁 */ pcp_spin_unlock_irqrestore(pcp, flags); return page; }

逐步说明

1. 获取 PCP 锁

pcp = pcp_spin_lock_irqsave(zone->per_cpu_pageset);
  • pcp_spin_lock系列:先pcpu_task_pin()禁止迁移,再this_cpu_ptr()定位当前 CPU 的 PCP,最后加锁。

  • 用irqsave版本同时保存中断状态,防止中断重入。

2. 计算目标链表

list = &pcp->lists[order_to_pindex(migratetype, order)];
  • order_to_pindex():把(migratetype, order)编码成 PCP 链表数组的扁平索引。

3. 调用内部函数

page = __rmqueue_pcplist(zone, order, migratetype, alloc_flags, pcp, list);
  • __rmqueue_pcplist():链表空则批量补充,否则从头部取页,并做坏页重试。

4. 释放 PCP 锁

pcp_spin_unlock_irqrestore(pcp, flags);
  • 解锁并恢复中断状态(pcp_spin_unlock+local_irq_restore)。

在分配路径中的位置

它是rmqueue()的首选路径:

rmqueue(preferred_zone, zone, order, gfp_flags, migratetype, alloc_flags) ├── if (pcp_allowed_order(order)) { │ page = rmqueue_pcplist(preferred_zone, zone, order, migratetype, alloc_flags); │ if (page) { │ zone_statistics(preferred_zone, zone, 1); │ return page; │ } │ } └── page = rmqueue_buddy(preferred_zone, zone, order, alloc_flags, migratetype);

关于alloc_flags参数

虽然rmqueue_pcplist()接收alloc_flags并传递给__rmqueue_pcplist(),但__rmqueue_pcplist()本身并不直接使用它——它只负责从 PCP 链表取页。alloc_flags的实际用途在批量补充时:rmqueue_bulk()会把它传给__rmqueue(),影响伙伴系统的 fallback 策略(如ALLOC_NOFRAGMENT控制是否允许从低阶偷页)。

与pcp_allowed_order()的关系

rmqueue()在调用rmqueue_pcplist()之前会先用pcp_allowed_order(order)检查阶数是否允许走 PCP。只有order <= PAGE_ALLOC_COSTLY_ORDER(通常为 3)的请求才会进入 PCP 路径,更高阶的请求直接走rmqueue_buddy()。

总结

rmqueue_pcplist()是 PCP 分配路径的锁封装层:它通过pcp_spin_lock_irqsave()获取当前 CPU 的 PCP 锁,用order_to_pindex()定位目标链表,调用__rmqueue_pcplist()执行实际的取页和批量补充,最后释放锁并恢复中断。它与__rmqueue_pcplist()形成清晰的“锁封装 + 持锁执行”分工,是rmqueue()在 PCP 允许的阶数范围内的首选分配路径。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 6:54:39

数字文旅补贴来了,景区申报要注意什么?

从支持方向到材料准备&#xff1a;一份可对照的实操清单近两年&#xff0c;支持文旅数字化改造的资金明显变多&#xff1a;多地把"数字文旅""智慧景区""沉浸式体验"写进专项资金申报指南&#xff0c;部分方向对建设投入给予比例补助&#xff0c;…

作者头像 李华
网站建设 2026/10/11 6:53:20

AI重塑单元测试:从用例生成到工程师转型的实战指南

AI与自动化重塑单元测试&#xff1a;智能化发展、效率提升与从业者转型这几年做软件测试的朋友应该都有同感&#xff1a;团队里的“写测试”这个动作&#xff0c;正在肉眼可见地变快、变奇。以前我一天能手写三五十条单元测试用例&#xff0c;已经算高产&#xff1b;现在AI辅助…

作者头像 李华
网站建设 2026/10/11 6:52:46

零基础学计算机入门指南:学习路径、核心基础与避坑建议

初入计算机领域的简单宣言&#xff1a;写给零基础起步者的心里话与避坑指南这两年经常有朋友问我&#xff1a;现在才开始学计算机&#xff0c;是不是太晚了&#xff1f;没有科班背景&#xff0c;能不能在这个行业扎下根&#xff1f;说实话&#xff0c;我特别理解这种焦虑&#…

作者头像 李华
网站建设 2026/10/11 6:49:38

AnyPS5通用化跨环境项目实战:抽象层设计与环境适配指南

1. 从“AnyPS5”这个名字说起&#xff1a;它到底想解决什么问题第一次看到“AnyPS5”这个标题&#xff0c;我脑子里蹦出来的第一个念头是&#xff1a;这大概率是一个围绕“跨平台运行”或者“通用化处理”做文章的项目。名字里的“Any”通常意味着“任意、通用、不受限”&#…

作者头像 李华
网站建设 2026/10/11 6:47:42

Astro框架深度解析:岛屿架构如何重塑内容型网站性能

Astro这个前端框架&#xff0c;我这两年用得越来越频繁。从最初只是拿它搭个个人博客&#xff0c;到后来几个团队的文档站点、营销官网、产品落地页都陆续切到了 Astro 上。它在开发者圈子里讨论热度一直在线&#xff0c;尤其是在内容型站点这块&#xff0c;几乎成了绕不开的候…

作者头像 李华
网站建设 2026/10/11 6:47:23

SpringBoot+Vue服装生产管理系统设计与实现全流程解析

第一次看到“服装生产管理”这几个字作为毕设选题的时候&#xff0c;很多人心里会先打一个问号&#xff1a;这不又是一个普通的“企业管理系统”吗&#xff1f;无非是用户管理、订单管理、库存管理&#xff0c;再往里面塞几张报表&#xff0c;感觉很难做出亮点。我当初也是抱着…

作者头像 李华