Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wasm] stop using mmap/munmap #108512

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

pavelsavara
Copy link
Member

@pavelsavara pavelsavara commented Oct 3, 2024

Contributes to #108510
Fixes #107215

Context

  • sgen GC is using mono_valloc -> mmap on all other platforms.
  • mmap emulator in emscripten and wasi-libc doens't implement partial munmap
    • It's implemented on top of malloc rather than on top of sbrk.
    • It has large alignment overhead and no added value.
  • We have our own implementation of custom mmap
    • which can do partial munmap
    • but it never releases pages back to malloc pool.
  • wasm could only grow, we can't return pages to OS/browser
  • wasm32 adress space is rather small and could get fragmented easily

Changes

  • set MS_BLOCK_ALLOC_NUM to 1 which prevents sgen from doing partial mono_vfree
  • implement mono_vfree using dlfree
  • implement mono_valloc_aligned and mono_valloc using posix_memalign
    • emscripten sys_alloc implementation will stitch last segment to new memory allocated via sbrk
  • avoids emscripten mmap which always calls memset to zero the memory
    • this PR brings optimization that new pages which are received from sbrk don't need that.
    • also some calls to mono_valloc pass MONO_MMAP_NOZERO
  • removes mono-wasm-pagemgr.c and wasm-mmap option

TODO

  • add unit test
  • measure startup performance
  • try to fix LOS alignment overhead between 64K and 1MB
  • fix soft-heap-limit to understand dlmalloc overhead (vs zero overhead of mmap on other systems)

image

@pavelsavara pavelsavara added arch-wasm WebAssembly architecture area-GC-mono os-browser Browser variant of arch-wasm labels Oct 3, 2024
@pavelsavara pavelsavara added this to the 10.0.0 milestone Oct 3, 2024
@pavelsavara pavelsavara self-assigned this Oct 3, 2024
#else
// WASM doesn't support partial munmap, so we can't free individual blocks
// we use posix_memalign and free the whole block at once
#define MS_BLOCK_ALLOC_NUM 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should investigate whether this will meaningfully regress performance; mwpm caused a benchmark regression that was fairly sizable

@@ -45,11 +45,7 @@ typedef struct {
MonoMemAccountType account_type;
} MonoLockFreeAllocator;

#ifdef HOST_WASM
#define LOCK_FREE_ALLOC_SB_MAX_SIZE (mono_opt_wasm_mmap ? 65536 : 16384)
#else
#define LOCK_FREE_ALLOC_SB_MAX_SIZE 16384
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need a solution for the 16 vs 64k problem here since the system page size is still 64kb right now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does sbrk() page size matter in any way ? Why ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it might be fine with the combination of all the changes you made, but mono_pagesize not agreeing with other sources of page size information feels like a hazard down the road

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would be the other sources which could conflict ?

#endif

return saved_pagesize;
return 16384;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should make sure it's actually okay to lie here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will improve the state of things by making pagesize not > the max block size, but the design of sgen is optimized for a base page size in the 4-8K range so that it can start with smaller blocks and then step up to larger blocks. i think with a page size of 16K it will always allocate only large blocks, and that might be bad? i'm not sure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can change it down to 4K, I think

Copy link
Member Author

@pavelsavara pavelsavara Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The natural wasm page size of 64k is spoiled by the fact there is dlmalloc header around it anyway.
So I think we could choose arbitrary page size and 16K is max on other platforms for sgen.

Right @BrzVlad ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kg not sure if you are talking about other blocks. GC major blocks (for small object allocation) are at least 16k.

I think 16k page size is just fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm referring to the comments in the lock free allocator, which is one of the places that was consuming the page size and interacting with mmap. I guess I was under the mistaken assumption that we used the lock free allocator in more places than we do.

@pavelsavara
Copy link
Member Author

@radekdoulik could you please run startup benchmark on this PR ? Many thanks

if ((flags & MONO_MMAP_NOZERO) == 0) {
memset (res, 0, size);
}
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this no longer does mono_account_mem tracking of allocated memory


mono_account_mem (type, -(ssize_t)length);

// NOTE: this doesn't implement partial freeing like munmap does
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, missing tracking of allocated memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly architecture area-GC-mono os-browser Browser variant of arch-wasm
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[wasm] New failure condition introduced by anonymous mmap implementation
3 participants