fix: fix login wallpaper startup delay
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 179
|
||||
#define MONTAUK_BUILD_NUMBER 182
|
||||
|
||||
+39
-1
@@ -45,7 +45,12 @@ namespace montauk::abi {
|
||||
static constexpr uint64_t VmProtWrite = 2;
|
||||
static constexpr uint64_t VmProtExec = 4;
|
||||
|
||||
inline uint64_t Sys_MapAnonymous(uint64_t size, uint64_t prot) {
|
||||
// Sys_MapAnonymous flags. Populate commits the whole range at mapping
|
||||
// time; without it every page is materialized on first touch.
|
||||
static constexpr uint64_t VmFlagPopulate = 1;
|
||||
|
||||
inline uint64_t Sys_MapAnonymous(uint64_t size, uint64_t prot,
|
||||
uint64_t flags = 0) {
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc == nullptr) return 0;
|
||||
int slot = GetCurrentSlot();
|
||||
@@ -83,6 +88,33 @@ namespace montauk::abi {
|
||||
g_heapAllocs[slot] = new HeapAlloc { userVa, numPages, prot, allocationId,
|
||||
g_heapAllocs[slot] };
|
||||
|
||||
// Populate is best effort: commit as much of the range as the frame
|
||||
// allocator will give up front, and leave the remainder to the fault
|
||||
// path. A caller that is about to touch every page (a decode buffer,
|
||||
// a heap slab) then pays one loop instead of one trap, one mutex
|
||||
// acquire and one VMA walk per 4 KiB.
|
||||
if ((flags & VmFlagPopulate) != 0) {
|
||||
bool writable = (prot & VmProtWrite) != 0;
|
||||
bool executable = (prot & VmProtExec) != 0;
|
||||
// Bounded so one syscall cannot pin an unbounded amount of memory
|
||||
// with the slot's heap lock held. Anything past the cap faults in.
|
||||
static constexpr uint64_t MaxPopulatePages = 64 * 1024 * 1024 / 0x1000;
|
||||
uint64_t populate = numPages < MaxPopulatePages ? numPages
|
||||
: MaxPopulatePages;
|
||||
for (uint64_t i = 0; i < populate; i++) {
|
||||
uint64_t pageVa = userVa + i * 0x1000ULL;
|
||||
void* page = Memory::g_pfa->AllocateZeroed();
|
||||
if (page == nullptr) break;
|
||||
uint64_t phys = Memory::SubHHDM((uint64_t)page);
|
||||
if (!Memory::VMM::Paging::MapUserInPermissions(
|
||||
proc->pml4Phys, phys, pageVa, writable, executable)) {
|
||||
Memory::g_pfa->Free(page);
|
||||
break;
|
||||
}
|
||||
Sched::g_allocatedPages[slot]++;
|
||||
}
|
||||
}
|
||||
|
||||
g_heapLocks[slot].Release();
|
||||
return userVa;
|
||||
}
|
||||
@@ -91,6 +123,12 @@ namespace montauk::abi {
|
||||
return Sys_MapAnonymous(size, VmProtRead | VmProtWrite);
|
||||
}
|
||||
|
||||
// As Sys_Alloc, but commits the pages immediately instead of faulting them
|
||||
// in one at a time.
|
||||
inline uint64_t Sys_AllocEager(uint64_t size) {
|
||||
return Sys_MapAnonymous(size, VmProtRead | VmProtWrite, VmFlagPopulate);
|
||||
}
|
||||
|
||||
// Reset heap allocation tracking for a process slot.
|
||||
// The actual physical pages are freed by Paging::FreeUserHalf() during process cleanup.
|
||||
inline void CleanupHeapForSlot(int slot, uint64_t /*pml4Phys*/) {
|
||||
|
||||
@@ -116,6 +116,8 @@ namespace montauk::abi {
|
||||
(int)frame->arg4);
|
||||
case SYS_ALLOC:
|
||||
return (int64_t)Sys_Alloc(frame->arg1);
|
||||
case SYS_ALLOC_EAGER:
|
||||
return (int64_t)Sys_AllocEager(frame->arg1);
|
||||
case SYS_FREE:
|
||||
Sys_Free(frame->arg1);
|
||||
return 0;
|
||||
|
||||
@@ -338,6 +338,11 @@ namespace montauk::abi {
|
||||
static constexpr uint64_t SYS_SPAWN_CAPS = 185;
|
||||
static constexpr uint64_t SYS_SPAWN_REDIR_CAPS = 186;
|
||||
|
||||
/* Heap.hpp -- as SYS_ALLOC, but commits every page up front instead of
|
||||
faulting them in one at a time. For buffers the caller is about to
|
||||
touch in full (image decode, heap slabs). */
|
||||
static constexpr uint64_t SYS_ALLOC_EAGER = 187; // (bytes) -> va, 0 on failure
|
||||
|
||||
/* Kernel-owned process capabilities. User identities may namespace
|
||||
per-user resources, but never participate in authorization decisions. */
|
||||
static constexpr uint64_t CAP_PROCESS_ADMIN = 1ULL << 0;
|
||||
|
||||
@@ -48,6 +48,10 @@ namespace Fs {
|
||||
{"/config/init.toml", false, montauk::abi::CAP_USER_ADMIN},
|
||||
{"/config/ssh.toml", false, montauk::abi::CAP_USER_ADMIN},
|
||||
{"/config/capabilities.toml",false, montauk::abi::CAP_USER_ADMIN},
|
||||
// Pre-scaled wallpaper the login screen blits before it has decoded
|
||||
// anything. It is drawn on a screen that is about to take a password,
|
||||
// so it must not be plantable by an unprivileged process.
|
||||
{"/config/wallpaper.cache", false, montauk::abi::CAP_USER_ADMIN},
|
||||
// Read by the Bluetooth driver at controller bring-up.
|
||||
{"/config/bluetooth.toml", false, montauk::abi::CAP_DEVICE_ADMIN},
|
||||
// Program images. Capability grants are keyed on binary path, so a
|
||||
|
||||
@@ -355,10 +355,18 @@ namespace Fs::Ramdisk {
|
||||
uint64_t newCap = entry.size;
|
||||
if (endOffset > newCap) newCap = endOffset;
|
||||
if (newCap < 256) newCap = 256;
|
||||
// Round up to next power of 2 for growth
|
||||
uint64_t rounded = 256;
|
||||
while (rounded < newCap) rounded *= 2;
|
||||
newCap = rounded;
|
||||
// Small files round to the next power of 2, so an appender grows
|
||||
// in a few steps. Large ones round to a page instead: the kernel
|
||||
// heap grows in physically contiguous runs, and doubling an 8 MiB
|
||||
// write into a 16 MiB block asks the frame allocator for twice the
|
||||
// contiguous span the file actually needs.
|
||||
if (newCap < 64 * 1024) {
|
||||
uint64_t rounded = 256;
|
||||
while (rounded < newCap) rounded *= 2;
|
||||
newCap = rounded;
|
||||
} else {
|
||||
newCap = (newCap + 0xFFFULL) & ~0xFFFULL;
|
||||
}
|
||||
|
||||
uint8_t* newBuf = (uint8_t*)Memory::g_heap->Request(newCap);
|
||||
if (newBuf == nullptr) return -1;
|
||||
@@ -374,8 +382,14 @@ namespace Fs::Ramdisk {
|
||||
|
||||
// Grow buffer if needed
|
||||
if (endOffset > entry.capacity) {
|
||||
uint64_t newCap = entry.capacity;
|
||||
while (newCap < endOffset) newCap *= 2;
|
||||
// Double while small, then grow in fixed 1 MiB steps. Doubling all
|
||||
// the way keeps growth amortized but overshoots badly on multi-MiB
|
||||
// files, and every byte of overshoot is a physically contiguous
|
||||
// kernel-heap run this file holds for the rest of the boot.
|
||||
static constexpr uint64_t MaxGrowStep = 1024 * 1024;
|
||||
uint64_t newCap = entry.capacity < 256 ? 256 : entry.capacity;
|
||||
while (newCap < endOffset)
|
||||
newCap += (newCap < MaxGrowStep) ? newCap : MaxGrowStep;
|
||||
|
||||
uint8_t* newBuf = (uint8_t*)Memory::g_heap->Request(newCap);
|
||||
if (newBuf == nullptr) return -1;
|
||||
|
||||
Reference in New Issue
Block a user