abrown opened PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
:
When multiple threads can concurrently modify a WebAssembly shared memory, the underlying data for a Wiggle
GuestSlice
andGuestSliceMut
could change due to access from other threads. This breaks Rust guarantees when&[T]
and&mut [T]
slices are handed out. This change modifiesGuestPtr
to makeas_slice
andas_slice_mut
return anOption
which isNone
when the underlying WebAssembly memory is shared.But WASI implementations still need access to the underlying WebAssembly memory, both to read to it and write from it. This change adds new APIs:
GuestPtr::to_vec
copies the bytes from WebAssembly memory (from which we can safely take a&[T]
)GuestPtr::as_unsafe_slice_mut
returns a wrapperstruct
from which we canunsafe
-ly return a mutable slice (users must accept the unsafety of concurrently modifying a&mut [T]
)This approach allows us to maintain Wiggle's borrow-checking infrastructure, which enforces the guarantee that Wiggle will not modify overlapping regions, e.g. This is important because the underlying system calls may expect this. Though other threads may modify the same underlying region, this is impossible to prevent; at least Wiggle will not be able to do so.
Finally, the changes to Wiggle's API are propagated to all WASI implementations in Wasmtime. For now, code locations that attempt to get a guest slice will panic if the underlying memory is shared. Note that Wiggle is not enabled for shared memory (that will come later in something like #5054), but when it is, these panics will be clear indicators of locations that must be re-implemented in a thread-safe way.
<!--
Please ensure that the following steps are all taken care of before submitting
the PR.
[ ] This has been discussed in issue #..., or if not, please tell us why
here.[ ] A short description of what this does, why it is needed; if the
description becomes long, the matter should probably be discussed in an issue
first.[ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
If you don't know who could review this, please indicate so. The list of
suggested reviewers on the right can help you.Please ensure all communication adheres to the code of conduct.
-->
abrown edited PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
:
When multiple threads can concurrently modify a WebAssembly shared memory, the underlying data for a Wiggle
GuestSlice
andGuestSliceMut
could change due to access from other threads. This breaks Rust guarantees when&[T]
and&mut [T]
slices are handed out. This change modifiesGuestPtr
to makeas_slice
andas_slice_mut
return anOption
which isNone
when the underlying WebAssembly memory is shared.But WASI implementations still need access to the underlying WebAssembly memory, both to read to it and write from it. This change adds new APIs:
GuestPtr::to_vec
copies the bytes from WebAssembly memory (from which we can safely take a&[T]
)GuestPtr::as_unsafe_slice_mut
returns a wrapperstruct
from which we canunsafe
-ly return a mutable slice (users must accept the unsafety of concurrently modifying a&mut [T]
)This approach allows us to maintain Wiggle's borrow-checking infrastructure, which enforces the guarantee that Wiggle will not modify overlapping regions, e.g. This is important because the underlying system calls may expect this. Other threads may modify the same underlying region and this is impossible to prevent; at least Wiggle will not be able to do so.
Finally, the changes to Wiggle's API are propagated to all WASI implementations in Wasmtime. For now, code locations that attempt to get a guest slice will panic if the underlying memory is shared. Note that Wiggle is not enabled for shared memory (that will come later in something like #5054), but when it is, these panics will be clear indicators of locations that must be re-implemented in a thread-safe way.
<!--
Please ensure that the following steps are all taken care of before submitting
the PR.
[ ] This has been discussed in issue #..., or if not, please tell us why
here.[ ] A short description of what this does, why it is needed; if the
description becomes long, the matter should probably be discussed in an issue
first.[ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
If you don't know who could review this, please indicate so. The list of
suggested reviewers on the right can help you.Please ensure all communication adheres to the code of conduct.
-->
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
alexcrichton submitted PR review.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Could the
expect
messages here be replaced with something along the lines of aTODO: ..
to clarify that there's nothing a user running into this can do to fix things, it requires source changes here.
alexcrichton created PR review comment:
double
as *mut T
cast?
alexcrichton created PR review comment:
Could this have a comment, or a reference, for why shared memory is rejected here?
alexcrichton created PR review comment:
Could you update the documentation of this function to indicate what the
Option
return means?
alexcrichton created PR review comment:
We'll need to be careful here because the mere presence of
&mut [T]
, however ephemeral it is, will be UB for Rust that we need to avoid. Basically the raw-pointer-ness needs to get plumbed all the way down to thestd::ptr::copy
.Also, can you be sure to tag this
std::ptr::copy
in the threads issue as "please audit at some point" along the lines of the other copies already inruntime/src/instances.rs
alexcrichton created PR review comment:
Or sort of more generally I think it's worth writing down somewhere the general idea behind shared memory and how it works in wiggle, and then link to that as part of various comments.
alexcrichton created PR review comment:
Could this perhaps be refactored with the result or such to be usable as an internal implementation detail of the two methods above? Deduplicating the bounds checks would be pretty convenient and the "Unsafe" version could then have a methods
{shared,mut}_borrow
to give the safe versions, returningNone
for shared memories.basically
as_slice()
could be a small wrapper aroundOk(self.as_unsafe_slice().shared_borrow())
or something like that.
alexcrichton created PR review comment:
Similar requests as above for doc updates and comments on the test for shared memory here
alexcrichton created PR review comment:
Also, given the sheer quantity of these, I think it might be good to have some sort of greppable string in the message here so an entry can be added to the threads tracking issue of how to find places to resolve.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
I don't think that this is doing what you might expect, I think this'll need to be written with
std::slice::from_raw_parts
. That being said I think it's best to dropas_slice
andas_slice_mut
here for now since nothing needs it. I think these would be better modeled as aDeref<Target = [UnsafeCell<T>]>
in the future if it's necessary.
alexcrichton created PR review comment:
Could this method be implemented with
as_unsafe_slice_mut
to deduplicate the bits internally?
alexcrichton created PR review comment:
For this this will still need to be implemented with an actual call to
std::ptr::copy
. I know for a fact that anything other than that is inherently UB, the only question to me is whetherstd::ptr::copy
is UB-or-not in this situation.
alexcrichton submitted PR review.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
abrown has marked PR #5229 as ready for review.
alexcrichton submitted PR review.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
I believe this will need to do a
guest_slice.mut_borrow()?;
before doing this copy to return an error if this is already borrowed for unshared memories.
abrown submitted PR review.
abrown created PR review comment:
I have
UnsafeGuestSlice::mut_borrow(self)
which then makes it difficult to either use the mutable borrow or use the unsafe slice forstd::ptr::copy
. Should it take&mut self
instead?
alexcrichton submitted PR review.
alexcrichton created PR review comment:
While no longer compatible with
?
how about:enum BorrowResult<T,S> { Ok(T), Shared(S), Err(GuestError), }
as the return value? So that way given a
Shared
error you can still get at the internal pointer.While you could change
mut_burrow
to&mut self
it would require still having theself
version to get the lifetimes onas_slice_mut
to work.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
alexcrichton submitted PR review.
alexcrichton has enabled auto merge for PR #5229.
abrown updated PR #5229 from shmem-in-wiggle-copy-and-unsafe
to main
.
alexcrichton merged PR #5229.
Last updated: Dec 23 2024 at 12:05 UTC