page_alloc init_pageblock_migratetype
初始化阶段设置 pageblock 迁移类型的接口带一个是否隔离的特殊参数。它服务于内存初始化/热插拔时的批量迁移类型设置。一、函数签名void __meminit init_pageblock_migratetype(struct page *page, enum migratetype migratetype, bool isolate)参数参数类型含义pagestruct page *目标 pageblock 内的某一页migratetypeenum migratetype要设置的迁移类型isolatebool是否隔离处理返回值void无返回值。__meminit__meminit表示内存初始化阶段使用的函数。链接器把它放到.meminit.text段。内存初始化完成后memblock_free_all()之后该段内存被释放函数体被卸载。与__init类似但__meminit更精确地表示内存热插拔/初始化相关内存热插拔memory hotplug时新上线内存的初始化也走__meminit路径所以它不能像__init那样启动完就永久卸载——热插拔时还可能被调用。实际语义__meminit段在系统启动完成且内存热插拔不再发生时才可能被回收或根据配置保留。与set_pageblock_migratetype()的区别函数阶段特点set_pageblock_migratetype(page, migratetype)运行期常规设置可能有额外检查/统计init_pageblock_migratetype(page, migratetype, isolate)初始化/热插拔多了isolate参数用于批量、无锁或特殊处理二、isolate参数的含义这是这个函数最特殊的地方。背景内存初始化 / 热插拔时的页块状态内存初始化启动时或热插拔时新内存页刚加入伙伴系统需要给每个 pageblock 设置迁移类型。内存隔离memory isolation内存热插拔下线、CMA 分配等场景需要把 pageblock 标记为MIGRATE_ISOLATE表示这些页暂时不参与分配。isolate的作用isolate通常表示这块内存是否处于隔离状态影响初始化的具体行为例如是否标记为MIGRATE_ISOLATE如果isolate true可能把 pageblock 初始迁移类型设为MIGRATE_ISOLATE而非migratetype参数值表示待处理/待下线。如果isolate false正常设为migratetype。是否更新统计隔离的页块不应计入正常的迁移类型统计所以可能跳过统计更新。是否设置额外标志位可能需要同时设置/清除某个 pageblock 独立位来标记隔离状态。锁与并发处理初始化/隔离阶段可能有不同的锁策略如持有zone-lock或使用node_size_lock。具体语义随内核版本但核心意图是初始化时区分普通设置和隔离设置两种情况。三、典型实现实际实现通常比运行期版本更底层可能直接操作位图不走__set_pfnblock_flags_mask()的通用路径因为初始化阶段无并发可以简化。示意void __meminit init_pageblock_migratetype(struct page *page, enum migratetype migratetype, bool isolate) { unsigned long flags; unsigned long pfn page_to_pfn(page); unsigned long *bitmap; unsigned long bitidx; /* * 隔离时实际迁移类型设为 MIGRATE_ISOLATE * 否则用传入的 migratetype。 */ if (isolate) migratetype MIGRATE_ISOLATE; flags (unsigned long)migratetype PB_migrate; bitmap get_pageblock_bitmap(page, pfn); bitidx pfn_to_bitidx(page, pfn); /* 初始化阶段无并发可直接读改写 */ set_pageblock_flags(bitmap, bitidx, PB_migrate_mask, flags); /* 可能更新统计只有非隔离才计入 */ if (!isolate) ... /* 更新 zone 的迁移类型统计 */ }关键点isolate true时强制迁移类型为MIGRATE_ISOLATE这是隔离的核心语义。初始化阶段可以假设无并发实现可以更简单不必用原子位操作。__meminit函数体在内存初始化完成后可能被卸载节省内存。四、调用场景1. 启动时内存初始化free_area_init()/memmap_init()等初始化路径。每个 pageblock 初始设置迁移类型通常根据其所在 zone 和默认策略。2. 内存热插拔上线online_pages()把新内存加入伙伴系统时初始化其 pageblock 迁移类型。此时可能先用isolate true隔离完成后再用isolate false正式上线。3. 内存下线隔离offline_pages()需要先隔离页块MIGRATE_ISOLATE再迁移/下线。相关设置可能通过此函数或类似接口完成。4. CMA 区域初始化CMA 预留区域在初始化时设置MIGRATE_CMA。可能涉及isolate参数CMA 页块有特殊隔离语义。五、与前面内容的呼应前面出现过的这里的关联set_pageblock_migratetype()运行期版本本函数是初始化版本get_pfnblock_migratetype()读迁移类型本函数写迁移类型__set_pfnblock_flags_mask()通用写实现本函数可能用简化/专用路径PB_migrate/PB_migrate_mask迁移类型字段的位置和掩码MIGRATE_ISOLATEisolate true时的目标迁移类型__meminit内存初始化/热插拔阶段使用函数体可卸载get_pageblock_bitmap()/pfn_to_bitidx()底层定位内存热插拔online_pages()/offline_pages()典型调用场景调用链启动初始化 / 内存热插拔 └── init_pageblock_migratetype(page, migratetype, isolate) ├── if (isolate) migratetype MIGRATE_ISOLATE ├── get_pageblock_bitmap(page, pfn) ├── pfn_to_bitidx(page, pfn) └── 写入 PB_migrate 字段 可能的统计更新六、小结表项说明函数名init_pageblock_migratetype作用初始化/热插拔阶段设置 pageblock 迁移类型参数page目标 pageblock 内的页参数migratetype要设置的迁移类型参数isolate是否隔离处理true 时可能强制MIGRATE_ISOLATE返回值void段属性__meminit内存初始化/热插拔相关函数体可卸载与运行期版本区别多isolate参数可能有专用简化路径阶段不同典型场景启动内存初始化、内存热插拔上线/下线、CMA 初始化底层依赖get_pageblock_bitmap()/pfn_to_bitidx()/PB_migrate字段一句话总结init_pageblock_migratetype()是内存初始化/热插拔阶段设置 pageblock 迁移类型的__meminit接口相比运行期的set_pageblock_migratetype()多了一个isolate参数isolate true时通常把页块标记为MIGRATE_ISOLATE隔离待处理false时按传入的迁移类型正常设置它服务于启动内存初始化、内存热插拔上线/下线、CMA 预留区初始化等场景函数体在内存初始化完成后可被卸载。