fix: reliability improvements in WinServer/IPC subsystems
This commit is contained in:
+10
-15
@@ -1806,7 +1806,8 @@ namespace Ipc {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext, uint64_t& outVa) {
|
||||
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext,
|
||||
uint64_t& outVa, bool reserveGrowthRange) {
|
||||
if (surface == nullptr) return -1;
|
||||
|
||||
int slot = SlotForPid(pid);
|
||||
@@ -1862,20 +1863,14 @@ namespace Ipc {
|
||||
g_surfaceMaps[slot][mapIdx].numPages = numPages;
|
||||
surface->refs++; // inlined RetainRawObject — we already hold surface->lock
|
||||
|
||||
// Reserve the full surface address-range cap, not just the currently
|
||||
// mapped pages. ResizeSurface can grow this surface up to
|
||||
// MaxSurfacePages, and its grow path extends the existing VA range
|
||||
// in-place by mapping new pages at baseVa + p*0x1000 for p beyond the
|
||||
// original size. If we only bumped heapNext by numPages*0x1000, any
|
||||
// subsequent mapping (another surface, heap allocation, etc.) would
|
||||
// sit at baseVa + numPages*0x1000 -- and a later grow would silently
|
||||
// overwrite its PTEs. Reserving MaxSurfacePages*0x1000 (32 MiB) of
|
||||
// VA per mapping is cheap: 47-bit user VA gives 128 TiB of headroom,
|
||||
// and at most MaxSurfaceMapsPerProcess (64) mappings per process
|
||||
// means at most 2 GiB of reserved VA per process. Page tables are
|
||||
// only populated for pages actually mapped; unused VA in the
|
||||
// reservation costs nothing beyond the address-space slot.
|
||||
heapNext += (uint64_t)MaxSurfacePages * 0x1000ULL;
|
||||
// Generic IPC surfaces can grow in place through ResizeSurface(), so
|
||||
// their mapping must reserve the maximum VA range that a later grow
|
||||
// can populate. Window-server surfaces are replaced rather than grown
|
||||
// in place, so callers can opt out and avoid burning 32 MiB of process
|
||||
// VA on every window map/remap during a long desktop session.
|
||||
uint32_t reservedPages = reserveGrowthRange ? MaxSurfacePages : numPages;
|
||||
if (reservedPages < numPages) reservedPages = numPages;
|
||||
heapNext += (uint64_t)reservedPages * 0x1000ULL;
|
||||
outVa = baseVa;
|
||||
surface->lock.Release();
|
||||
return 0;
|
||||
|
||||
@@ -135,7 +135,8 @@ namespace Ipc {
|
||||
uint32_t fillPixel);
|
||||
uint64_t MapSurfaceHandle(int handle);
|
||||
int ResizeSurfaceHandle(int handle, uint64_t newSize);
|
||||
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext, uint64_t& outVa);
|
||||
int MapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys, uint64_t& heapNext,
|
||||
uint64_t& outVa, bool reserveGrowthRange = true);
|
||||
int UnmapSurfaceForPid(Surface* surface, int pid, uint64_t pml4Phys);
|
||||
|
||||
ProcessObject* GetProcessObject(int pid);
|
||||
|
||||
Reference in New Issue
Block a user