[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
pgd_page vs. pmd_page vs. pte_page
Hi all,
pgd_page, pmd_page, and pte_page are implemented on i386 in 2.6.0-test7 as:
#define pfn_to_page(pfn) (mem_map + (pfn))
#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
#define pte_page(x) pfn_to_page(pte_pfn(x))
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
They're all different although the last two are pretty close :)
Why does pmd_page and pte_page use a PFN-based scheme to get the page relative to mem_map while pgd_page totally ignores mem_map?
It seems like it's possible that pgd_page could end up with a struct page *less* than mem_map: imagine the pgd_t given to pgd_val represents a very, very low physical address, let's be drastic and say it represents the first page frame, i.e. (physical) address 0. When converted into a virtual address, that's 0xC0000000, which is to say less than mem_map's virtual address. Or does the code assume that we're never going to generate a page less than mem_map because when we create the pgd_t that we're going through the buddy allocator and thus by definition can't be less?
So again, why the three different methods of getting the struct page? Are they all *exactly* equivalent or is there a subtle difference?
Thanks!
Kirk
)zYw朆az^jn{zP+rzmj)gX+w?!Gg{z+ګ