参照元

説明

引数

返り値

参考

実装

/*
 * Obtain the lock on page, remove all ptes and migrate the page
 * to the newly allocated page in newpage.
 */
static ICE_noinline int unmap_and_move(new_page_t get_new_page,
				   free_page_t put_new_page,
				   unsigned long private, struct page *page,
				   int force, enum migrate_mode mode,
				   enum migrate_reason reason)
{
	int rc = MIGRATEPAGE_SUCCESS;
	int *result = NULL;
	struct page *newpage;
	newpage = get_new_page(page, private, &result);
	if (!newpage)
		return -ENOMEM;
	if (page_count(page) == 1) {
		/* page was freed from under us. So we are done. */
		goto out;
	}
	if (unlikely(PageTransHuge(page)))
		if (unlikely(split_huge_page(page)))
			goto out;
	rc = __unmap_and_move(page, newpage, force, mode);
	if (rc == MIGRATEPAGE_SUCCESS)
		put_new_page = NULL;
out:
	if (rc != -EAGAIN) {
		/*
		 * A page that has been migrated has all references
		 * removed and will be freed. A page that has not been
		 * migrated will have kepts its references and be
		 * restored.
		 */
		list_del(&page->lru);
		dec_zone_page_state(page, NR_ISOLATED_ANON +
				page_is_file_cache(page));
		/* Soft-offlined page shouldn't go through lru cache list */
		if (reason == MR_MEMORY_FAILURE) {
			put_page(page);
			if (!test_set_page_hwpoison(page))
				num_poisoned_pages_inc();
		} else
			putback_lru_page(page);
	}

	/*
	 * If migration was not successful and there's a freeing callback, use
	 * it.  Otherwise, putback_lru_page() will drop the reference grabbed
	 * during isolation.
	 */
	if (put_new_page)
		put_new_page(newpage, private);
	else if (unlikely(__is_movable_balloon_page(newpage))) {
		/* drop our reference, page already in the balloon */
		put_page(newpage);
	} else
		putback_lru_page(newpage);
	if (result) {
		if (rc)
			*result = rc;
		else
			*result = page_to_nid(newpage);
	}
	return rc;
}

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-09-15 (金) 20:30:34