*参照元 [#taa07d25] #backlinks *説明 [#hbb765cc] -パス: [[linux-4.4.1/mm/migrate.c]] -FIXME: これは何? --説明 **引数 [#jbc95353] -new_page_t get_new_page -- --[[linux-4.4.1/new_page_t]] -free_page_t put_new_page -- --[[linux-4.4.1/free_page_t]] -unsigned long private -- -struct page *page -- --[[linux-4.4.1/page]] -int force -- -enum migrate_mode mode -- --[[linux-4.4.1/migrate_mode]] -enum migrate_reason reason -- --[[linux-4.4.1/migrate_reason]] **返り値 [#d99e7c18] -int -- **参考 [#j8f89e6c] *実装 [#a03c92d2] /* * 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; - --[[linux-4.4.1/ICE_noinline]] newpage = get_new_page(page, private, &result); if (!newpage) return -ENOMEM; -get_new_page は引数で渡されている関数ポインタ。 if (page_count(page) == 1) { /* page was freed from under us. So we are done. */ goto out; } - --[[linux-4.4.1/page_count()]] if (unlikely(PageTransHuge(page))) if (unlikely(split_huge_page(page))) goto out; - --[[linux-4.4.1/PageTransHuge()]] --[[linux-4.4.1/split_huge_page()]] --[[linux-4.4.1/unlikely()]] rc = __unmap_and_move(page, newpage, force, mode); if (rc == MIGRATEPAGE_SUCCESS) put_new_page = NULL; - --[[linux-4.4.1/__unmap_and_move()]] 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)); - --[[linux-4.4.1/list_del()]] --[[linux-4.4.1/dec_zone_page_state()]] --[[linux-4.4.1/page_is_file_cache()]] /* 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); - --[[linux-4.4.1/put_page()]] --[[linux-4.4.1/test_set_page_hwpoison()]] --[[linux-4.4.1/num_poisoned_pages_inc()]] --[[linux-4.4.1/putback_lru_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); -put_new_page は引数で渡されている関数ポインタ else if (unlikely(__is_movable_balloon_page(newpage))) { /* drop our reference, page already in the balloon */ put_page(newpage); - --[[linux-4.4.1/__is_movable_baloon_page()]] --[[linux-4.4.1/__is_movable_balloon_page()]] --[[linux-4.4.1/put_page()]] } else putback_lru_page(newpage); - --[[linux-4.4.1/putback_lru_page()]] if (result) { if (rc) *result = rc; else *result = page_to_nid(newpage); } - --[[linux-4.4.1/page_to_nid()]] return rc; } *コメント [#i5329ad1]