kernel/vm: Set sAvailableMemory from the reserved physical pages size.
Rather than setting it from the total count of pages, and then reducing it by the size of the B_ALREADY_WIRED areas incrementally. This means that other things allocated in the early boot period (like page tables) will also be accounted for. The downside is that, if they don't have a corresponding area, then any pages freed later on won't also unreserve memory at present; but the early boot page tables likely won't be freed at all (since they'll be in use; or should have already been freed in the case of the 32-bit to PAE transition.) (In the future, we should reserve memory as well as pages for the page tables, and that will take care of that problem anyway.) Booting x86_64 in QEMU with 1GB of RAM, the old accounting method produced an initial (after ALREADY_WIRED accounting) sAvailableMemory of 251,368 total pages, while this new accounting method gives 250,812 instead, a difference of 556 pages. (Some of that is probably the never-freed bootloader memory, which I think is around ~360 pages.) Overall this should reduce the amount of "theoretically available but actually inaccessible" memory, which should hopefully help with the VM getting itself into trouble thinking memory is available when it really isn't.
This commit is contained in:
@@ -1653,6 +1653,7 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
||||
|
||||
physical_address_restrictions stackPhysicalRestrictions;
|
||||
bool doReserveMemory = false;
|
||||
addr_t reservedMemory = 0;
|
||||
switch (wiring) {
|
||||
case B_NO_LOCK:
|
||||
break;
|
||||
@@ -1661,8 +1662,6 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
||||
case B_CONTIGUOUS:
|
||||
doReserveMemory = true;
|
||||
break;
|
||||
case B_ALREADY_WIRED:
|
||||
break;
|
||||
case B_LOMEM:
|
||||
stackPhysicalRestrictions = *physicalAddressRestrictions;
|
||||
stackPhysicalRestrictions.high_address = 16 * 1024 * 1024;
|
||||
@@ -1680,17 +1679,22 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
||||
// TODO: We don't really support this mode efficiently. Just fall
|
||||
// through for now ...
|
||||
case B_32_BIT_CONTIGUOUS:
|
||||
#if B_HAIKU_PHYSICAL_BITS > 32
|
||||
#if B_HAIKU_PHYSICAL_BITS > 32
|
||||
if (vm_page_max_address() >= (phys_addr_t)1 << 32) {
|
||||
stackPhysicalRestrictions = *physicalAddressRestrictions;
|
||||
stackPhysicalRestrictions.high_address
|
||||
= (phys_addr_t)1 << 32;
|
||||
physicalAddressRestrictions = &stackPhysicalRestrictions;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
wiring = B_CONTIGUOUS;
|
||||
doReserveMemory = true;
|
||||
break;
|
||||
case B_ALREADY_WIRED:
|
||||
ASSERT(gKernelStartup);
|
||||
// The used memory will already be accounted for.
|
||||
reservedMemory = size;
|
||||
break;
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
@@ -1728,7 +1732,6 @@ vm_create_anonymous_area(team_id team, const char *name, addr_t size,
|
||||
// chances of failure, since while holding the write lock to the address
|
||||
// space (if it is the kernel address space that is), the low memory handler
|
||||
// won't be able to free anything for us.
|
||||
addr_t reservedMemory = 0;
|
||||
if (doReserveMemory) {
|
||||
bigtime_t timeout = (flags & CREATE_AREA_DONT_WAIT) != 0 ? 0 : 1000000;
|
||||
if (vm_try_reserve_memory(size, priority, timeout) != B_OK)
|
||||
@@ -3921,7 +3924,6 @@ vm_init(kernel_args* args)
|
||||
|
||||
// initialize some globals
|
||||
vm_page_init_num_pages(args);
|
||||
sAvailableMemory = vm_page_num_pages() * B_PAGE_SIZE;
|
||||
|
||||
slab_init(args);
|
||||
|
||||
|
||||
@@ -3431,6 +3431,9 @@ vm_page_init(kernel_args *args)
|
||||
// prevent future allocations from the kernel args ranges
|
||||
args->num_physical_allocated_ranges = 0;
|
||||
|
||||
// report initially available memory
|
||||
vm_unreserve_memory(vm_page_num_free_pages() * B_PAGE_SIZE);
|
||||
|
||||
// The target of actually free pages. This must be at least the system
|
||||
// reserve, but should be a few more pages, so we don't have to extract
|
||||
// a cached page with each allocation.
|
||||
|
||||
Reference in New Issue
Block a user