*参照元 [#s3cb7d5c] #backlinks *説明 [#v668bda5] -パス: [[linux-4.4.1/]] -パス: [[linux-4.4.1/mm/huge_memory.c]] -FIXME: これは何? --説明 **引数 [#u8234761] -struct page *page -- --[[linux-4.4.1/page]] -struct anon_vma *anon_vma -- --[[linux-4.4.1/anon_vma]] -struct list_head *list -- --[[linux-4.4.1/list_head]] **返り値 [#e5225d56] -void **参考 [#q2264ba2] *実装 [#x4372d2b] /* must be called with anon_vma->root->rwsem held */ static void __split_huge_page(struct page *page, struct anon_vma *anon_vma, struct list_head *list) { int mapcount, mapcount2; pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); struct anon_vma_chain *avc; - --[[linux-4.4.1/pgoff_t]] --[[linux-4.4.1/anon_vma_chain]] BUG_ON(!PageHead(page)); BUG_ON(PageTail(page)); - --[[linux-4.4.1/BUG_ON()]] --[[linux-4.4.1/PageHead()]] --[[linux-4.4.1/PageTail()]] mapcount = 0; anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) { struct vm_area_struct *vma = avc->vma; unsigned long addr = vma_address(page, vma); BUG_ON(is_vma_temporary_stack(vma)); mapcount += __split_huge_page_splitting(page, vma, addr); } - --[[linux-4.4.1/anon_vma_interval_tree_foreach()]] --[[linux-4.4.1/vm_area_struct]] --[[linux-4.4.1/vma_address()]] --[[linux-4.4.1/BUG_ON()]] --[[linux-4.4.1/is_vma_temporary_stack()]] --[[linux-4.4.1/__split_huge_page_splitting()]] /* * It is critical that new vmas are added to the tail of the * anon_vma list. This guarantes that if copy_huge_pmd() runs * and establishes a child pmd before * __split_huge_page_splitting() freezes the parent pmd (so if * we fail to prevent copy_huge_pmd() from running until the * whole __split_huge_page() is complete), we will still see * the newly established pmd of the child later during the * walk, to be able to set it as pmd_trans_splitting too. */ if (mapcount != page_mapcount(page)) { pr_err("mapcount %d page_mapcount %d\n", mapcount, page_mapcount(page)); BUG(); } - --[[linux-4.4.1/page_mapcount()]] --[[linux-4.4.1/pr_err()]] --[[linux-4.4.1/BUG()]] __split_huge_page_refcount(page, list); - --[[linux-4.4.1/__split_huge_page_refcount()]] mapcount2 = 0; anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) { struct vm_area_struct *vma = avc->vma; unsigned long addr = vma_address(page, vma); BUG_ON(is_vma_temporary_stack(vma)); mapcount2 += __split_huge_page_map(page, vma, addr); } - --[[linux-4.4.1/anon_vma_interval_tree_foreach()]] --[[linux-4.4.1/vm_area_struct]] --[[linux-4.4.1/vma_address()]] --[[linux-4.4.1/BUG_ON()]] --[[linux-4.4.1/is_vma_temporary_stack()]] --[[linux-4.4.1/__split_huge_page_map()]] if (mapcount != mapcount2) { pr_err("mapcount %d mapcount2 %d page_mapcount %d\n", mapcount, mapcount2, page_mapcount(page)); BUG(); } } *コメント [#c827dafd]