参照元

説明

引数

返り値

参考

実装

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)から割り当て不能な領域を除外する
	//★★free_pagesの初期値: zone_page_state(z, NR_FREE_PAGES))
	/* free_pages may go negative - that's OK */
	free_pages -= __zone_watermark_unusable_free(z, order, alloc_flags);

	//★★ALLOC_HIGHフラグがあったら、watermarkを引き下げて1/2にする
	if (alloc_flags & ALLOC_HIGH)
		min -= min / 2;

	//★★ALLOC_HARDER, ALLOC_OOMフラグがあったらwatermarkを引き下げて、
	//★★普段よりメモリを確保しようとする
	//★★ALLOC_HARDER: watermarkを3/4にする
	//★★ALLOC_OOM   : watermarkを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;
	}

	/*
	 * 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.
	 */
	//★★free_pagesがwatermark + protection以下だったらメモリ確保しない
	if (free_pages <= min + z->lowmem_reserve[highest_zoneidx])
		return false;

	/* If this is an order-0 request then the watermark is fine */
	//★★free_pagesがwatermark + protection以上で、order 0ならメモリ確保できる
	//★★order 1以上の場合は追加で判定が必要
	if (!order)
		return true;

	/* 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を見に行く
		if (!area->nr_free)
			continue;

		//★★MIGRATE_UNMOVABLE, MOVABLE, RECLAIMABLEを見に行く
		//★★空いていればメモリ確保できる、値はenum migratetypeを参照
		//★★  0: MIGRATE_UNMOVABLE
		//★★  1: MIGRATE_MOVABLE
		//★★  2: MIGRATE_RECLAIMABLE
		//★★  3: MIGRATE_PCPTYPES = MIGRATE_HIGHATOMIC
		for (mt = 0; mt < MIGRATE_PCPTYPES; mt++) {
			if (!free_area_empty(area, mt))
				return true;
		}

#ifdef CONFIG_CMA
		//★★CMAから確保してよければMIGRATE_CMAも見に行く
		//★★空いていればメモリ確保できる、値はenum migratetypeを参照
		//★★  4: MIGRATE_CMA
		if ((alloc_flags & ALLOC_CMA) &&
		    !free_area_empty(area, MIGRATE_CMA)) {
			return true;
		}
#endif
		//★★ALLOC_HARDERかALLOC_OOMが指定されていたら、MIGRAGE_HIGHATOMICを見に行く
		//★★空いていればメモリ確保できる、値はenum migratetypeを参照
		//★★  3: MIGRATE_PCPTYPES = MIGRATE_HIGHATOMIC
		if (alloc_harder && !free_area_empty(area, MIGRATE_HIGHATOMIC))
			return true;
	}
	return false;
}

コメント


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS