Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5782,6 +5782,7 @@ dependencies = [
"io-uring",
"libc",
"loan_cell",
"minircu",
"once_cell",
"pal",
"pal_async",
Expand Down
1 change: 1 addition & 0 deletions support/pal/pal_uring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ ci = []
[target.'cfg(target_os = "linux")'.dependencies]
inspect.workspace = true
loan_cell.workspace = true
minircu.workspace = true
pal.workspace = true
pal_async.workspace = true

Expand Down
21 changes: 21 additions & 0 deletions support/pal/pal_uring/src/threadpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,27 @@ impl Worker {
}
}

// About to block in io_uring_enter. Mark this thread
// as quiesced for the global RCU domain so that any
// concurrent `synchronize_blocking()` writer (e.g.
// `guestmem::rcu()` page-protection updates in
// OpenHCL's `underhill_mem`) can complete without
// issuing a process-wide `membarrier()` on our
// behalf. Without this, every worker that has ever
// polled a future containing a `guestmem` critical
// section stays registered as a non-quiesced RCU
// reader for the lifetime of the thread, forcing
// each writer to broadcast `membarrier(PRIVATE_
// EXPEDITED)` to every CPU. On large isolated VMs
// (e.g. 64-VP) that broadcast can stall long
// enough to trigger kernel `rcu_preempt self-
// detected stall` warnings in
// `smp_call_function_many_cond`. Re-entering a
// critical section after this issues a local
// memory barrier via `ThreadData::enter_slow`, so
// correctness is preserved.
minircu::global().quiesce();

state.worker.io_ring.submit_and_wait();
}
}
Expand Down
Loading