Skip to content

Delete historical interruptable support in Wasmtime#3925

Merged
alexcrichton merged 7 commits into
bytecodealliance:mainfrom
alexcrichton:delete-interurpts
Mar 14, 2022
Merged

Delete historical interruptable support in Wasmtime#3925
alexcrichton merged 7 commits into
bytecodealliance:mainfrom
alexcrichton:delete-interurpts

Conversation

@alexcrichton
Copy link
Copy Markdown
Member

This commit removes the Config::interruptable configuration along with
the InterruptHandle type from the wasmtime crate. The original
support for adding interruption to WebAssembly was added pretty early on
in the history of Wasmtime when there was no other method to prevent an
infinite loop from the host. Nowadays, however, there are alternative
methods for interruption such as fuel or epoch-based interruption.

One of the major downsides of Config::interruptable is that even when
it's not enabled it forces an atomic swap to happen when entering
WebAssembly code. This technically could be a non-atomic swap if the
configuration option isn't enabled but that produces even more branch-y
code on entry into WebAssembly which is already something we try to
optimize. Calling into WebAssembly is on the order of a dozens of
nanoseconds at this time and an atomic swap, even uncontended, can add
up to 5ns on some platforms.

The main goal of this PR is to remove this atomic swap on entry into
WebAssembly. This is done by removing the Config::interruptable field
entirely, moving all existing consumers to epochs instead which are
suitable for the same purposes. This means that the stack overflow check
is no longer entangled with the interruption check and perhaps one day
we could continue to optimize that further as well.

Some consequences of this change are:

  • Epochs are now the only method of remote-thread interruption.
  • There are no more Wasmtime traps that produces the Interrupted trap
    code, although we may wish to move future traps to this so I left it
    in place.
  • The C API support for interrupt handles was also removed and bindings
    for epoch methods were added.
  • Function-entry checks for interruption are a tiny bit less efficient
    since one check is performed for the stack limit and a second is
    performed for the epoch as opposed to the Config::interruptable
    style of bundling the stack limit and the interrupt check in one. It's
    expected though that this is likely to not really be measurable.
  • The old VMInterrupts structure is renamed to VMRuntimeLimits.

This commit removes the `Config::interruptable` configuration along with
the `InterruptHandle` type from the `wasmtime` crate. The original
support for adding interruption to WebAssembly was added pretty early on
in the history of Wasmtime when there was no other method to prevent an
infinite loop from the host. Nowadays, however, there are alternative
methods for interruption such as fuel or epoch-based interruption.

One of the major downsides of `Config::interruptable` is that even when
it's not enabled it forces an atomic swap to happen when entering
WebAssembly code. This technically could be a non-atomic swap if the
configuration option isn't enabled but that produces even more branch-y
code on entry into WebAssembly which is already something we try to
optimize. Calling into WebAssembly is on the order of a dozens of
nanoseconds at this time and an atomic swap, even uncontended, can add
up to 5ns on some platforms.

The main goal of this PR is to remove this atomic swap on entry into
WebAssembly. This is done by removing the `Config::interruptable` field
entirely, moving all existing consumers to epochs instead which are
suitable for the same purposes. This means that the stack overflow check
is no longer entangled with the interruption check and perhaps one day
we could continue to optimize that further as well.

Some consequences of this change are:

* Epochs are now the only method of remote-thread interruption.
* There are no more Wasmtime traps that produces the `Interrupted` trap
  code, although we may wish to move future traps to this so I left it
  in place.
* The C API support for interrupt handles was also removed and bindings
  for epoch methods were added.
* Function-entry checks for interruption are a tiny bit less efficient
  since one check is performed for the stack limit and a second is
  performed for the epoch as opposed to the `Config::interruptable`
  style of bundling the stack limit and the interrupt check in one. It's
  expected though that this is likely to not really be measurable.
* The old `VMInterrupts` structure is renamed to `VMRuntimeLimits`.
@github-actions github-actions Bot added fuzzing Issues related to our fuzzing infrastructure wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:c-api Issues pertaining to the C API. wasmtime:config Issues related to the configuration of Wasmtime wasmtime:docs Issues related to Wasmtime's documentation labels Mar 14, 2022
@github-actions
Copy link
Copy Markdown

Subscribe to Label Action

cc @fitzgen, @peterhuene

Details This issue or pull request has been labeled: "fuzzing", "wasmtime:api", "wasmtime:c-api", "wasmtime:config", "wasmtime:docs"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: fuzzing
  • peterhuene: wasmtime:api, wasmtime:c-api

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 14, 2022

Label Messager: wasmtime:config

It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:

  • If you added a new Config method, you wrote extensive documentation for
    it.

    Details

    Our documentation should be of the following form:

    Short, simple summary sentence.
    
    More details. These details can be multiple paragraphs. There should be
    information about not just the method, but its parameters and results as
    well.
    
    Is this method fallible? If so, when can it return an error?
    
    Can this method panic? If so, when does it panic?
    
    # Example
    
    Optional example here.
    
  • If you added a new Config method, or modified an existing one, you
    ensured that this configuration is exercised by the fuzz targets.

    Details

    For example, if you expose a new strategy for allocating the next instance
    slot inside the pooling allocator, you should ensure that at least one of our
    fuzz targets exercises that new strategy.

    Often, all that is required of you is to ensure that there is a knob for this
    configuration option in wasmtime_fuzzing::Config (or one
    of its nested structs).

    Rarely, this may require authoring a new fuzz target to specifically test this
    configuration. See our docs on fuzzing for more details.

  • If you are enabling a configuration option by default, make sure that it
    has been fuzzed for at least two weeks before turning it on by default.


Details

To modify this label's message, edit the .github/label-messager/wasmtime-config.md file.

To add new label messages or remove existing label messages, edit the
.github/label-messager.json configuration file.

Learn more.

Copy link
Copy Markdown
Member

@cfallin cfallin left a comment

Choose a reason for hiding this comment

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

LGTM -- this is a nice simplification!

Comment thread crates/c-api/include/wasmtime/engine.h Outdated
Comment thread crates/cranelift/src/func_environ.rs Outdated
Comment thread crates/wasmtime/src/config.rs Outdated
Comment thread crates/wasmtime/src/config.rs Outdated
Comment thread crates/c-api/include/wasmtime/store.h Outdated
@alexcrichton alexcrichton merged commit c22033b into bytecodealliance:main Mar 14, 2022
@alexcrichton alexcrichton deleted the delete-interurpts branch March 14, 2022 20:25
alexcrichton added a commit to alexcrichton/wasmtime-cpp that referenced this pull request Mar 15, 2022
alexcrichton added a commit to alexcrichton/wasmtime-go that referenced this pull request Mar 15, 2022
alexcrichton added a commit to alexcrichton/wasmtime-py that referenced this pull request Mar 15, 2022
alexcrichton added a commit to bytecodealliance/wasmtime-py that referenced this pull request Mar 15, 2022
alexcrichton added a commit to bytecodealliance/wasmtime-go that referenced this pull request Mar 15, 2022
alexcrichton added a commit to bytecodealliance/wasmtime-cpp that referenced this pull request Mar 15, 2022
* Remove InterruptHandle, bind epochs

Handles the changes made in bytecodealliance/wasmtime#3925

* Run clang-format
@theduke
Copy link
Copy Markdown
Contributor

theduke commented Apr 2, 2022

I would appreciate some guidance on how to achieve interruption support with async yielding now.

Before 0.35 I could use epoch_deadline_async_yield_and_update and use the InterruptHandle to do a hard abort.

The only idea I came up with is wrapping the call_async future with futures::future::Abortable, which would stop execution on the next epoch yield.

But maybe I'm missing a better solution?

@alexcrichton
Copy link
Copy Markdown
Member Author

Yes if you're using the epoch support for async yielding then you'll want to use a timeout-like approach to drop the future at an await point (or abortable as you mentioned) to stop execution of wasm altogether.

X-leaf7 added a commit to X-leaf7/wasmtime-go that referenced this pull request Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fuzzing Issues related to our fuzzing infrastructure wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:c-api Issues pertaining to the C API. wasmtime:config Issues related to the configuration of Wasmtime wasmtime:docs Issues related to Wasmtime's documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants