[PATCH 2/7] rteval: Add core sharing validation for CPU isolation
John Kacur <[email protected]> Tue, 21 Apr 2026 14:26:13 -0400
| Newsgroups | org.kernel.vger.linux-rt-users |
|---|---|
| Message-ID | <[email protected]> |
Add validation to detect and warn when CPUs sharing physical cores are assigned to different workload types (housekeeping, measurement, load). When SMT/hyperthreading is enabled, CPUs sharing a physical core also share L1/L2 caches, execution units, TLB, and other core-level resources. Running different workload types on sibling threads defeats CPU isolation and can corrupt real-time measurements or create unreproducible results. Key features: - Uses CoreSiblings class to detect which CPUs share physical cores - Only warns when at least one CPU in a pair is isolated (via isolcpus) - Checks all three workload type combinations: * Housekeeping vs Measurement * Housekeeping vs Load * Measurement vs Load - Warning format clearly indicates which CPUs are isolated with "(isol)" marker Example warning: Warning: Housekeeping CPU 0 (isol) shares core with measurement CPU 8 (isol) Implementation: - coresiblings.py: Add comment explaining SMT-enabled/disabled behavior - systopology.py: Add validate_core_sharing() function - rteval-cmd: Call validation after CPU lists are finalized and log warnings This validation is purely informational - it warns users but does not prevent execution, allowing users to make informed decisions about their CPU configurations. Assisted-by: Claude Sonnet 4.5 <[email protected]> Signed-off-by: John Kacur <[email protected]> --- rteval-cmd | 8 ++++- rteval/sysinfo/coresiblings.py | 8 ++++- rteval/systopology.py | 55 ++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/rteval-cmd b/rteval-cmd index a903b537c891..f0efb0117726 100755 --- a/rteval-cmd +++ b/rteval-cmd @@ -31,7 +31,7 @@ from rteval.modules.loads import LoadModules from rteval.modules.measurement import MeasurementModules from rteval import cpupower from rteval.version import RTEVAL_VERSION -from rteval.systopology import SysTopology, parse_cpulist_from_config, validate_housekeeping_cpus +from rteval.systopology import SysTopology, parse_cpulist_from_config, validate_housekeeping_cpus, validate_core_sharing from rteval.modules.loads.kcompile import ModuleParameters from rteval.cpulist_utils import CpuList, is_relative, collapse_cpulist @@ -446,6 +446,12 @@ if __name__ == '__main__': logger.log(Log.DEBUG, f"measurement cpulist: {msrcfg.cpulist}") logger.log(Log.DEBUG, f"workdir: {rtevcfg.workdir}") + # Validate core sharing between housekeeping, measurement, and load CPUs + if housekeeping_cpus or msrcfg_cpus or ldcfg_cpus: + core_warnings = validate_core_sharing(housekeeping_cpus, msrcfg_cpus, ldcfg_cpus) + for warning in core_warnings: + logger.log(Log.WARN, warning) + # if --summarize was specified then just parse the XML, print it and exit if cmd_opts.rteval___summarize: for xmlfile in cmd_opts.rteval___summarize: diff --git a/rteval/sysinfo/coresiblings.py b/rteval/sysinfo/coresiblings.py index 3c97439d0a39..d55a4b699149 100644 --- a/rteval/sysinfo/coresiblings.py +++ b/rteval/sysinfo/coresiblings.py @@ -8,7 +8,13 @@ import os from rteval.cpulist_utils import expand_cpulist class CoreSiblings: - """Query CPU core topology to determine which CPUs share physical cores""" + """ + Query CPU core topology to determine which CPUs share physical cores + + Note: This class works correctly whether SMT/hyperthreading is enabled or disabled. + When SMT is disabled, each CPU's thread_siblings_list contains only itself, + so the class will correctly report that no CPUs share cores. + """ def __init__(self, root="/"): self.sysdir = os.path.join(root, 'sys', 'devices', 'system', 'cpu') diff --git a/rteval/systopology.py b/rteval/systopology.py index 5f2bc291f608..0ee81d5c5e36 100644 --- a/rteval/systopology.py +++ b/rteval/systopology.py @@ -294,6 +294,61 @@ def parse_cpulist_from_config(cpulist, run_on_isolcpus=False): return result +def validate_core_sharing(housekeeping_cpus, measurement_cpus, load_cpus): + """ + Check for CPUs sharing physical cores across different workload types. + Warns if isolated CPUs share cores between housekeeping, measurement, and load groups. + + :param housekeeping_cpus: List of housekeeping CPU integers + :param measurement_cpus: List of measurement CPU integers + :param load_cpus: List of load CPU integers + :return: List of warning messages (empty if no issues) + """ + from rteval.sysinfo.coresiblings import CoreSiblings + + warnings = [] + + # Get isolated CPUs + isolated_cpus = set(SysTopology().isolated_cpus()) + + # Create CoreSiblings instance + try: + cs = CoreSiblings() + except Exception: + # If we can't read topology, skip validation + return warnings + + def check_pair(cpu1, cpu2, type1, type2): + """Check if two CPUs share a core and generate warning if at least one is isolated""" + if cs.share_core(cpu1, cpu2): + cpu1_isol = cpu1 in isolated_cpus + cpu2_isol = cpu2 in isolated_cpus + + # Only warn if at least one CPU is isolated + if cpu1_isol or cpu2_isol: + cpu1_str = f"{type1} CPU {cpu1}{' (isol)' if cpu1_isol else ''}" + cpu2_str = f"{type2} CPU {cpu2}{' (isol)' if cpu2_isol else ''}" + warnings.append(f"Warning: {cpu1_str} shares core with {cpu2_str}") + + # Check all three combinations + # 1. Housekeeping vs Measurement + for hk_cpu in housekeeping_cpus: + for msr_cpu in measurement_cpus: + check_pair(hk_cpu, msr_cpu, "Housekeeping", "measurement") + + # 2. Housekeeping vs Load + for hk_cpu in housekeeping_cpus: + for ld_cpu in load_cpus: + check_pair(hk_cpu, ld_cpu, "Housekeeping", "load") + + # 3. Measurement vs Load + for msr_cpu in measurement_cpus: + for ld_cpu in load_cpus: + check_pair(msr_cpu, ld_cpu, "Measurement", "load") + + return warnings + + if __name__ == "__main__": def unit_test(): -- 2.53.0