-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Use bytes for maximum size of linear memory with pooling #8628
Use bytes for maximum size of linear memory with pooling #8628
Conversation
This commit changes configuration of the pooling allocator to use a byte-based unit rather than a page based unit. The previous `PoolingAllocatorConfig::memory_pages` configuration option configures the maximum size that a linear memory may grow to at runtime. This is an important factor in calculation of stripes for MPK and is also a coarse-grained knob apart from `StoreLimiter` to limit memory consumption. This configuration option has been renamed to `max_memory_size` and documented that it's in terms of bytes rather than pages as before. Additionally the documented constraint of `max_memory_size` must be smaller than `static_memory_bound` is now additionally enforced as a minor clean-up as part of this PR as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but I am confused about one thing and have Opinions and Concerns about writing the constant value directly all over the place
@@ -76,7 +76,7 @@ impl Config { | |||
if let InstanceAllocationStrategy::Pooling(pooling) = &mut self.wasmtime.strategy { | |||
// One single-page memory | |||
pooling.total_memories = config.max_memories as u32; | |||
pooling.memory_pages = 10; | |||
pooling.max_memory_size = 10 * 65535; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be 65536
right? If you instead want the max address it should be 10 * 65536 - 1
.
Also lets use named constants for the Wasm page size so that it is easier to find uses and update in the future for the custom-page-sizes proposal. We have it defined in wasmtime_types
already, FWIW, and this could use that here:
wasmtime/crates/types/src/lib.rs
Line 1493 in c477424
pub const WASM_PAGE_SIZE: u32 = 0x10000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah 65535 is a typo here, and everywhere else, but I'm hesitant to go through all the work to import a constant in all these places since it's all in tests anyway and all the values are basically random constants. In the future the wasm page size won't be constant as well so it feels weird to proliferate usage of the constant... I can change these to >>16
and <<16
though where appropriate perhaps to reduce the risk of typos.
@@ -135,7 +135,7 @@ impl Config { | |||
if pooling.total_memories < 1 | |||
|| pooling.total_tables < 5 | |||
|| pooling.table_elements < 1_000 | |||
|| pooling.memory_pages < 900 | |||
|| pooling.max_memory_size < (900 * 65536) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto regarding named constant
if pooling.memory_pages == 0 { | ||
pooling.memory_pages = 1; | ||
if pooling.max_memory_size == 0 { | ||
pooling.max_memory_size = 65535; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also confused about 65535
here since that isn't a multiple of the page size, so this will disallow any non-zero-length memories, assuming we don't do rounding elsewhere in this PR?
cfg.max_memory32_pages = min / 65536; | ||
cfg.max_memory64_pages = min / 65535; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also confused about 65535
vs 65536
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And ditto about named constants on everything here.
@@ -703,7 +704,7 @@ mod test { | |||
let config = PoolingInstanceAllocatorConfig { | |||
limits: InstanceLimits { | |||
total_memories: 1, | |||
memory_pages: 0x10001, | |||
max_memory_size: (1 << 32) + 65536, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
named constant, even tho it's just a test. we want to make sure we are actually testing sizes that wasm could potentially grow to, and not accidentally just testing rounding behavior or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you expand on this? I could see a comment going here but I'm not sure otherwise what you're looking for in terms of a constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the goal is to test behavior with N wasm pages of capacity, then we should make sure we are actually doing that (as opposed to testing with unaligned capacity) and using a constant helps in this scenario. I feel like the typos are evidence that we can mess this up.
Additionally, having a constant that we can grep for all uses of will make it easier to support the custom-page-sizes proposal down the line: we have a list of uses that we can turn into method calls if necessary, and a list of tests that we might want to update or copy and tweak.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The meaning of this test has sort of been updated and lost a bit over time as I've been tweaking settings. This isn't specifically testing for unalignment or anything like that it's just one size being bigger than the other and various bits and pieces have been lost to translation over time.
I'm gonna go ahead and merge this as-is but we can of course update tests afterwards. I'm basically just somewhat doubtful if it's worth the effort to try to document all tests for precisely what they're doing page-wise and such. I don't think any of the tests really need to be updated with custom-page-sizes since they're all using wasm memories of 64k pages and the tests for custom-page-sizes are going to be pretty orthogonal anyway. Much of the time the page limits are just to reduce VM memory reservations anyway and don't have much to do with page sizes.
@@ -767,7 +763,7 @@ mod tests { | |||
max_tables_per_module: 0, | |||
max_memories_per_module: 3, | |||
table_elements: 0, | |||
memory_pages: 1, | |||
max_memory_size: 65536, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
tests/all/async_functions.rs
Outdated
@@ -344,7 +344,9 @@ async fn fuel_eventually_finishes() { | |||
#[tokio::test] | |||
async fn async_with_pooling_stacks() { | |||
let mut pool = crate::small_pool_config(); | |||
pool.total_stacks(1).memory_pages(1).table_elements(0); | |||
pool.total_stacks(1) | |||
.max_memory_size(65536) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto in this file's changes
tests/all/limits.rs
Outdated
@@ -354,7 +354,7 @@ fn test_pooling_allocator_initial_limits_exceeded() -> Result<()> { | |||
let mut pool = crate::small_pool_config(); | |||
pool.total_memories(2) | |||
.max_memories_per_module(2) | |||
.memory_pages(5) | |||
.max_memory_size(5 * 65536) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay I am going to stop saying "ditto about named constants" now and assume you will go over the diff yourself to catch all of them at this point
Subscribe to Label Actioncc @fitzgen
This issue or pull request has been labeled: "fuzzing", "wasmtime:api", "wasmtime:config"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
Label Messager: wasmtime:configIt looks like you are changing Wasmtime's configuration options. Make sure to
To modify this label's message, edit the To add new label messages or remove existing label messages, edit the |
I've updated with |
Fallout from bytecodealliance#8628 that I forgot to handle.
* Fix some fuzz memory configuration issues Fallout from #8628 that I forgot to handle. * More fuzz tweaks * More tweaks for more bugs
…iance#8628) * Use bytes for maximum size of linear memory with pooling This commit changes configuration of the pooling allocator to use a byte-based unit rather than a page based unit. The previous `PoolingAllocatorConfig::memory_pages` configuration option configures the maximum size that a linear memory may grow to at runtime. This is an important factor in calculation of stripes for MPK and is also a coarse-grained knob apart from `StoreLimiter` to limit memory consumption. This configuration option has been renamed to `max_memory_size` and documented that it's in terms of bytes rather than pages as before. Additionally the documented constraint of `max_memory_size` must be smaller than `static_memory_bound` is now additionally enforced as a minor clean-up as part of this PR as well. * Review comments * Fix benchmark build
* Fix some fuzz memory configuration issues Fallout from bytecodealliance#8628 that I forgot to handle. * More fuzz tweaks * More tweaks for more bugs
This commit changes configuration of the pooling allocator to use a byte-based unit rather than a page based unit. The previous
PoolingAllocatorConfig::memory_pages
configuration option configures the maximum size that a linear memory may grow to at runtime. This is an important factor in calculation of stripes for MPK and is also a coarse-grained knob apart fromStoreLimiter
to limit memory consumption. This configuration option has been renamed tomax_memory_size
and documented that it's in terms of bytes rather than pages as before.Additionally the documented constraint of
max_memory_size
must be smaller thanstatic_memory_bound
is now additionally enforced as a minor clean-up as part of this PR as well.