[Crash-utility] kmem: WARNING: cannot find mem_map page for address

Bruce Korb bruce.korb at gmail.com
Tue Dec 18 21:34:45 UTC 2012


Hi Dave,

On Tue, Dec 18, 2012 at 6:52 AM, Dave Anderson <anderson at redhat.com> 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.




More information about the Crash-utility mailing list