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 ÿò®w¥ìëÿéiy§!¢Ø^®W®v¢ëm ââìdz¹Þð+r¯{øm¶ÿþf¢ùåþX§»è®äz¹Þw°n'¬üPþm§ÿÿêçzYÞÁ³ú+÷Ú