#author("2025-09-10T15:44:27+09:00","default:guest","guest")
#author("2025-09-10T16:56:17+09:00","default:guest","guest")
*参照元 [#lf84ca32]
#backlinks

*説明 [#wf684f6e]
-パス: [[linux-5.15/mm/page_alloc.c]]

-ゾーンにmark以上の空きページがあるか取得する。
--markに指定する値は任意だが、watermarkが指定されることが多い。


**引数 [#q19c0df5]
-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
--
-long free_pages
--空きページ数。
--zone_page_state(z, NR_FREE_PAGES)を指定することが多い。


**返り値 [#t5b04011]
-bool
--十分な空きページがあればtrue、なければfalse。


**参考 [#ae5f60c8]


*実装 [#j7b78854]

 /*
  * Return true if free base pages are above 'mark'. For high-order checks it
  * will return true of the order-0 watermark is reached and there is at least
  * one free page of a suitable size. Checking now avoids taking the zone lock
  * to check in the allocation paths if no pages are free.
  */
 bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
 			 int highest_zoneidx, unsigned int alloc_flags,
 			 long free_pages)
 {
 	long min = mark;
 	int o;
 	const bool alloc_harder = (alloc_flags & (ALLOC_HARDER|ALLOC_OOM));
 

空きページ数(free_pages)から割り当て不能な領域を除外する。

-[[linux-5.15/__zone_watermark_unusable_free()]]

 	/* free_pages may go negative - that's OK */
 	free_pages -= __zone_watermark_unusable_free(z, order, alloc_flags);
 

ALLOC_HIGHフラグがあったら、markを引き下げて1/2にする
-空きページ数(free_pages)から割り当て不能な領域を除外する。
--[[linux-5.15/__zone_watermark_unusable_free()]] 

 	if (alloc_flags & ALLOC_HIGH)
 		min -= min / 2;
 

-ALLOC_HIGHフラグがあったら、markを引き下げて1/2にする

ALLOC_HARDER, ALLOC_OOMフラグがあったらmarkを引き下げて、普段よりメモリを確保しようとする。

- ALLOC_HARDER: markを3/4にする
- ALLOC_OOM   : markを1/2にする

 	if (unlikely(alloc_harder)) {
 		/*
 		 * OOM victims can try even harder than normal ALLOC_HARDER
 		 * users on the grounds that it's definitely going to be in
 		 * the exit path shortly and free memory. Any allocation it
 		 * makes during the free path will be small and short-lived.
 		 */
 		if (alloc_flags & ALLOC_OOM)
 			min -= min / 2;
 		else
 			min -= min / 4;
 	}
 

free_pagesがmark + protection以下だったら十分な空きメモリがないと判断しfalseを返す。
-ALLOC_HARDER, ALLOC_OOMフラグがあったらmarkを引き下げて、普段よりメモリを確保しようとする。
--ALLOC_HARDER: markを3/4にする
--ALLOC_OOM   : markを1/2にする

 	/*
 	 * Check watermarks for an order-0 allocation request. If these
 	 * are not met, then a high-order request also cannot go ahead
 	 * even if a suitable page happened to be free.
 	 */
 	if (free_pages <= min + z->lowmem_reserve[highest_zoneidx])
 		return false;
 

free_pagesがwatermark + protection以上で、order 0なら十分な空きメモリがあると判断しtrueを返す。
order 1以上の場合はさらに追加の判定が必要。
-free_pagesがmark + protection以下だったら十分な空きメモリがないと判断しfalseを返す。

 	/* If this is an order-0 request then the watermark is fine */
 	if (!order)
 		return true;
 

-free_pagesがwatermark + protection以上で、order 0なら十分な空きメモリがあると判断しtrueを返す。
-order 1以上の場合はさらに追加の判定が必要。

 	/* For a high-order request, check at least one suitable page is free */
 	for (o = order; o < MAX_ORDER; o++) {
 		struct free_area *area = &z->free_area[o];
 		int mt;
 

注目しているorderの空きブロック数が0なら、もう1段階大きいorderを見に行く。

--[[linux-5.15/free_area]]

 		if (!area->nr_free)
 			continue;
 

MIGRATE_UNMOVABLE, MOVABLE, RECLAIMABLEを見に行く。空いていれば十分な空きメモリがあると判断しtrueを返す。
-注目しているorderの空きブロック数が0なら、もう1段階大きいorderを見に行く。
--[[linux-5.15/free_area]]

- 0: MIGRATE_UNMOVABLE
- 1: MIGRATE_MOVABLE
- 2: MIGRATE_RECLAIMABLE
- 3: MIGRATE_PCPTYPES = MIGRATE_HIGHATOMIC
--[[linux-5.15/migratetype]]
--[[linux-5.15/free_area_empty()]]

 		for (mt = 0; mt < MIGRATE_PCPTYPES; mt++) {
 			if (!free_area_empty(area, mt))
 				return true;
 		}
 

CMAから確保してよければMIGRATE_CMAも見に行く。空いていれば十分な空きメモリがあると判断しtrueを返す。
MIGRATE_CMAの空き容量は/proc/zoneinfoのnr_free_cmaで確認できる。
- 4: MIGRATE_CMA
-MIGRATE_UNMOVABLE, MOVABLE, RECLAIMABLEを見に行く。空いていれば十分な空きメモリがあると判断しtrueを返す。
--0: MIGRATE_UNMOVABLE
--1: MIGRATE_MOVABLE
--2: MIGRATE_RECLAIMABLE
--3: MIGRATE_PCPTYPES = MIGRATE_HIGHATOMIC
--[[linux-5.15/migratetype]]
--[[linux-5.15/free_area_empty()]]

 #ifdef CONFIG_CMA
 		if ((alloc_flags & ALLOC_CMA) &&
 		    !free_area_empty(area, MIGRATE_CMA)) {
 			return true;
 		}
 #endif
 

ALLOC_HARDERかALLOC_OOMが指定されていたら、MIGRAGE_HIGHATOMICを見に行く。空いていれば十分な空きメモリがあると判断しtrueを返す。

- 3: MIGRATE_PCPTYPES = MIGRATE_HIGHATOMIC
-CMAから確保してよければMIGRATE_CMAも見に行く。空いていれば十分な空きメモリがあると判断しtrueを返す。
MIGRATE_CMAの空き容量は/proc/zoneinfoのnr_free_cmaで確認できる。
--4: MIGRATE_CMA
--[[linux-5.15/migratetype]]

 		if (alloc_harder && !free_area_empty(area, MIGRATE_HIGHATOMIC))
 			return true;

-ALLOC_HARDERかALLOC_OOMが指定されていたら、MIGRAGE_HIGHATOMICを見に行く。空いていれば十分な空きメモリがあると判断しtrueを返す。
--3: MIGRATE_PCPTYPES = MIGRATE_HIGHATOMIC
--[[linux-5.15/migratetype]]

 	}
 	return false;
 }


*コメント [#e23a4086]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS