Repository navigation
feat(libkernel): map regular files with mmap on Windows - #6542
adriadam10 merged 1 commit into
Conversation
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
c132955 to
85aece7
Compare
|
Rebase handoff — rebased onto current Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release,
To pick it up: Head is |
85aece7 to
39d9005
Compare
|
Thanks for the rebase, @blawesom. I've pushed my own rebase instead (
The new head keeps Windows 11, WinLibs GCC 15.2.0: full build passes, and 454/454 AI-assisted: yes (Claude Code); results above were run on this machine. |
39d9005 to
c1879fe
Compare
c1879fe to
2eabf63
Compare
|
I extended this PR to support shared mappings that end inside the guest page holding the end of the file. It is rebased on Found with PS5LM Plus (PPSA99581, v0.8.4). Its llama.cpp CPU backend maps the whole model file shared and read-only. The test model is Qwen2.5-0.5B-Instruct q4_k_m from Qwen's Hugging Face repo (Apache-2.0), 491,400,032 bytes, so the rounded length runs past the end of the file. The previous revision refused that and gave A Windows view can't cover host pages past the section size, and a larger section would grow the file. With this revision the model loads, and "The capital of France is" completes as " Paris. It is the largest city in Europe…" in 4 of 4 runs. The description has the test results and a note on the overlap with #7299. AI-assisted: yes (Claude Code); results above were run on this machine. |
2eabf63 to
45a702a
Compare
|
Windows run of head
Titles. PS5LM Plus is not a local title, so I could not run the case in the description. I ran five relinked titles that import Notes on the diff, none blocking:
Not checked: PS5LM Plus, Windows builds other than 10.0.26220, AMD and Intel GPUs, Linux and macOS, a large private mapping, the suite on plain Written with Claude Code assistance (validation by a subagent, reviewed in this session). |
A shared mapping is a view of a file section created on the descriptor's handle, read-write when the descriptor is, otherwise read-only. A private mapping is a copy of the file read at mmap, as POSIX allows. Anonymous shm_open objects and JIT shared memory descriptors are temporary files on Windows, so mmap now maps them too (it failed with EOPNOTSUPP before). mprotect of a mapped view above the view's protection fails with EACCES before any bookkeeping changes. The cases Windows cannot represent are listed in the libkernel debt. Dusklight (PPSA99305) uses SQLite in WAL mode, which maps its -shm file. On Windows main f063408 every start logged "Failed to start transaction: disk I/O error" for its Dawn and pipeline caches (3 of 3 runs); with this change the caches initialise and their WAL files fill (4 of 4 runs). The title reaches its menu either way. A shared mapping may end inside the 16 KiB page that holds the end of the file, as POSIX mmap allows: the view ends with the file's last 4 KiB host page, which Windows zero-fills past the end, the rest of the guest page is private zero pages, and the file never grows. A mapping that reaches a whole page past the end still fails with EOPNOTSUPP. PS5LM Plus (PPSA99581) loads its model with llama.cpp, which maps the whole GGUF file shared and read-only. With a 491,400,032-byte model, Windows main 5de7a46 and this change without the last page logged "llama_model_load: error loading model: mmap failed: Operation not supported" (3 of 3 runs); now the model loads and the completion of "The capital of France is" starts with " Paris" (3 of 3 runs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45a702a to
ddb774a
Compare
What
mmapof a regular file now works on Windows. Before, it failed withEOPNOTSUPP(PosixMemory.cpp; libkernel debt: "Windows maps no files"). Linux gained the same feature in #5053.CreateFileMappingW), read-write when the descriptor allows writing and read-only otherwise. They are mapped page by page throughWindowsMappings::Map, which now takes the section's view protection instead of always using execute-read-write (newGuestArenaMapFile_nid_postfix). Writes through the descriptor and through the mapping see each other.mmaptime (POSIX leaves it unspecified whether later file changes show). The partial last page is zero-filled, as on FreeBSD.shm_openobjects and JIT shared-memory descriptors are temporary files on Windows, sommapnow maps them too; the debt entries for both are updated.mprotectof a mapped view above the view's protection fails withEACCESbefore anything changes, as FreeBSD'svm_map_protectdoes. This covers writing through a read-only descriptor and addingPROT_EXEC.EOPNOTSUPPand are listed indocs/dev/debt/libkernel.md:PROT_EXECon a file view;ftruncateshrinking a file fails withEINVALwhile any shared mapping of it exists;mmapcalls make separate sections, so write tracking does not treat them as aliases.Title: Dusklight (PPSA99305, v0.3.0, the author's GPL-3.0 release) uses SQLite in WAL mode, which maps its
-shmfile withmmap(MAP_SHARED, fd).main: both of its caches fail on every start:Failed to start transaction: disk I/O error,SQLite DB init failedandFailed to begin pipeline cache schema transaction(3 of 3 runs).SQLite cache init succeededin 4 of 4 runs, the WAL files fill (dawn_cache.db-wal1.4 MB), and a second start reuses the cache. The title reaches the same menu as before, since there is no disc image.Tested
CheckRegularFileMappinginGuestMemory.cppnow also runs on Windows, with new checks: apwriteshows through a live shared mapping, a refusedmprotectreturnsEACCESand leaves the view usable, andremovesucceeds aftermunmap.GuestShmOpen.cppandGuestJitSharedMemory.cppgainmmapchecks.main, all three tests fail at the firstmmap; with this change they pass.main44df21632: 424 of 424guest_*,libkernel*,kernel*,libc*and stream tests pass, excludingagc_/video_out.mprotectto read-write on a read-only file view followed by a write gives the normal access violation, not the abort that bookkeeping changed beforeVirtualProtectwould cause.guest_memory,guest_shm_open,guest_jit_shared_memory,guest_mmap_fixed_anonymous,guest_mprotect_unmapped,guest_mlockandguest_msyncpass, both withmain's library sources and with this change (the library change is Windows-only; the new assertions also hold on Linux). The full tree builds.main5d9dcc42d(onlydocs/dev/debt/libkernel.mdconflicted, with the kqueue entries from fix(libkernel): serialize Windows vectored file transfers #5833 and feat(libkernel): implement kevent EV_DISABLE, EV_DISPATCH and EV_FORCEONESHOT #5847; the code is unchanged), rebuilt and re-tested on Windows: 424 of 424 again.python tools/check_conventions.py --base origin/mainpasses.Mappings that end past the end of the file (Windows). A shared mapping may end inside the 16 KiB guest page that holds the end of the file, as POSIX
mmapallows. The section keeps the file's size, so the file never grows. In that last guest page:EOPNOTSUPP, and a read-write alias of such a page throws.PS5LM Plus (PPSA99581, v0.8.4) needs this. It runs llama.cpp, whose CPU backend maps the whole GGUF model
MAP_SHARED, PROT_READ.-dev none -ngl 0, Windowsmainand the previous revision both loggedllama_model_load: error loading model: mmap failed: Operation not supported, 3 of 3 runs each.Tested for this revision (rebased on
5de7a46e0):CheckRegularFileMappingcovers the read-only and read-write cases. It fails on the previous revision (mmapreturnsMAP_FAILED, errno 45) and passes now.guest_memory,guest_shm_open,guest_jit_shared_memory,guest_mmap_fixed_anonymous,guest_mprotect_unmapped,guest_mlockandguest_msyncpass.mprotectacross the view/private boundary (refused withEACCES, nothing partly applied),munmapandMAP_FIXEDover the last page (no leftover allocations), write tracking on both parts, and the end-of-file bounds at several file sizes and offsets.Overlap: #7299 (named shared memory on Windows) conflicts with this in
docs/dev/debt/libkernel.md. With both, named objects would also take the file-mapping path here, so whichever lands second should reconcile the access checks.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code