#author("2025-09-10T18:32:41+09:00","default:guest","guest") #author("2025-09-11T16:17:36+09:00","default:guest","guest") *参照元 [#hdca5acf] #backlinks *説明 [#n10e5156] -パス: [[linux-5.15/mm/compaction.c]] -コンパクションを延期するかどうか取得します。 **引数 [#n0e689a6] -struct zone *zone --メモリゾーン。 --[[linux-5.15/zone]] -int order --オーダー。 **返り値 [#cc61d76d] -bool --コンパクションを延期するならtrue、延期しないならfalse。 **参考 [#d9d7bcd5] compact_order_failedは、 compact_order_failedは下記のどちらかを保持する。 - 過去にコンパクションに成功したときのorder + 1の値 --[[linux-5.15/compaction_defer_reset()]] - 過去にコンパクションに失敗したときのorderの値 --[[linux-5.15/defer_compaction()]] のどちらかを保持する。 compaction_defer_reset()呼び出し元は3つ -[[linux-5.15/try_to_compact_pages()]] --[[linux-5.15/compact_zone_order()]]に成功したときに呼ぶ。[[linux-5.15/compact_zone_order()]]は内部で[[linux-5.15/compact_zone()]]を呼ぶ。 -[[linux-5.15/kcompactd_do_work()]] --[[linux-5.15/compact_zone()]]に成功したときに呼ぶ。 -[[linux-5.15/__alloc_pages_direct_compact()]] --[[linux-5.15/try_to_compact_pages()]]でコンパクションに成功し、[[linux-5.15/get_page_from_freelist()]]でページ割当てに成功したときに呼ぶ。 defer_compaction()の呼び出し元は2つあって、 defer_compaction()の呼び出し元は2つ -[[linux-5.15/try_to_compact_pages()]] --[[linux-5.15/compact_zone_order()]]に失敗したときに呼ぶ。 -[[linux-5.15/kcompactd_do_work()]] --[[linux-5.15/compact_zone()]]に失敗したときに呼ぶ ざっくりいうとcompact_zone()が成功したらorder + 1、失敗したらorderの値が設定されると思っておけば良さそうです。 例えばorder 9でコンパクションをするか判定するとき、 -前回のコンパクションでorder 9が成功した、compact_order_failed = 10 --今回も成功するはずなのでコンパクションを延期せず実施する(return false)。 -前回のコンパクションでorder 9が失敗した、compact_order_failed = 9 --今回も失敗する確率が高いのでコンパクションを延期して実施しない(return true)。 コンパクションを延期し続けてしまうことを避けるため、延期する度にcompact_consideredがインクリメントされます。もしリミット回数(1 << compact_defer_shift)に達していたらコンパクションします。 リミット回数の計算に使うcompact_defer_shiftはコンパクション延期時(defer_compaction()を呼ぶ)にインクリメントされ、コンパクション成功時(compaction_defer_reset()を呼ぶ)に0にセットされます。最大6で、リミット値だと64回に相当します。 compact_defer_shiftはコンパクション延期時(defer_compaction()を呼ぶ)にインクリメントされ、コンパクション成功時(compaction_defer_reset()を呼ぶ)に0にセットされます。最大6で、リミット値だと64回に相当します。 *実装 [#v6d63841] /* Returns true if compaction should be skipped this time */ static bool compaction_deferred(struct zone *zone, int order) { unsigned long defer_limit = 1UL << zone->compact_defer_shift; if (order < zone->compact_order_failed) return false; -前回のコンパクションが成功しているか、失敗していても今回のorderの方が小さければコンパクションを延期しない。 /* Avoid possible overflow */ if (++zone->compact_considered >= defer_limit) { zone->compact_considered = defer_limit; return false; } -コンパクションを延期した回数が一定数を超えていたら、コンパクションを延期しない。 trace_mm_compaction_deferred(zone, order); return true; } -いずれの条件も成立しないならコンパクションを延期する。 --[[linux-5.15/trace_mm_compaction_deferred()]] *コメント [#k6936ea7]