Skip to content

Commit b500820

Browse files
Add support for the Linux PAGEMAP_SCAN ioctl (#11372)
* WIP: use the pagemap_scan ioctl to selectively reset an instance's dirty pages * Less hacky, and supporting tables, too * Bugfixes * WIP: memcpy instead of pread * Refactor support for pagemap * Don't hold a raw pointer to the original data, plumb through an `Arc` to have a safe reference instead. * Update pagemap bindings to latest version of abstraction written. * Include pagemap-specific tests. * Use a `PageMap` structure created once-per-pool instead of a static-with-a-file. * Refactor to use the "pagemap path" unconditionally which blends in the keep_resident bits. * Improve safety documentation prtest:full * Fix some lints * Skip ioctl tests when it's not supported * Fix a memory leak by moving impls around * Fix no vm build * Review comments * Add more pagemap-specific documentation * Add more docs, refactor implementation slightly * Improve `category_*` docs Basically forward to the Linux kernel source itself. * Fix compile * Make pagemap integration resilient across forks * Fix non-pooling-allocator-build * Fix portability issues of new test * Actually use config on macos --------- Co-authored-by: Till Schneidereit <till@tillschneidereit.net>
1 parent b2a25c3 commit b500820

15 files changed

Lines changed: 1581 additions & 255 deletions

File tree

crates/wasmtime/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ wasmtime-versioned-export-macros = { workspace = true, optional = true }
112112
name = "host_segfault"
113113
harness = false
114114

115+
[[test]]
116+
name = "engine_across_forks"
117+
harness = false
118+
115119
# =============================================================================
116120
#
117121
# Features for the Wasmtime crate.

crates/wasmtime/src/runtime/module.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::prelude::*;
22
#[cfg(feature = "std")]
33
use crate::runtime::vm::open_file_for_mmap;
4-
use crate::runtime::vm::{CompiledModuleId, ModuleMemoryImages, VMWasmCallFunction};
4+
use crate::runtime::vm::{CompiledModuleId, MmapVec, ModuleMemoryImages, VMWasmCallFunction};
55
use crate::sync::OnceLock;
66
use crate::{
77
Engine,
@@ -1114,7 +1114,7 @@ impl Module {
11141114
let images = self
11151115
.inner
11161116
.memory_images
1117-
.get_or_try_init(|| memory_images(&self.inner.engine, &self.inner.module))?
1117+
.get_or_try_init(|| memory_images(&self.inner))?
11181118
.as_ref();
11191119
Ok(images)
11201120
}
@@ -1164,21 +1164,30 @@ fn _assert_send_sync() {
11641164

11651165
/// Helper method to construct a `ModuleMemoryImages` for an associated
11661166
/// `CompiledModule`.
1167-
fn memory_images(engine: &Engine, module: &CompiledModule) -> Result<Option<ModuleMemoryImages>> {
1167+
fn memory_images(inner: &Arc<ModuleInner>) -> Result<Option<ModuleMemoryImages>> {
11681168
// If initialization via copy-on-write is explicitly disabled in
11691169
// configuration then this path is skipped entirely.
1170-
if !engine.tunables().memory_init_cow {
1170+
if !inner.engine.tunables().memory_init_cow {
11711171
return Ok(None);
11721172
}
11731173

11741174
// ... otherwise logic is delegated to the `ModuleMemoryImages::new`
11751175
// constructor.
1176-
let mmap = if engine.config().force_memory_init_memfd {
1177-
None
1178-
} else {
1179-
Some(module.mmap())
1180-
};
1181-
ModuleMemoryImages::new(module.module(), module.code_memory().wasm_data(), mmap)
1176+
ModuleMemoryImages::new(
1177+
&inner.engine,
1178+
inner.module.module(),
1179+
inner.code.code_memory(),
1180+
)
1181+
}
1182+
1183+
impl crate::vm::ModuleMemoryImageSource for CodeMemory {
1184+
fn wasm_data(&self) -> &[u8] {
1185+
<Self>::wasm_data(self)
1186+
}
1187+
1188+
fn mmap(&self) -> Option<&MmapVec> {
1189+
Some(<Self>::mmap(self))
1190+
}
11821191
}
11831192

11841193
#[cfg(test)]

crates/wasmtime/src/runtime/vm.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ mod imports;
6060
mod instance;
6161
mod memory;
6262
mod mmap_vec;
63+
#[cfg(has_virtual_memory)]
64+
mod pagemap_disabled;
6365
mod provenance;
6466
mod send_sync_ptr;
6567
mod stack_switching;
@@ -161,6 +163,17 @@ cfg_if::cfg_if! {
161163
}
162164
}
163165

166+
/// Source of data used for [`MemoryImage`]
167+
pub trait ModuleMemoryImageSource: Send + Sync + 'static {
168+
/// Returns this image's slice of all wasm data for a module which is then
169+
/// further sub-sliced for a particular initialization segment.
170+
fn wasm_data(&self) -> &[u8];
171+
172+
/// Optionally returns the backing mmap. Used for using the backing mmap's
173+
/// file to perform other mmaps, for example.
174+
fn mmap(&self) -> Option<&MmapVec>;
175+
}
176+
164177
/// Dynamic runtime functionality needed by this crate throughout the execution
165178
/// of a wasm instance.
166179
///

0 commit comments

Comments
 (0)