Skip to content

Commit 6b5734f

Browse files
authored
server: build Tokio runtime using oxide-tokio-rt (#913)
As described in [RFD 579], we are now recommending that the [`oxide-tokio-rt`] crate be used to construct the Tokio runtime in all production software that uses Tokio. This crate provides common functions for constructing Tokio runtimes with the recommended configurations. In particular, it currently does the following: - On illumos, configures the runtime to emit DTrace probes, using [`tokio-dtrace`]. - Disables Tokio's LIFO slot optimization. This feature is intended to improve message-passing latency, but because tasks in the LIFO slot do not currently participate in work-stealing, it can result in extreme latency spikes in some cases (see omicron#8334 for a worked example). Thus, this commit changes `propolis-server` to construct its Tokio runtimes using `oxide-tokio-rt` so that these common recommended configurations are included. This requires enabling Tokio's unstable features in the workspace. [RFD 579]: https://rfd.shared.oxide.computer/rfd/0579 [`oxide-tokio-rt`]: https://github.com/oxidecomputer/oxide-tokio-rt [`tokio-dtrace`]: https://github.com/oxidecomputer/tokio-dtrace
1 parent 199802d commit 6b5734f

8 files changed

Lines changed: 53 additions & 18 deletions

File tree

.cargo/config.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,11 @@ xtask = "run --package xtask --quiet --"
55
# Currently required by Falcon due to
66
# https://github.com/rust-lang/cargo/issues/3946#issuecomment-973132993
77
CARGO_WORKSPACE_DIR = { value = "", relative = true }
8+
9+
[build]
10+
# Tokio's unstable features are required by `tokio-dtrace` probes, and for
11+
# disabling the LIFO slot optimization.
12+
#
13+
# See here for details:
14+
# https://github.com/oxidecomputer/oxide-tokio-rt/blob/main/README.md#enabling-tokio_unstable-features
15+
rustflags = ["--cfg", "tokio_unstable"]

Cargo.lock

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ mockall = "0.12"
132132
newtype_derive = "0.1.6"
133133
newtype-uuid = { version = "1.0.1", features = [ "v4" ] }
134134
owo-colors = "4"
135+
oxide-tokio-rt = "0.1.2"
135136
pin-project-lite = "0.2.13"
136137
proc-macro2 = "1.0"
137138
proc-macro-error = "1"

bin/propolis-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ kstat-rs.workspace = true
3939
lazy_static.workspace = true
4040
nexus-client.workspace = true
4141
omicron-common.workspace = true
42+
oxide-tokio-rt.workspace = true
4243
oximeter-instruments.workspace = true
4344
oximeter-producer.workspace = true
4445
oximeter.workspace = true

bin/propolis-server/src/lib/vm/ensure.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,14 @@ impl<'a> VmEnsureNotStarted<'a> {
263263
let result: InitResult = tokio::task::spawn_blocking(move || {
264264
// Create the runtime that will host tasks created by
265265
// VMM components (e.g. block device runtime tasks).
266-
let vmm_rt = tokio::runtime::Builder::new_multi_thread()
267-
.thread_name("tokio-rt-vmm")
268-
.worker_threads(usize::max(
266+
let vmm_rt = {
267+
let mut builder = tokio::runtime::Builder::new_multi_thread();
268+
builder.thread_name("tokio-rt-vmm").worker_threads(usize::max(
269269
VMM_MIN_RT_THREADS,
270270
VMM_BASE_RT_THREADS + spec.board.cpus as usize,
271-
))
272-
.enable_all()
273-
.build()?;
271+
));
272+
oxide_tokio_rt::build(&mut builder)?
273+
};
274274

275275
let init_result = vmm_rt
276276
.block_on(async move {

bin/propolis-server/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,11 @@ fn run_server(
160160
// Spawn the runtime for handling API processing
161161
// If/when a VM instance is created, a separate runtime for handling device
162162
// emulation and other VM-related work will be spawned.
163-
let api_runtime = tokio::runtime::Builder::new_multi_thread()
164-
.worker_threads(API_RT_THREADS)
165-
.enable_all()
166-
.thread_name("tokio-rt-api")
167-
.build()?;
163+
let api_runtime = {
164+
let mut builder = tokio::runtime::Builder::new_multi_thread();
165+
builder.worker_threads(API_RT_THREADS).thread_name("tokio-rt-api");
166+
oxide_tokio_rt::build(&mut builder)?
167+
};
168168
let _guard = api_runtime.enter();
169169

170170
// Start TCP listener for VNC, if requested

bin/propolis-standalone/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ libc.workspace = true
2424
toml.workspace = true
2525
tokio = { workspace = true, features = ["io-util", "rt-multi-thread"] }
2626
serde = { workspace = true, features = ["derive"] }
27+
oxide-tokio-rt.workspace = true
2728
propolis.workspace = true
2829
propolis_types.workspace = true
2930
crucible-client-types = { workspace = true, optional = true }

bin/propolis-standalone/src/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,11 +1490,11 @@ fn main() -> anyhow::Result<ExitCode> {
14901490
// since we'll block in main when we call `Instance::wait_for_state`
14911491
let rt_threads =
14921492
MIN_RT_THREADS.max(BASE_RT_THREADS + config.main.cpus as usize);
1493-
let rt = tokio::runtime::Builder::new_multi_thread()
1494-
.worker_threads(rt_threads)
1495-
.enable_all()
1496-
.thread_name("vmm-tokio")
1497-
.build()?;
1493+
let rt = {
1494+
let mut builder = tokio::runtime::Builder::new_multi_thread();
1495+
builder.worker_threads(rt_threads).thread_name("vmm-tokio");
1496+
oxide_tokio_rt::build(&mut builder)?
1497+
};
14981498
let _rt_guard = rt.enter();
14991499

15001500
// Create the VM afresh or restore it from a snapshot

0 commit comments

Comments
 (0)