#author("2025-09-12T15:00:55+09:00","default:guest","guest") #author("2025-09-12T15:09:45+09:00","default:guest","guest") *参照元 [#hc8f6b83] #backlinks *説明 [#b8ca5968] -パス: [[linux-5.15/mm/page_alloc.c]] -ゾーンにmark以上の空きページがあるか取得する。 --order 0の判定に対する高速化が実装されている。 --markに指定する値は任意だが、watermarkが指定されることが多い。 **引数 [#s1c64106] -struct zone *z --メモリゾーン。 --[[linux-5.15/zone]] -unsigned int order --オーダー。カーネルのメモリ確保関数は、ページ数を2^orderの形で表すことがある。つまりorder 0 = 1ページ, order 1 = 2ページ, order 2 = 4ページ, order 3 = 8ページのようになる。 -unsigned long mark --十分な空きページがあると判定するための閾値。指定する値は任意だが、watermarkが指定されることが多い。 -int highest_zoneidx --ゾーンインデックス。このインデックス以下のゾーンからメモリを確保する。 -unsigned int alloc_flags -- -gfp_t gfp_mask -- --[[linux-5.15/gfp_t]] **返り値 [#rc902135] -bool --十分な空きページがあればtrue、なければfalse。 **参考 [#j8ff0c00] *実装 [#nbdc975e] static inline bool zone_watermark_fast(struct zone *z, unsigned int order, unsigned long mark, int highest_zoneidx, unsigned int alloc_flags, gfp_t gfp_mask) { long free_pages; free_pages = zone_page_state(z, NR_FREE_PAGES); -ゾーンの空きページ数を取得する。 --[[linux-5.15/zone_page_state()]] /* * Fast check for order-0 only. If this fails then the reserves * need to be calculated. */ if (!order) { long fast_free; fast_free = free_pages; fast_free -= __zone_watermark_unusable_free(z, 0, alloc_flags); if (fast_free > mark + z->lowmem_reserve[highest_zoneidx]) return true; } -order 0のみの高速判定処理。空きページ数からunusable_free(HIGHATOMIC, CMA領域のページ数)を除外したページ数が閾値 + プロテクション値を上回っていればtrueを返す。 -通常判定とALLOC_HIGH、ALLOC_HARDERやALLOC_OOMによるmin watermarkの切り下げをしない点が異なる。 -通常判定と比べると、ALLOC_HIGH、ALLOC_HARDERやALLOC_OOMによるmin watermarkの切り下げをしない点が異なる。 --[[linux-5.15/__zone_watermark_unusable_free()]] if (__zone_watermark_ok(z, order, mark, highest_zoneidx, alloc_flags, free_pages)) return true; -通常判定に成功したらtrueを返す。 --[[linux-5.15/__zone_watermark_ok()]] /* * Ignore watermark boosting for GFP_ATOMIC order-0 allocations * when checking the min watermark. The min watermark is the * point where boosting is ignored so that kswapd is woken up * when below the low watermark. */ if (unlikely(!order && (gfp_mask & __GFP_ATOMIC) && z->watermark_boost && ((alloc_flags & ALLOC_WMARK_MASK) == WMARK_MIN))) { mark = z->_watermark[WMARK_MIN]; return __zone_watermark_ok(z, order, mark, highest_zoneidx, alloc_flags, free_pages); } return false; } -order 0でGFP_ATOMICが指定されているときはwatermark_boostを無視した条件で再度判定して、成功したらtrueを返す。 --[[linux-5.15/__zone_watermark_ok()]] *コメント [#y05c2ade]