Skip to content

Conversation

@dicej
Copy link
Contributor

@dicej dicej commented Jan 20, 2026

Previously, we weren't creating a new thread or task in all cases when entering a component instance, even when component model async features were enabled. In particular, entering an instance via a sync-to-sync, guest-to-guest adapter, via Linker::instantiate[_async], or via [Typed]Func::call all skipped creating a thread or task, leading to panics and/or instance mismatches in certain cases.

This commit addresses all those cases and also adds assertions to all CM async intrinsics to verify that the caller instance matches the most-recently-pushed task. Note that we still skip pushing and popping threads and tasks if no CM async features are enabled in the Config.

In order to populate the GuestTask::instance field for tasks created as part of Linker::instantiate[_async] calls, I had to add a RuntimeComponentInstanceIndex field to GlobalInitializer::InstantiateModule and friends so it would be available when needed.

While testing this, I uncovered and fixed a couple of related issues:

  • We weren't checking the may_leave flag when guest-to-guest calling a resource destructor
  • We weren't checking whether a subtask was ready to delete (e.g. that no threads were still running) before attempting to delete it while deleting its supertask

@dicej dicej requested a review from alexcrichton January 20, 2026 22:54
@dicej dicej requested review from a team as code owners January 20, 2026 22:54
@github-actions github-actions bot added wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:config Issues related to the configuration of Wasmtime labels Jan 21, 2026
@github-actions
Copy link

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.

dicej added a commit to dicej/component-model that referenced this pull request Jan 22, 2026
While rebasing bytecodealliance/wasmtime#12379 onto
Wasmtime's `main` branch, I found I needed to tweak the expected resource handle
values and trap messages due to subtle changes to when Wasmtime allocates a
thread handle.  Once WebAssembly#600
lands and is implemented in Wasmtime, we should be able to clean all this up
once and for all; for now we just muddle along.
@dicej
Copy link
Contributor Author

dicej commented Jan 22, 2026

I've rebased this onto main and addressed the feedback so far locally. Once WebAssembly/component-model#601 is merged, I'll push my updates.

lukewagner pushed a commit to WebAssembly/component-model that referenced this pull request Jan 22, 2026
While rebasing bytecodealliance/wasmtime#12379 onto
Wasmtime's `main` branch, I found I needed to tweak the expected resource handle
values and trap messages due to subtle changes to when Wasmtime allocates a
thread handle.  Once #600
lands and is implemented in Wasmtime, we should be able to clean all this up
once and for all; for now we just muddle along.
@dicej dicej force-pushed the consistent-task-push branch from ea0b3fb to 200c24a Compare January 22, 2026 23:13
@dicej dicej requested a review from alexcrichton January 23, 2026 00:00
Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

Two other possible spots worth scrutinizing:

  • cabi_realloc invocations - probably don't need special treatment? Unsure.
  • ResourceAny::resource_drop - I think this'll need task-related treatment?

Although given the litany of entrypoints into wasm I'm finding it really hard to keep them all in sync, so it's probably also worth refactoring in theory to only have one entrypoint somewhere

@dicej
Copy link
Contributor Author

dicej commented Jan 23, 2026

* `cabi_realloc` invocations - probably don't need special treatment? Unsure.

As with post-return functions, we don't allow cabi_realloc functions to leave the instance.

* `ResourceAny::resource_drop` - I think this'll need task-related treatment?

Yup, I'll address that and add a test.

Although given the litany of entrypoints into wasm I'm finding it really hard to keep them all in sync, so it's probably also worth refactoring in theory to only have one entrypoint somewhere

I'll open an issue for that.

@alexcrichton
Copy link
Member

Right yeah cabi_realloc can't leave, but do we have tests for that?

dicej added 4 commits January 23, 2026 09:15
Previously, we weren't creating a new thread or task in all cases when entering
a component instance, even when component model async features were enabled.  In
particular, entering an instance via a sync-to-sync, guest-to-guest adapter, via
`Linker::instantiate[_async]`, or via `[Typed]Func::call` all skipped creating a
thread or task, creating panics and/or instance mismatches in certain cases.

This commit addresses all those cases and also adds assertions to all CM async
intrinsics to verify that the caller instance matches the most-recently-pushed
task.  Note that we still skip pushing and popping threads and tasks if no CM
async features are enabled in the `Config`.

In order to populate the `GuestTask::instance` field for tasks created as part
of `Linker::instantiate[_async]` calls, I had to add a
`RuntimeComponentInstanceIndex` field to `GlobalInitializer::InstantiateModule`
and friends so it would be available when needed.

While testing this, I uncovered and fixed a couple of related issues:

- We weren't checking the `may_leave` flag when guest-to-guest calling a resource destructor
- We weren't checking whether a subtask was ready to delete (e.g. that no threads were still running) before attempting to delete it while deleting its supertask
…tions

...and assert that the indexes match as expected.

Getting the post-return test to pass required moving the call to
`StoreOpaque::exit_sync_call` to after the post-return function is called.
@dicej dicej enabled auto-merge January 23, 2026 17:41
@dicej dicej added this pull request to the merge queue Jan 23, 2026
Merged via the queue into bytecodealliance:main with commit b271e45 Jan 23, 2026
45 checks passed
@dicej dicej deleted the consistent-task-push branch January 23, 2026 18:17
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Jan 23, 2026
This commit is an extension/refactor of bytecodealliance#12377 and bytecodealliance#12379. Notably this
decouples the runtime behavior of Wasmtime from enabled/disabled
WebAssembly proposals. This enables the `wasmtime serve` subcommand, for
example, to continue to disallow component-model-async by default but
continue to use `*_concurrent` under the hood.

Specifically a new `Config::concurrency_support` knob is added. This is
plumbed directly through to `Tunables` and takes over the preexisting
`component_model_concurrency` field. This field configures whether
tasks/etc are enabled at runtime for component-y things. The default
value of this configuration option is the same as `cfg!(feature =
"component-model-async")`, and this field is required if
component-model-async wasm proposals are enabled. It's intended that
eventually this'll affect on-by-default wasm features in Wasmtime
depending if the support is compiled in.

This results in a subtle shift in behavior where component-model-async
concurrency is used by default now because the feature is turned on by
default, even though the wasm features are off-by-default. This required
adjusting a few indices expected in runtime tests due to tasks/threads
being allocated in index spaces.

Finally, this additionally denies access at runtime to
`Linker::*_concurrent` when concurrent support is disabled as otherwise
the various runtime data structures won't be initialized and panics will
happen.

Closes bytecodealliance#12393
github-merge-queue bot pushed a commit that referenced this pull request Jan 23, 2026
* Document panics from using CM async machinery when CM async is not enabled

* Refactor how concurrency support is enabled in a `Store`

This commit is an extension/refactor of #12377 and #12379. Notably this
decouples the runtime behavior of Wasmtime from enabled/disabled
WebAssembly proposals. This enables the `wasmtime serve` subcommand, for
example, to continue to disallow component-model-async by default but
continue to use `*_concurrent` under the hood.

Specifically a new `Config::concurrency_support` knob is added. This is
plumbed directly through to `Tunables` and takes over the preexisting
`component_model_concurrency` field. This field configures whether
tasks/etc are enabled at runtime for component-y things. The default
value of this configuration option is the same as `cfg!(feature =
"component-model-async")`, and this field is required if
component-model-async wasm proposals are enabled. It's intended that
eventually this'll affect on-by-default wasm features in Wasmtime
depending if the support is compiled in.

This results in a subtle shift in behavior where component-model-async
concurrency is used by default now because the feature is turned on by
default, even though the wasm features are off-by-default. This required
adjusting a few indices expected in runtime tests due to tasks/threads
being allocated in index spaces.

Finally, this additionally denies access at runtime to
`Linker::*_concurrent` when concurrent support is disabled as otherwise
the various runtime data structures won't be initialized and panics will
happen.

Closes #12393

* Add a `-Wconcurrency-support` CLI flag

Used to update disas tests to show that, when disabled, old codegen
quality is preserved

* Ungate `Config` flag

* Review comments

---------

Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:config Issues related to the configuration of Wasmtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CM async] panic performing blocking operation during core start function

2 participants