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

Allow using mmap for shared linear memory if OS_ENABLE_HW_BOUND_CHECK is disabled #3029

Merged
merged 1 commit into from
Jan 16, 2024

Conversation

loganek
Copy link
Collaborator

@loganek loganek commented Jan 15, 2024

For shared memory, the max memory size must be defined in advanced. Re-allocation for growing memory can't be used as it might change the base address, therefore for OS_ENABLE_HW_BOUND_CHECK enabled the memory is mmaped, and if the flag is disabled, the memory is allocated. This change introduces a flag that allows users to use mmap for reserving memory address space even if the OS_ENABLE_HW_BOUND_CHECK is disabled.

@wenyongh
Copy link
Contributor

@loganek we are considering using os_mmap to allocate memory no matter whether OS_ENABLE_HW_BOUND_CHECK is enabled or not, since currently the code of memory instantiation/de-instantiation is very complex and not easy to maintain, and we may implement wasm64 feature later, which will make them more complex. os_mmap should have been implemented in all the platforms, and using it may greatly simplify the code, and for this PR, we don't need to introduce WAMR_ENABLE_SHARED_MEMORY_MMAP. How do you think?

@yamt
Copy link
Collaborator

yamt commented Jan 16, 2024

@loganek we are considering using os_mmap to allocate memory no matter whether OS_ENABLE_HW_BOUND_CHECK is enabled or not, since currently the code of memory instantiation/de-instantiation is very complex and not easy to maintain, and we may implement wasm64 feature later, which will make them more complex. os_mmap should have been implemented in all the platforms, and using it may greatly simplify the code, and for this PR, we don't need to introduce WAMR_ENABLE_SHARED_MEMORY_MMAP. How do you think?

how do you plan to implement the realloc case?

@yamt
Copy link
Collaborator

yamt commented Jan 16, 2024

This change introduces a flag that allows users to use mmap for reserving memory address space even if the OS_ENABLE_HW_BOUND_CHECK is disabled.

why do you want to use mmap?

@wenyongh
Copy link
Contributor

@loganek we are considering using os_mmap to allocate memory no matter whether OS_ENABLE_HW_BOUND_CHECK is enabled or not, since currently the code of memory instantiation/de-instantiation is very complex and not easy to maintain, and we may implement wasm64 feature later, which will make them more complex. os_mmap should have been implemented in all the platforms, and using it may greatly simplify the code, and for this PR, we don't need to introduce WAMR_ENABLE_SHARED_MEMORY_MMAP. How do you think?

how do you plan to implement the realloc case?

Do you mean realloc memory when memory.grow? Yes, it is a good question, per my understanding, for shared memory, no need to mmap a new memory, just increase the current page count. For non-shared memory, runtime should mmap a new memory, duplicate memory data to it and update the related info, like:

if (!(memory_data_new =
wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
ret = false;
goto return_func;
}
if (memory_data_old) {
bh_memcpy_s(memory_data_new, (uint32)total_size_new,
memory_data_old, total_size_old);
wasm_runtime_free(memory_data_old);
}
}

@yamt
Copy link
Collaborator

yamt commented Jan 16, 2024

@loganek we are considering using os_mmap to allocate memory no matter whether OS_ENABLE_HW_BOUND_CHECK is enabled or not, since currently the code of memory instantiation/de-instantiation is very complex and not easy to maintain, and we may implement wasm64 feature later, which will make them more complex. os_mmap should have been implemented in all the platforms, and using it may greatly simplify the code, and for this PR, we don't need to introduce WAMR_ENABLE_SHARED_MEMORY_MMAP. How do you think?

how do you plan to implement the realloc case?

Do you mean realloc memory when memory.grow? Yes, it is a good question, per my understanding, for shared memory, no need to mmap a new memory, just increase the current page count. For non-shared memory, runtime should mmap a new memory, duplicate memory data to it and update the related info, like:

if (!(memory_data_new =
wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
ret = false;
goto return_func;
}
if (memory_data_old) {
bh_memcpy_s(memory_data_new, (uint32)total_size_new,
memory_data_old, total_size_old);
wasm_runtime_free(memory_data_old);
}
}

realloc can be far cheaper than malloc+memcpy+free.
i'd suggest to introduce os_mremap, which a platform can use realloc to implement. (and maybe mremap on linux)

@wenyongh
Copy link
Contributor

@loganek we are considering using os_mmap to allocate memory no matter whether OS_ENABLE_HW_BOUND_CHECK is enabled or not, since currently the code of memory instantiation/de-instantiation is very complex and not easy to maintain, and we may implement wasm64 feature later, which will make them more complex. os_mmap should have been implemented in all the platforms, and using it may greatly simplify the code, and for this PR, we don't need to introduce WAMR_ENABLE_SHARED_MEMORY_MMAP. How do you think?

how do you plan to implement the realloc case?

Do you mean realloc memory when memory.grow? Yes, it is a good question, per my understanding, for shared memory, no need to mmap a new memory, just increase the current page count. For non-shared memory, runtime should mmap a new memory, duplicate memory data to it and update the related info, like:

if (!(memory_data_new =
wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
ret = false;
goto return_func;
}
if (memory_data_old) {
bh_memcpy_s(memory_data_new, (uint32)total_size_new,
memory_data_old, total_size_old);
wasm_runtime_free(memory_data_old);
}
}

realloc can be far cheaper than malloc+memcpy+free. i'd suggest to introduce os_mremap, which a platform can use realloc to implement. (and maybe mremap on linux)

Thanks a lot, it is good.

@loganek
Copy link
Collaborator Author

loganek commented Jan 16, 2024

@wenyongh, I think using mmap in all the cases sounds reasonable, and given that grow isn't that frequent operation, and it always allocates big chunk of memory, that shouldn't impact the performance either. Having said that, I'd suggest we merge this PR and continue the work on simplifications on top of that so our usecase is unblocked. What do you think?

@wenyongh
Copy link
Contributor

@wenyongh, I think using mmap in all the cases sounds reasonable, and given that grow isn't that frequent operation, and it always allocates big chunk of memory, that shouldn't impact the performance either. Having said that, I'd suggest we merge this PR and continue the work on simplifications on top of that so our usecase is unblocked. What do you think?

@loganek ok, it is good to me, let's review the PR and merge it after it is carefully checked.

@loganek
Copy link
Collaborator Author

loganek commented Jan 16, 2024

Thanks, please review it then and let me know if you have any feedback. As a followup, I can work on migrating to mmap completely later this week or next week.

core/iwasm/interpreter/wasm_runtime.c Outdated Show resolved Hide resolved
core/iwasm/aot/aot_runtime.c Outdated Show resolved Hide resolved
core/iwasm/aot/aot_runtime.c Outdated Show resolved Hide resolved
core/iwasm/aot/aot_runtime.c Outdated Show resolved Hide resolved
core/iwasm/aot/aot_runtime.c Outdated Show resolved Hide resolved
core/iwasm/aot/aot_runtime.c Show resolved Hide resolved
core/iwasm/interpreter/wasm_runtime.c Outdated Show resolved Hide resolved
core/iwasm/interpreter/wasm_runtime.c Show resolved Hide resolved
@loganek
Copy link
Collaborator Author

loganek commented Jan 16, 2024

@wenyongh looks like the build failed for unrelated reason - would you be able to restart the build?

Copy link
Contributor

@wenyongh wenyongh left a comment

Choose a reason for hiding this comment

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

LGTM with minor comment.

Comment on lines +1101 to +1108
void
wasm_munmap_linear_memory(void *mapped_mem, uint64 commit_size,
uint64 map_size);

void *
wasm_mmap_linear_memory(uint64_t map_size, uint64 *io_memory_data_size,
char *error_buf, uint32 error_buf_size);

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it better to move wasm_munmap_linear_memory/wasm_mmap_linear_memory from wasm_runtime_common.h/c to wasm_memory.h/c? We normally implement memory related operations (except shared memory) in the latter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, done.

Copy link
Collaborator Author

@loganek loganek Jan 16, 2024

Choose a reason for hiding this comment

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

Actually, I've reverted this change since I realized that set_error_buf is not defined and we'd have to define it for wasm_memory too. Because I'm planning to refactor the code and use mmap everywhere, I'll keep it where it is now and move things around during the refactoring. I hope that's ok.

@loganek loganek force-pushed the loganek/mmap branch 3 times, most recently from 5b80152 to ae41591 Compare January 16, 2024 12:44
… is disabled

For shared memory, the max memory size must be defined in advanced. Re-allocation
for growing memory can't be used as it might change the base address, therefore for
OS_ENABLE_HW_BOUND_CHECK enabled the memory is mmaped, and if the flag is disabled,
the memory is allocated. This change introduces a flag that allows users to use mmap
for reserving memory address space even if the OS_ENABLE_HW_BOUND_CHECK is disabled
@wenyongh wenyongh merged commit ffa131b into bytecodealliance:main Jan 16, 2024
405 of 407 checks passed
victoryang00 pushed a commit to victoryang00/wamr-aot-gc-checkpoint-restore that referenced this pull request May 27, 2024
…ecodealliance#3029)

For shared memory, the max memory size must be defined in advanced. Re-allocation
for growing memory can't be used as it might change the base address, therefore when
OS_ENABLE_HW_BOUND_CHECK is enabled the memory is mmaped, and if the flag is
disabled, the memory is allocated. This change introduces a flag that allows users to use
mmap for reserving memory address space even if the OS_ENABLE_HW_BOUND_CHECK
is disabled.
@loganek loganek deleted the loganek/mmap branch June 10, 2024 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants