Hi Dave, On Tue, Dec 18, 2012 at 6:52 AM, Dave Anderson <anderson@xxxxxxxxxx> wrote: > #define __page_to_pfn(pg) \ > ({ const struct page *__pg = (pg); \ > int __sec = page_to_section(__pg); \ > (unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \ > }) > > Maybe you could play around with emulating that macro w/crash, and see what > comes up? Hey, that was sure fun. :( Since "struct page" is another name for "cfs_page_t": > crash> p $tp->page->flags > $9 = 0x200000000000000 "page to section" is a 43 bit right shift: > crash> p ($tp->page->flags >> 43) > $10 = 0x4000 > static inline struct mem_section *__nr_to_section(unsigned long nr) > { > if (!mem_section[SECTION_NR_TO_ROOT(nr)]) > return NULL; > return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK]; > } There are 16 maps per mem section, so a 4 bit shift and mask yield: return &mem_section[0x400][0] > crash> p mem_section[0x400] > $13 = (struct mem_section *) 0xffffffff81a26658 > crash> p mem_section[0x400][0x0] > $14 = { > section_mem_map = 0xffffffff81a26630, > pageblock_flags = 0xffffffff81a26680 > } So the result of __page_to_pfn is the difference between > crash> p $pg > $24 = (cfs_page_t *) 0xffffea001bb1d1e8 and the return result of __section_mem_map_addr((struct mem_section *) 0xffffffff81a26658) > static inline struct page *__section_mem_map_addr(struct mem_section *section) > { > unsigned long map = section->section_mem_map; > map &= SECTION_MAP_MASK; > return (struct page *)map; > } SECTION_MAP_MASK maps off the low order 3 bits, yielding: (cfs_page_t *) 0xffffffff81a26630 > crash> gdb set $mpg = (cfs_page_t *)0xffffffff81a26630 > crash> p ($pg - $mpg) > $32 = 0xffffff9b707721ed Now what do I do with that number? :) It is the difference between the numeric values of $pg and $mpg, divided by the size of "struct page" (which is 0x38 bytes) and sign extended. -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility