#author("2025-09-11T11:22:14+09:00","default:guest","guest") #author("2025-09-11T11:23:19+09:00","default:guest","guest") *参照元 [#yae1b76a] #backlinks *説明 [#y6bdf0a8] -パス: [[linux-5.15/mm/compaction.c]] -FIXME: これは何? --説明 **引数 [#cf2fa82f] -struct zone *zone --メモリゾーン。 --[[linux-5.15/zone]] -int order --オーダー -unsigned int alloc_flags --割当フラグ -int highest_zoneidx --この値以下のゾーンから割り当てる -unsigned long wmark_target --閾値、空きページ数や利用可能なページ数を指定する **返り値 [#c61a2469] -enum compact_result --COMPACT_SKIPPED - コンパクションするための空きページが足りない(のでコンパクションしない) --COMPACT_SUCCESS - コンパクションしなくても割当が成功する(のでコンパクションしない) --COMPACT_CONTINUE - コンパクションすべき **参考 [#fe7fb776] *実装 [#a2bbec0c] static enum compact_result __compaction_suitable(struct zone *zone, int order, unsigned int alloc_flags, int highest_zoneidx, unsigned long wmark_target) { unsigned long watermark; if (is_via_compact_memory(order)) return COMPACT_CONTINUE; watermark = wmark_pages(zone, alloc_flags & ALLOC_WMARK_MASK); /* * If watermarks for high-order allocation are already met, there * should be no need for compaction at all. */ if (zone_watermark_ok(zone, order, watermark, highest_zoneidx, alloc_flags)) return COMPACT_SUCCESS; -watermarkその1の判定 --判定の目的は「現時点でメモリ割当可能ならコンパクションしない」です。watermarkを超える空きページがあるので、コンパクションは不要と判断します。 -alloc_flags & ALLOC_WMARK_MASKの意味 --ALLOC_WMARK_MASK = 4 - 1 = 3で、alloc_flagsのビットフィールド0~1の値を取得します。値はstruct zoneの配列_watermarkの添字にします。 -値の意味はenum zone_watermarksと同じで下記の通り。 --0: min = WMARK_MIN --1: low = WMARK_LOW --2: high = WMARK_HIGH --3: 使わない --[[linux-5.15/is_via_compact_memory()]] --[[linux-5.15/wmark_pages()]] --[[linux-5.15/zone_watermark_ok()]] /* * Watermarks for order-0 must be met for compaction to be able to * isolate free pages for migration targets. This means that the * watermark and alloc_flags have to match, or be more pessimistic than * the check in __isolate_free_page(). We don't use the direct * compactor's alloc_flags, as they are not relevant for freepage * isolation. We however do use the direct compactor's highest_zoneidx * to skip over zones where lowmem reserves would prevent allocation * even if compaction succeeds. * For costly orders, we require low watermark instead of min for * compaction to proceed to increase its chances. * ALLOC_CMA is used, as pages in CMA pageblocks are considered * suitable migration targets */ watermark = (order > PAGE_ALLOC_COSTLY_ORDER) ? low_wmark_pages(zone) : min_wmark_pages(zone); watermark += compact_gap(order); if (!__zone_watermark_ok(zone, 0, watermark, highest_zoneidx, ALLOC_CMA, wmark_target)) return COMPACT_SKIPPED; -watermarkその2の判定 --判定の目的は「空きページが足りないならコンパクションしない」です。コンパクションに必要な空きページが足りないので、コンパクションは不要と判断します。 --order 4以上: low watermarkを使います --order 3以下: min watermarkを使います(PAGE_ALLOC_COSTLY_ORDER = 3) --さらにcompact_gap() = (2 << order)を加算します(値の意味は後述(※))から、 --さらにcompact_gap() = (2 << order)を加算します(値の意味はcompact_gapのコメント参照)から、 --watermark2 = low or min watermark + (2 << order) -引数ALLOC_CMAは割当てにCMAも使ってよいことを意味します。 -引数wmark_targetの値は呼び出し元を見ると、zone_page_state(zone, NR_FREE_PAGES)が指定されています。値は/proc/zoneinfoのpages freeで確認できます。 --[[linux-5.15/__zone_watermark_ok()]] --[[linux-5.15/compact_gap()]] return COMPACT_CONTINUE; } *コメント [#v1674188]