Dave,
We're working on a problem where two physical pages think they're mapped
to the same virtual page (one has been orphaned)
I wanted to see if any other cases occurred, so I wanted to use kmem -p
to dump all the page structs. But I got the lines like this:
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffff81012fbb7720 11c6fc000 ------- ----- 3 200000000000004
...
ffff81012fc8d3b8 120411000 ------- ----- 2 200000000000064
which led to the twisty passages of anonymous struct members, and gdb
nastiness, and datatype_info etc.
But the real key was that
MEMBER_OFFSET_INIT(page_mapping, "page", "mapping");
was failing because on our kernel, mapping is in an anonymous struct in
a union in the page struct.
When I figured out that the following would still work:
crash> gdb p &((struct page*)0x0).mapping
$4 = (struct address_space **) 0x18
I set about to writing a patch to find it the hard way by sending that
command to gdb and then parsing the result, blah, blah, blah. Imagine
my surprise when I looked for an example somewhere in crash and happened
upon anon_member_offset, doing exactly the same thing! That and a few
discovered macros and all I had to do was change the above to:
MEMBER_OFFSET_INIT(page_mapping, "page", "mapping");
if (INVALID_MEMBER(page_mapping))
ANON_MEMBER_OFFSET_INIT(page_mapping,
"page","mapping");
So now, I can see that these two page structs have the same mapping and
offset, (and that this was the only case of it in my entire dump). I'm
so happy.
PAGE PHYSICAL MAPPING INDEX CNT FLAGS
ffff81012fbb7720 11c6fc000 ffff81012a0993f1 11453246214 3 200000000000004
...
ffff81012fc8d3b8 120411000 ffff81012a0993f1 11453246214 2 200000000000064
Patch is attached. Any problem with doing it this way?
Thanks,
Bob Montgomery