From: John Kacur <jkacur@redhat.com>
To: linux-rt-users@vger.kernel.org
Cc: Clark Williams <williams@redhat.com>, Tomas Glozar <tglozar@redhat.com>
Subject: [PATCH 6/6] rteval: Add --housekeeping option to reserve isolated CPUs
Date: Fri, 17 Apr 2026 15:51:13 -0400 [thread overview]
Message-ID: <20260417195113.177799-7-jkacur@redhat.com> (raw)
In-Reply-To: <20260417195113.177799-1-jkacur@redhat.com>
Add a new --housekeeping option that allows users to specify isolated CPUs
that should be reserved for system housekeeping tasks and not used by
rteval's measurement or load modules.
Key features:
- Validates that housekeeping CPUs are in the isolated CPU list (isolcpus)
- Detects conflicts with explicitly specified --measurement-cpulist or
--loads-cpulist options and exits with a clear error message
- Filters housekeeping CPUs from both measurement and load CPU lists
- Correctly excludes housekeeping CPUs from inverted CPU lists when only
one of measurement/loads is specified
Example usage:
rteval --housekeeping 0-3 --measurement-run-on-isolcpus
Reserves isolcpus 0-3 for system tasks, runs measurements on
remaining isolated CPUs (4+) plus non-isolated CPUs
Implementation:
- systopology.py: Add validate_housekeeping_cpus() function to validate
that housekeeping CPUs are in isolcpus
- rteval-cmd: Add --housekeeping argument, conflict checking, filtering,
and fix inversion logic to exclude housekeeping CPUs
This feature is purely additive and does not change existing behavior
when --housekeeping is not specified.
Assisted-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval-cmd | 46 ++++++++++++++++++++++++++++++++++++++++++-
rteval/systopology.py | 24 ++++++++++++++++++++++
2 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/rteval-cmd b/rteval-cmd
index 0ad90cf29ec4..a903b537c891 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
+from rteval.systopology import SysTopology, parse_cpulist_from_config, validate_housekeeping_cpus
from rteval.modules.loads.kcompile import ModuleParameters
from rteval.cpulist_utils import CpuList, is_relative, collapse_cpulist
@@ -113,6 +113,9 @@ def parse_options(cfg, parser, cmdargs):
parser.add_argument("-i", "--installdir", dest="rteval___installdir",
type=str, default=rtevcfg.installdir, metavar="DIRECTORY",
help=f"place to locate installed templates (default: {rtevcfg.installdir})")
+ parser.add_argument("--housekeeping", dest="rteval___housekeeping",
+ type=str, default="", metavar="CPULIST",
+ help="isolated CPUs reserved for system tasks (not used by rteval)")
parser.add_argument("-s", "--sysreport", dest="rteval___sysreport",
action="store_true", default=rtevcfg.sysreport,
help=f'run sysreport to collect system data (default: {rtevcfg.sysreport})')
@@ -370,6 +373,13 @@ if __name__ == '__main__':
ldcfg = config.GetSection('loads')
msrcfg = config.GetSection('measurement')
+
+ # Validate and process housekeeping CPUs
+ housekeeping_cpus = []
+ if rtevcfg.housekeeping:
+ housekeeping_cpus = validate_housekeeping_cpus(rtevcfg.housekeeping)
+ logger.log(Log.DEBUG, f"housekeeping cpulist: {collapse_cpulist(housekeeping_cpus)}")
+
# Remember if cpulists were explicitly set by the user before running
# parse_cpulist_from_config, which generates default value for them
msrcfg_cpulist_present = msrcfg.cpulist != ""
@@ -382,17 +392,51 @@ if __name__ == '__main__':
msrcfg.cpulist = collapse_cpulist(cpulist)
cpulist = parse_cpulist_from_config(ldcfg.cpulist)
ldcfg.cpulist = collapse_cpulist(cpulist)
+
+ # Check for conflicts between housekeeping and measurement/load cpulists
+ if housekeeping_cpus:
+ msrcfg_cpus = CpuList(msrcfg.cpulist).cpus if msrcfg.cpulist else []
+ ldcfg_cpus = CpuList(ldcfg.cpulist).cpus if ldcfg.cpulist else []
+
+ # Check measurement conflicts
+ if msrcfg_cpulist_present:
+ conflicts = [cpu for cpu in housekeeping_cpus if cpu in msrcfg_cpus]
+ if conflicts:
+ raise RuntimeError(
+ f"Housekeeping CPUs {collapse_cpulist(conflicts)} conflict with "
+ f"--measurement-cpulist {msrcfg.cpulist}"
+ )
+
+ # Check load conflicts
+ if ldcfg_cpulist_present:
+ conflicts = [cpu for cpu in housekeeping_cpus if cpu in ldcfg_cpus]
+ if conflicts:
+ raise RuntimeError(
+ f"Housekeeping CPUs {collapse_cpulist(conflicts)} conflict with "
+ f"--loads-cpulist {ldcfg.cpulist}"
+ )
+
+ # Filter out housekeeping CPUs from measurement and load lists
+ msrcfg_cpus = [cpu for cpu in msrcfg_cpus if cpu not in housekeeping_cpus]
+ ldcfg_cpus = [cpu for cpu in ldcfg_cpus if cpu not in housekeeping_cpus]
+ msrcfg.cpulist = collapse_cpulist(msrcfg_cpus) if msrcfg_cpus else ""
+ ldcfg.cpulist = collapse_cpulist(ldcfg_cpus) if ldcfg_cpus else ""
+
# if we only specified one set of cpus (loads or measurement)
# default the other to the inverse of the specified list
if not ldcfg_cpulist_present and msrcfg_cpulist_present:
tmplist = CpuList(msrcfg.cpulist).cpus
tmplist = SysTopology().invert_cpulist(tmplist)
tmplist = CpuList(tmplist).online().cpus
+ # Exclude housekeeping CPUs from the inverted list
+ tmplist = [cpu for cpu in tmplist if cpu not in housekeeping_cpus]
ldcfg.cpulist = collapse_cpulist(tmplist)
if not msrcfg_cpulist_present and ldcfg_cpulist_present:
tmplist = CpuList(ldcfg.cpulist).cpus
tmplist = SysTopology().invert_cpulist(tmplist)
tmplist = CpuList(tmplist).online().cpus
+ # Exclude housekeeping CPUs from the inverted list
+ tmplist = [cpu for cpu in tmplist if cpu not in housekeeping_cpus]
msrcfg.cpulist = collapse_cpulist(tmplist)
if ldcfg_cpulist_present:
diff --git a/rteval/systopology.py b/rteval/systopology.py
index 7305fc278995..5f2bc291f608 100644
--- a/rteval/systopology.py
+++ b/rteval/systopology.py
@@ -239,6 +239,30 @@ class SysTopology:
return [c for c in self.online_cpus() if c in cpulist]
+def validate_housekeeping_cpus(housekeeping_cpulist):
+ """
+ Validates that housekeeping CPUs are in isolated CPU list
+ :param housekeeping_cpulist: CPU list string for housekeeping CPUs
+ :return: Sorted list of validated housekeeping CPUs as integers
+ :raises: RuntimeError if housekeeping CPUs are not in isolcpus
+ """
+ if not housekeeping_cpulist:
+ return []
+
+ housekeeping = CpuList(housekeeping_cpulist).online().cpus
+ isolcpus = SysTopology().isolated_cpus()
+
+ # Check if all housekeeping CPUs are in isolcpus
+ not_isolated = [cpu for cpu in housekeeping if cpu not in isolcpus]
+ if not_isolated:
+ isolcpus_str = collapse_cpulist(isolcpus) if isolcpus else "none"
+ raise RuntimeError(
+ f"Housekeeping CPUs {collapse_cpulist(not_isolated)} are not in isolated CPUs [{isolcpus_str}]"
+ )
+
+ return sorted(housekeeping)
+
+
def parse_cpulist_from_config(cpulist, run_on_isolcpus=False):
"""
Generates a cpulist based on --*-cpulist argument given by user
--
2.53.0
next prev parent reply other threads:[~2026-04-17 19:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-17 19:51 [PATCH 0/6] rteval: Improve CPU management infrastructure and add housekeeping option John Kacur
2026-04-17 19:51 ` [PATCH 1/6] rteval: Add cpuset module for cgroup v2 management John Kacur
2026-04-17 19:51 ` [PATCH 2/6] rteval: Fix xmlout unit test XSL file path John Kacur
2026-04-17 19:51 ` [PATCH 3/6] rteval: Add CpuList class to cpulist_utils module John Kacur
2026-04-17 19:51 ` [PATCH 4/6] rteval: Migrate call sites to use CpuList class where beneficial John Kacur
2026-04-17 19:51 ` [PATCH 5/6] rteval: Add unit tests for CpuList class John Kacur
2026-04-17 19:51 ` John Kacur [this message]
2026-04-20 9:33 ` [PATCH 6/6] rteval: Add --housekeeping option to reserve isolated CPUs Tomas Glozar
2026-04-20 21:42 ` John Kacur
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260417195113.177799-7-jkacur@redhat.com \
--to=jkacur@redhat.com \
--cc=linux-rt-users@vger.kernel.org \
--cc=tglozar@redhat.com \
--cc=williams@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox