ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

page_alloc set_pageblock_migratetype

page_alloc set_pageblock_migratetype 设置某个 pageblock 的迁移类型。它是反碎片机制的核心写入接口与get_pfnblock_migratetype()读配对。一、函数签名static void set_pageblock_migratetype(struct page *page, enum migratetype migratetype)参数参数类型含义pagestruct page *目标 pageblock 内的某一页用于定位 zone/位图migratetypeenum migratetype要设置的迁移类型返回值void无返回值。static文件内私有不导出。仅在page_alloc.c内部使用。对外可能通过其他封装如set_pageblock_migratetype_nolock()或宏提供。注释/** * set_pageblock_migratetype - Set the migratetype of a pageblock * page: The page within the block of interest * migratetype: migratetype to set */Set the migratetype of a pageblock设置一个 pageblock 的迁移类型。注意不是 page而是 pageblock——整个2^pageblock_order页的属性。二、与读函数对比函数方向参数返回get_pfnblock_migratetype(page, pfn)读page, pfnenum migratetypeset_pageblock_migratetype(page, migratetype)写page, migratetypevoid参数差异写函数为什么没有pfn读函数get_pfnblock_migratetype(page, pfn)同时给page和pfn是为了省去page_to_pfn()性能优化。写函数set_pageblock_migratetype(page, migratetype)只给page内部自己算 pfnunsigned long pfn page_to_pfn(page);原因写操作本身就是慢路径分配/释放/规整时调用page_to_pfn()的开销可忽略API 简洁更重要。若调用方已有 pfn可能内部有另一个接口如set_pfnblock_migratetype(page, migratetype, pfn)来复用。三、典型实现static void set_pageblock_migratetype(struct page *page, enum migratetype migratetype) { if (unlikely(page_group_by_mobility_disabled)) return; set_pfnblock_flags_mask(page, page_to_pfn(page), (unsigned long)migratetype, PB_migrate_mask); }或更直接地编码到字段位置static void set_pageblock_migratetype(struct page *page, enum migratetype migratetype) { unsigned long pfn page_to_pfn(page); if (unlikely(page_group_by_mobility_disabled)) return; /* * 把 migratetype 编码到 PB_migrate 字段 * (migratetype PB_migrate) PB_migrate_mask */ set_pfnblock_flags_mask(page, pfn, (unsigned long)migratetype PB_migrate, PB_migrate_mask); }逐步说明1. 禁用分组的快速返回if (unlikely(page_group_by_mobility_disabled)) return;page_group_by_mobility_disabled当系统内存太小、分组收益不大时内核禁用按迁移性分组。禁用后pageblock 的迁移类型不再有意义所有页混在一起管理设置它没有用处。直接return跳过写入省开销。unlikely()因为运行期绝大多数系统不会禁用分组只有小内存系统才禁用所以偏向不返回。2. 把迁移类型编码到字段(unsigned long)migratetype PB_migratePB_migrate迁移类型字段的起始位偏移。把migratetype值左移到该字段位置。例如PB_migrate 0、migratetype MIGRATE_MOVABLE (1)→ 编码为1。3. 用 mask 限定只改迁移类型字段PB_migrate_mask覆盖PB_migrate ~ PB_migrate_end的掩码。保证只改迁移类型字段其他独立位如PB_migrate_skip保持不变。4. 调用set_pfnblock_flags_mask()set_pfnblock_flags_mask(page, pfn, 编码值, PB_migrate_mask);这是__set_pfnblock_flags_mask()的对外包装带VM_BUG_ON等检查。底层做读-改-写(旧值 ~mask) | (新值 mask)只更新迁移类型字段。完整语义set_pageblock_migratetype(page, MIGRATE_MOVABLE) ↓ if (分组禁用) return; // 小内存优化 ↓ pfn page_to_pfn(page) ↓ set_pfnblock_flags_mask(page, pfn, MIGRATE_MOVABLE PB_migrate, // 新值 PB_migrate_mask) // 只改这几位 ↓ 底层读-改-写其他位不动四、并发与锁这个函数本身不加锁正确性依赖调用方常见调用点在持zone-lock或pgdat-node_size_lock等锁的情况下或者操作的是当前 CPU 独有的页块不冲突多 CPU 并发修改同一 pageblock的迁移类型需要外部同步。这也是它为什么是static且注释简洁——它是内部工具同步责任在调用方。五、典型用途1. 伙伴系统初始化启动时把各 pageblock 的迁移类型设为初始值通常是MIGRATE_MOVABLE或MIGRATE_UNMOVABLE。2. 分配时改变迁移类型当从某迁移类型 fallback 到另一类型取页时可能需要更新 pageblock 的迁移类型反映实际使用情况。例如__rmqueue_fallback()中偷了别的类型的页块后可能把该 pageblock 标记为新类型避免后续继续误用。3. 内存规整compaction规整前把页块标记为MIGRATE_ISOLATE隔离规整后恢复。通过set_pageblock_migratetype(page, MIGRATE_ISOLATE)实现。4. CMA 区域CMA 预留的内存页块迁移类型设为MIGRATE_CMA表示这块给 CMA 用。分配时 CMA 类型优先满足 CMA 请求非 CMA 请求可临时借用。5. 内存热插拔下线内存前把页块迁移类型设为MIGRATE_ISOLATE隔离后迁移走页再下线。上线时恢复迁移类型。6.ZONE_MOVABLEMOVABLE zone 的页块迁移类型通常是MIGRATE_MOVABLE。六、与前面内容的呼应前面出现过的这里的关联migratetype_names[]enum migratetype的名字表get_pfnblock_migratetype()读配对PB_migrate/PB_migrate_end/PB_migrate_mask编码与掩码__set_pfnblock_flags_mask()/set_pfnblock_flags_mask()底层写入实现page_group_by_mobility_disabled分组禁用时直接 returnMIGRATE_ISOLATE/MIGRATE_CMA特殊迁移类型用此函数设置PB_migrate_skip独立位不受本函数影响因为 mask 只覆盖迁移类型字段调用链set_pageblock_migratetype(page, migratetype) ├── if (page_group_by_mobility_disabled) return; // 分组禁用 ├── pfn page_to_pfn(page) └── set_pfnblock_flags_mask(page, pfn, migratetype PB_migrate, PB_migrate_mask) └── __set_pfnblock_flags_mask(...) // 读-改-写 ├── get_pageblock_bitmap() ├── pfn_to_bitidx() └── 更新位七、小结表项说明函数名set_pageblock_migratetype作用设置某 pageblock 的迁移类型参数page用于定位 zone/位图内部转 pfn参数migratetype要设置的迁移类型返回值void可见性static文件内私有关键优化分组禁用page_group_by_mobility_disabled时直接返回实现依赖set_pfnblock_flags_mask(page, pfn, migratetype PB_migrate, PB_migrate_mask)并发不加锁正确性依赖调用方同步
返回列表