/* * Do the hard work of removing an element from the buddy allocator. * Call me with the zone->lock already held. */ /*采用两种范式试着分配order个page*/ static struct page *__rmqueue(struct zone *zone, unsigned int order, int migratetype) { struct page *page; retry_reserve: /*从指定order开始从小到达遍历,优先从指定的迁移类型链表中分配页面*/ page = __rmqueue_smallest(zone, order, migratetype); /* * 如果满足以下两个条件,就从备用链表中分配页面: * 快速流程没有分配到页面,需要从备用迁移链表中分配. * 当前不是从保留的链表中分配.因为保留的链表是最后可用的链表, * 不能从该链表分配的话,说明本管理区真的没有可用内存了. */ if (unlikely(!page) && migratetype != MIGRATE_RESERVE) { /*order从大到小遍历,从备用链表中分配页面*/ page = __rmqueue_fallback(zone, order, migratetype); /* * Use MIGRATE_RESERVE rather than fail an allocation. goto * is used because __rmqueue_smallest is an inline function * and we want just one call site */ if (!page) {/* 备用链表中没有分配到页面,从保留链表中分配页面了 */ migratetype = MIGRATE_RESERVE; goto retry_reserve;/* 跳转到retry_reserve,从保留的链表中分配页面*/ } } /*调试代码*/ trace_mm_page_alloc_zone_locked(page, order, migratetype); return page; }
Linux内存管理之伙伴系统(内存分配)(2)
内容版权声明:除非注明,否则皆为本站原创文章。