#author("2025-09-13T02:14:27+09:00","default:guest","guest") *参照元 [#qea971d4] #backlinks *説明 [#ea83ae9b] -パス: [[linux-5.15/mm/page_alloc.c]] -FIXME: これは何? --説明 **引数 [#jdb7bf89] -struct zone *zone -- --[[linux-5.15/zone]] -struct page *page -- --[[linux-5.15/page]] -unsigned int alloc_flags -- -int start_type -- -bool whole_block -- **返り値 [#sd84f815] -なし **参考 [#t6284162] *実装 [#g72c5483] /* * This function implements actual steal behaviour. If order is large enough, * we can steal whole pageblock. If not, we first move freepages in this * pageblock to our migratetype and determine how many already-allocated pages * are there in the pageblock with a compatible migratetype. If at least half * of pages are free or compatible, we can change migratetype of the pageblock * itself, so pages freed in the future will be put on the correct free list. */ static void steal_suitable_fallback(struct zone *zone, struct page *page, unsigned int alloc_flags, int start_type, bool whole_block) { unsigned int current_order = buddy_order(page); int free_pages, movable_pages, alike_pages; int old_block_type; old_block_type = get_pageblock_migratetype(page); - --[[linux-5.15/buddy_order()]] --[[linux-5.15/get_pageblock_migratetype()]] /* * This can happen due to races and we want to prevent broken * highatomic accounting. */ if (is_migrate_highatomic(old_block_type)) goto single_page; - --[[linux-5.15/is_migrate_highatomic()]] /* Take ownership for orders >= pageblock_order */ if (current_order >= pageblock_order) { change_pageblock_range(page, current_order, start_type); goto single_page; } - --[[linux-5.15/change_pageblock_range()]] /* * Boost watermarks to increase reclaim pressure to reduce the * likelihood of future fallbacks. Wake kswapd now as the node * may be balanced overall and kswapd will not wake naturally. */ if (boost_watermark(zone) && (alloc_flags & ALLOC_KSWAPD)) set_bit(ZONE_BOOSTED_WATERMARK, &zone->flags); - --[[linux-5.15/boost_watermark()]] --[[linux-5.15/set_bit()]] /* We are not allowed to try stealing from the whole block */ if (!whole_block) goto single_page; free_pages = move_freepages_block(zone, page, start_type, &movable_pages); - --[[linux-5.15/move_freepages_block()]] /* * Determine how many pages are compatible with our allocation. * For movable allocation, it's the number of movable pages which * we just obtained. For other types it's a bit more tricky. */ if (start_type == MIGRATE_MOVABLE) { alike_pages = movable_pages; } else { /* * If we are falling back a RECLAIMABLE or UNMOVABLE allocation * to MOVABLE pageblock, consider all non-movable pages as * compatible. If it's UNMOVABLE falling back to RECLAIMABLE or * vice versa, be conservative since we can't distinguish the * exact migratetype of non-movable pages. */ if (old_block_type == MIGRATE_MOVABLE) alike_pages = pageblock_nr_pages - (free_pages + movable_pages); else alike_pages = 0; } /* moving whole block can fail due to zone boundary conditions */ if (!free_pages) goto single_page; /* * If a sufficient number of pages in the block are either free or of * comparable migratability as our allocation, claim the whole block. */ if (free_pages + alike_pages >= (1 << (pageblock_order-1)) || page_group_by_mobility_disabled) set_pageblock_migratetype(page, start_type); return; - --[[linux-5.15/set_pageblock_migratetype()]] single_page: move_to_free_list(page, zone, current_order, start_type); } - --[[linux-5.15/move_to_free_list()]] *コメント [#o725d1ab]