kernel/vm: Use DebugGetReverseMappingInfo() in dump_page_long.

Iterating over every single page in a 64-bit address space is far
too expensive. Instead, use DebugGetReverseMappingInfo(), which
iterates over the page translation map's page tables.

(The only thing that implements this at present, however, is
X86VMTranslationMapPAE, so it won't be too useful on 64-bit
just yet. But at least we won't hang for very long periods
of time on 64-bit at least.)
This commit is contained in:
Augustin Cavalier
2024-09-25 11:49:53 -04:00
parent 718918a70a
commit b665a3ab2a
+28 -20
View File
@@ -1010,29 +1010,37 @@ dump_page_long(int argc, char **argv)
}
if (searchMappings) {
struct Callback : VMTranslationMap::ReverseMappingInfoCallback {
VMAddressSpace* fAddressSpace;
virtual bool HandleVirtualAddress(addr_t virtualAddress)
{
phys_addr_t physicalAddress;
uint32 flags = 0;
if (fAddressSpace->TranslationMap()->QueryInterrupt(virtualAddress,
&physicalAddress, &flags) != B_OK) {
kprintf(" aspace %" B_PRId32 ": %#" B_PRIxADDR " (querying failed)\n",
fAddressSpace->ID(), virtualAddress);
return false;
}
VMArea* area = fAddressSpace->LookupArea(virtualAddress);
kprintf(" aspace %" B_PRId32 ", area %" B_PRId32 ": %#"
B_PRIxADDR " (%c%c%s%s)\n", fAddressSpace->ID(),
area != NULL ? area->id : -1, virtualAddress,
(flags & B_KERNEL_READ_AREA) != 0 ? 'r' : '-',
(flags & B_KERNEL_WRITE_AREA) != 0 ? 'w' : '-',
(flags & PAGE_MODIFIED) != 0 ? " modified" : "",
(flags & PAGE_ACCESSED) != 0 ? " accessed" : "");
return false;
}
} callback;
kprintf("all mappings:\n");
VMAddressSpace* addressSpace = VMAddressSpace::DebugFirst();
while (addressSpace != NULL) {
size_t pageCount = addressSpace->Size() / B_PAGE_SIZE;
for (addr_t address = addressSpace->Base(); pageCount != 0;
address += B_PAGE_SIZE, pageCount--) {
phys_addr_t physicalAddress;
uint32 flags = 0;
if (addressSpace->TranslationMap()->QueryInterrupt(address,
&physicalAddress, &flags) == B_OK
&& (flags & PAGE_PRESENT) != 0
&& physicalAddress / B_PAGE_SIZE
== page->physical_page_number) {
VMArea* area = addressSpace->LookupArea(address);
kprintf(" aspace %" B_PRId32 ", area %" B_PRId32 ": %#"
B_PRIxADDR " (%c%c%s%s)\n", addressSpace->ID(),
area != NULL ? area->id : -1, address,
(flags & B_KERNEL_READ_AREA) != 0 ? 'r' : '-',
(flags & B_KERNEL_WRITE_AREA) != 0 ? 'w' : '-',
(flags & PAGE_MODIFIED) != 0 ? " modified" : "",
(flags & PAGE_ACCESSED) != 0 ? " accessed" : "");
}
}
callback.fAddressSpace = addressSpace;
addressSpace->TranslationMap()->DebugGetReverseMappingInfo(
page->physical_page_number * B_PAGE_SIZE, callback);
addressSpace = VMAddressSpace::DebugNext(addressSpace);
}
}