pub struct Topology {
pub llcs: u32,
pub cores_per_llc: u32,
pub threads_per_core: u32,
pub numa_nodes: u32,
pub nodes: Option<&'static [NumaNode]>,
pub distances: Option<&'static NumaDistance>,
}Expand description
Re-exports of topology types for use in KtstrTestEntry statics
generated by the #[ktstr_test] macro.
CPU topology specification with NUMA memory topology.
Models the hierarchy: NUMA nodes → LLCs → cores → threads.
Each NUMA node owns a contiguous range of LLCs and a memory region.
When nodes is None (the default), memory and LLCs are distributed
uniformly across numa_nodes synthetic nodes with 10/20 distances.
Use new for the simple uniform case, or
with_nodes for explicit per-node configuration.
Fields§
§llcs: u32Total number of last-level caches across the whole VM; must be
a multiple of numa_nodes when nodes is None.
cores_per_llc: u32Physical cores grouped into each LLC.
threads_per_core: u32Hardware threads exposed per core (1 = no SMT, 2 = SMT-2).
numa_nodes: u32Number of NUMA nodes.
nodes: Option<&'static [NumaNode]>Per-node configuration. When None, LLCs and memory are
distributed uniformly. When Some, the slice length must
equal numa_nodes and the sum of all NumaNode::llcs must
equal self.llcs.
distances: Option<&'static NumaDistance>Inter-node distance matrix. When None, distances default to
10 (local) / 20 (remote). When Some, the matrix dimension
must equal numa_nodes.
Implementations§
Source§impl Topology
impl Topology
Sourcepub const DEFAULT_FOR_PAYLOAD: Topology
pub const DEFAULT_FOR_PAYLOAD: Topology
Fallback topology used by
Payload::topology
for binary-kind payloads that have no scheduler-side topology
opinion. Matches the inline default in
KtstrTestEntry::DEFAULT:
1 NUMA node / 1 LLC / 2 cores / 1 thread (2 CPUs total), the
smallest VM shape that runs the harness meaningfully.
Sourcepub const fn new(
numa_nodes: u32,
llcs: u32,
cores_per_llc: u32,
threads_per_core: u32,
) -> Self
pub const fn new( numa_nodes: u32, llcs: u32, cores_per_llc: u32, threads_per_core: u32, ) -> Self
Validated const constructor for uniform topologies.
Produces a topology where LLCs and memory are distributed evenly across NUMA nodes, with default 10/20 distances.
See validate for a non-panicking alternative.
§Panics
Panics if any invariant is violated:
- any of
llcs,cores_per_llc,threads_per_core,numa_nodesis zero llcsis not divisible bynuma_nodes- total CPU count (
llcs * cores_per_llc * threads_per_core) overflowsu32
Sourcepub const fn with_nodes(
cores_per_llc: u32,
threads_per_core: u32,
nodes: &'static [NumaNode],
) -> Self
pub const fn with_nodes( cores_per_llc: u32, threads_per_core: u32, nodes: &'static [NumaNode], ) -> Self
Const constructor with explicit per-node configuration.
Total LLC count is computed from the sum of NumaNode::llcs
across all nodes. Memory-only nodes (llcs=0) are permitted.
§Panics
Panics if:
nodesis emptycores_per_llc == 0threads_per_core == 0- node LLC sum overflows
u32 - a CPU-bearing node (
llcs > 0) hasmemory_mib == 0 - total CPU count overflows
u32 - no node has LLCs (at least one must have
llcs > 0)
Sourcepub const fn distances(self, distances: &'static NumaDistance) -> Self
pub const fn distances(self, distances: &'static NumaDistance) -> Self
Attach a distance matrix.
§Panics
Panics if distances.n != self.numa_nodes — the matrix
dimension must equal the topology’s NUMA node count.
Sourcepub fn validate(&self) -> Result<(), String>
pub fn validate(&self) -> Result<(), String>
Non-panicking validation.
Returns Ok(()) if all invariants hold, or Err with a
description of the first violated invariant.
Sourcepub fn total_cpus(&self) -> u32
pub fn total_cpus(&self) -> u32
Total vCPU count = llcs * cores_per_llc * threads_per_core.
Sourcepub fn num_numa_nodes(&self) -> u32
pub fn num_numa_nodes(&self) -> u32
Number of NUMA nodes in the topology.
Sourcepub fn llcs_in_node(&self, node_id: u32) -> u32
pub fn llcs_in_node(&self, node_id: u32) -> u32
LLCs owned by NUMA node node_id.
With explicit nodes, returns nodes[node_id].llcs.
With uniform distribution, returns llcs / numa_nodes.
Sourcepub fn llcs_per_numa_node(&self) -> u32
pub fn llcs_per_numa_node(&self) -> u32
LLCs per NUMA node (uniform distribution only).
§Panics
Panics if the topology uses explicit nodes (use
llcs_in_node instead), if
numa_nodes == 0, or if llcs is not divisible by
numa_nodes.
Sourcepub fn numa_node_of(&self, llc_id: u32) -> u32
pub fn numa_node_of(&self, llc_id: u32) -> u32
NUMA node that owns the given LLC index.
With explicit nodes, walks the node list to find the owning node.
With uniform distribution, computes llc_id / llcs_per_node.
Out-of-bounds llc_id (>= total LLCs): with explicit nodes,
saturates to the last node index; with uniform distribution, no
bounds check — returns llc_id / llcs_per_node, which may
exceed numa_nodes - 1.
Sourcepub fn first_llc_in_node(&self, node_id: u32) -> u32
pub fn first_llc_in_node(&self, node_id: u32) -> u32
First LLC index owned by NUMA node node_id.
Uniform topologies do not bounds-check and return
node_id * llcs_per_node for any input.
§Panics
Panics if node_id > numa_nodes for explicit-node topologies
(the walk would index past the end of the node slice).
Sourcepub fn node_memory_mib(&self, node_id: u32) -> Option<u32>
pub fn node_memory_mib(&self, node_id: u32) -> Option<u32>
Memory in MiB for NUMA node node_id.
With explicit nodes, returns nodes[node_id].memory_mib.
With uniform distribution, returns None (caller must divide
total memory evenly).
Sourcepub fn total_node_memory_mib(&self) -> Option<u32>
pub fn total_node_memory_mib(&self) -> Option<u32>
Total memory across all explicit nodes, or None for uniform.
Sourcepub fn distance(&self, i: u32, j: u32) -> u8
pub fn distance(&self, i: u32, j: u32) -> u8
Distance from node i to node j.
Returns the explicit distance if a matrix is attached, otherwise 10 for local and 20 for remote.
Sourcepub fn has_memory_only_nodes(&self) -> bool
pub fn has_memory_only_nodes(&self) -> bool
Whether any node is memory-only (CXL).
Sourcepub fn cpu_bearing_nodes(&self) -> u32
pub fn cpu_bearing_nodes(&self) -> u32
Number of nodes that have CPUs (non-memory-only).
Trait Implementations§
Source§impl Display for Topology
Formats as {numa}n{llcs}l{cores}c{threads}t — e.g. 1n2l4c2t =
1 NUMA node, 2 LLCs, 4 cores/LLC, 2 threads/core.
impl Display for Topology
Formats as {numa}n{llcs}l{cores}c{threads}t — e.g. 1n2l4c2t =
1 NUMA node, 2 LLCs, 4 cores/LLC, 2 threads/core.
Source§impl From<Topology> for TopologyJson
Project a Topology into its wire-format mirror. Drops the
nodes and distances fields (uniform-distribution shape only);
callers that need to preserve explicit per-node config or distance
matrices must not use this conversion. Takes Topology by value
(it derives Copy) to match the by-value shape of
[From<TopologyConstraintsJson> for TopologyConstraints].
impl From<Topology> for TopologyJson
Project a Topology into its wire-format mirror. Drops the
nodes and distances fields (uniform-distribution shape only);
callers that need to preserve explicit per-node config or distance
matrices must not use this conversion. Takes Topology by value
(it derives Copy) to match the by-value shape of
[From<TopologyConstraintsJson> for TopologyConstraints].
Source§impl FromStr for Topology
Parse the Display format back into a
uniform Topology with nodes = None and distances = None.
impl FromStr for Topology
Parse the Display format back into a
uniform Topology with nodes = None and distances = None.
§Lossy round-trip
Only topologies built via Topology::new (uniform layout, no
per-node configuration, default 10/20 distances) round-trip cleanly
through Display → FromStr. A
Topology built via Topology::with_nodes or chained with
Topology::distances loses its per-node config + custom distance
matrix through Display (which serializes only the 4 primitives);
FromStr cannot reconstruct that information and produces a uniform
Topology instead. Use the Topology value directly when full
fidelity is required.
Source§impl TryFrom<TopologyJson> for Topology
Result-based validation for wire-format topology values. Lets the
verifier dispatch surface a per-cell “topology rejected” diagnostic
instead of taking the Topology::new panic surface in the builder.
Mirrors Topology::validate — any field == 0, overflow in total
CPU count, or llcs not divisible by numa_nodes returns Err.
The result is a uniform-distribution Topology (nodes = None,
distances = None); explicit per-node config and distance matrices
require constructing Topology directly.
impl TryFrom<TopologyJson> for Topology
Result-based validation for wire-format topology values. Lets the
verifier dispatch surface a per-cell “topology rejected” diagnostic
instead of taking the Topology::new panic surface in the builder.
Mirrors Topology::validate — any field == 0, overflow in total
CPU count, or llcs not divisible by numa_nodes returns Err.
The result is a uniform-distribution Topology (nodes = None,
distances = None); explicit per-node config and distance matrices
require constructing Topology directly.
impl Copy for Topology
impl Eq for Topology
impl StructuralPartialEq for Topology
Auto Trait Implementations§
impl Freeze for Topology
impl RefUnwindSafe for Topology
impl Send for Topology
impl Sync for Topology
impl Unpin for Topology
impl UnwindSafe for Topology
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more