Make latency tests exclusive, add --noload, and switch to autosetup
Prevent using cyclictest and timerlat at the same time Resolves: RHEL-35507 Add a --no-load option Resolves: RHEL-50324 Switch to autosetup, which avoids the need to list every patch in the prep section Signed-off-by: Crystal Wood <crwood@redhat.com>
This commit is contained in:
parent
2128ea4625
commit
849faebf5a
190
rteval-Add-noload-option.patch
Normal file
190
rteval-Add-noload-option.patch
Normal file
@ -0,0 +1,190 @@
|
||||
From 1a76277bc6a5e94d858497fdc8fa721540fa6af7 Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Fri, 19 Jul 2024 14:58:41 -0500
|
||||
Subject: [PATCH 5/7] rteval: Add --noload option
|
||||
|
||||
This option allows measurement to be done without any loads.
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||||
---
|
||||
doc/rteval.8 | 3 +++
|
||||
rteval-cmd | 9 +++++++
|
||||
rteval/__init__.py | 54 ++++++++++++++++++++++--------------------
|
||||
rteval/rtevalReport.py | 3 ++-
|
||||
rteval/rteval_text.xsl | 9 ++++++-
|
||||
5 files changed, 50 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/doc/rteval.8 b/doc/rteval.8
|
||||
index 9e2b377752e5..1981ac7b3913 100644
|
||||
--- a/doc/rteval.8
|
||||
+++ b/doc/rteval.8
|
||||
@@ -108,6 +108,9 @@ Print rteval version and exit.
|
||||
.TP
|
||||
.B \-S KERNEL_VERSION, \-\-source\-download=KERNEL_VERSION
|
||||
download a source kernel from kernel.org and exit
|
||||
+.TP
|
||||
+.B \-\-noload
|
||||
+Only run the measurements (don't run loads)
|
||||
|
||||
.SH GROUP OPTIONS
|
||||
.TP
|
||||
diff --git a/rteval-cmd b/rteval-cmd
|
||||
index 5cb6d7a44523..36b167a034e5 100755
|
||||
--- a/rteval-cmd
|
||||
+++ b/rteval-cmd
|
||||
@@ -146,6 +146,9 @@ def parse_options(cfg, parser, cmdargs):
|
||||
parser.add_argument("-S", "--source-download", nargs="*", dest="rteval___srcdownload",
|
||||
type=str, default=None, metavar="KERNEL_VERSION",
|
||||
help='download a source kernel from kernel.org and exit')
|
||||
+ parser.add_argument("--noload", dest="rteval___noload",
|
||||
+ action="store_true", default=False,
|
||||
+ help="only run the measurements (don't run loads)")
|
||||
|
||||
|
||||
if not cmdargs:
|
||||
@@ -273,6 +276,12 @@ if __name__ == '__main__':
|
||||
measuremods.SetupModuleOptions(parser)
|
||||
cmd_args = parse_options(config, parser, sys.argv[1:])
|
||||
|
||||
+ if rtevcfg.noload:
|
||||
+ if rtevcfg.onlyload:
|
||||
+ # Make up your mind!
|
||||
+ raise RuntimeError('The --noload and --onlyload options are incompatible.')
|
||||
+ loadmods = None
|
||||
+
|
||||
# download kernel tarball
|
||||
if rtevcfg.srcdownload:
|
||||
logger.log(Log.DEBUG, f"Kernel Version to download = {rtevcfg.srcdownload}")
|
||||
diff --git a/rteval/__init__.py b/rteval/__init__.py
|
||||
index 226d14f80f48..4d3e0c23e5ab 100644
|
||||
--- a/rteval/__init__.py
|
||||
+++ b/rteval/__init__.py
|
||||
@@ -46,9 +46,6 @@ class RtEval(rtevalReport):
|
||||
if not isinstance(config, rtevalConfig.rtevalConfig):
|
||||
raise TypeError("config variable is not an rtevalConfig object")
|
||||
|
||||
- if not isinstance(loadmods, LoadModules):
|
||||
- raise TypeError("loadmods variable is not a LoadModules object")
|
||||
-
|
||||
if not isinstance(measuremods, MeasurementModules):
|
||||
raise TypeError("measuremods variable is not a MeasurementModules object")
|
||||
|
||||
@@ -111,20 +108,21 @@ class RtEval(rtevalReport):
|
||||
except Exception as err:
|
||||
raise RuntimeError(f"Cannot create report directory (NFS with rootsquash on?) [{err}]]")
|
||||
|
||||
+ params = {'workdir':self.__rtevcfg.workdir,
|
||||
+ 'reportdir':self.__reportdir and self.__reportdir or "",
|
||||
+ 'builddir':builddir,
|
||||
+ 'srcdir':self.__rtevcfg.srcdir,
|
||||
+ 'verbose': self.__rtevcfg.verbose,
|
||||
+ 'debugging': self.__rtevcfg.debugging,
|
||||
+ 'numcores':self._sysinfo.cpu_getCores(True),
|
||||
+ 'logging':self.__rtevcfg.logging,
|
||||
+ 'memsize':self._sysinfo.mem_get_size(),
|
||||
+ 'numanodes':self._sysinfo.mem_get_numa_nodes(),
|
||||
+ 'duration': float(self.__rtevcfg.duration),
|
||||
+ }
|
||||
+
|
||||
if self._loadmods:
|
||||
self.__logger.log(Log.INFO, "Preparing load modules")
|
||||
- params = {'workdir':self.__rtevcfg.workdir,
|
||||
- 'reportdir':self.__reportdir and self.__reportdir or "",
|
||||
- 'builddir':builddir,
|
||||
- 'srcdir':self.__rtevcfg.srcdir,
|
||||
- 'verbose': self.__rtevcfg.verbose,
|
||||
- 'debugging': self.__rtevcfg.debugging,
|
||||
- 'numcores':self._sysinfo.cpu_getCores(True),
|
||||
- 'logging':self.__rtevcfg.logging,
|
||||
- 'memsize':self._sysinfo.mem_get_size(),
|
||||
- 'numanodes':self._sysinfo.mem_get_numa_nodes(),
|
||||
- 'duration': float(self.__rtevcfg.duration),
|
||||
- }
|
||||
self._loadmods.Setup(params)
|
||||
|
||||
self.__logger.log(Log.INFO, "Preparing measurement modules")
|
||||
@@ -144,15 +142,18 @@ class RtEval(rtevalReport):
|
||||
|
||||
print(f"rteval run on {os.uname()[2]} started at {time.asctime()}")
|
||||
onlinecpus = self._sysinfo.cpu_getCores(True)
|
||||
- cpulist = self._loadmods._cfg.GetSection("loads").cpulist
|
||||
- if cpulist:
|
||||
- print(f"started {self._loadmods.ModulesLoaded()} loads on cores {cpulist}", end=' ')
|
||||
- else:
|
||||
- print(f"started {self._loadmods.ModulesLoaded()} loads on {onlinecpus} cores", end=' ')
|
||||
- if self._sysinfo.mem_get_numa_nodes() > 1:
|
||||
- print(f" with {self._sysinfo.mem_get_numa_nodes()} numa nodes")
|
||||
- else:
|
||||
- print("")
|
||||
+ if self._loadmods:
|
||||
+ cpulist = self._loadmods._cfg.GetSection("loads").cpulist
|
||||
+ if cpulist:
|
||||
+ print(f"started {self._loadmods.ModulesLoaded()} loads on cores {cpulist}",
|
||||
+ end=' ')
|
||||
+ else:
|
||||
+ print(f"started {self._loadmods.ModulesLoaded()} loads on {onlinecpus} cores",
|
||||
+ end=' ')
|
||||
+ if self._sysinfo.mem_get_numa_nodes() > 1:
|
||||
+ print(f" with {self._sysinfo.mem_get_numa_nodes()} numa nodes")
|
||||
+ else:
|
||||
+ print("")
|
||||
cpulist = self._measuremods._cfg.GetSection("measurement").cpulist
|
||||
if cpulist:
|
||||
print(f"started measurement threads on cores {cpulist}")
|
||||
@@ -192,7 +193,7 @@ class RtEval(rtevalReport):
|
||||
if threading.active_count() < nthreads:
|
||||
raise RuntimeError("load thread died!")
|
||||
|
||||
- if not load_avg_checked:
|
||||
+ if self._loadmods and not load_avg_checked:
|
||||
self._loadmods.SaveLoadAvg()
|
||||
load_avg_checked = 5
|
||||
else:
|
||||
@@ -202,7 +203,8 @@ class RtEval(rtevalReport):
|
||||
left_to_run = stoptime - currtime
|
||||
self.__show_remaining_time(left_to_run)
|
||||
rpttime = currtime + report_interval
|
||||
- print(f"load average: {self._loadmods.GetLoadAvg():.2f}")
|
||||
+ if self._loadmods:
|
||||
+ print(f"load average: {self._loadmods.GetLoadAvg():.2f}")
|
||||
currtime = time.time()
|
||||
|
||||
self.__logger.log(Log.DEBUG, "out of measurement loop")
|
||||
diff --git a/rteval/rtevalReport.py b/rteval/rtevalReport.py
|
||||
index 57d99f520f50..7379a7904f3f 100644
|
||||
--- a/rteval/rtevalReport.py
|
||||
+++ b/rteval/rtevalReport.py
|
||||
@@ -57,7 +57,8 @@ class rtevalReport:
|
||||
self.__xmlreport.AppendXMLnodes(self._sysinfo.MakeReport())
|
||||
|
||||
# Add load info
|
||||
- self.__xmlreport.AppendXMLnodes(self._loadmods.MakeReport())
|
||||
+ if self._loadmods:
|
||||
+ self.__xmlreport.AppendXMLnodes(self._loadmods.MakeReport())
|
||||
|
||||
# Add measurement data
|
||||
self.__xmlreport.AppendXMLnodes(self._measuremods.MakeReport())
|
||||
diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl
|
||||
index b801679abcc5..96846aaf4d54 100644
|
||||
--- a/rteval/rteval_text.xsl
|
||||
+++ b/rteval/rteval_text.xsl
|
||||
@@ -15,7 +15,14 @@
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<xsl:text> Loads: </xsl:text>
|
||||
- <xsl:value-of select="loads/@loads"/><xsl:text> loads run on cores </xsl:text><xsl:value-of select="loads/@loadcpus"/>
|
||||
+ <xsl:choose>
|
||||
+ <xsl:when test="loads">
|
||||
+ <xsl:value-of select="loads/@loads"/><xsl:text> loads run on cores </xsl:text><xsl:value-of select="loads/@loadcpus"/>
|
||||
+ </xsl:when>
|
||||
+ <xsl:otherwise>
|
||||
+ <xsl:text>none</xsl:text>
|
||||
+ </xsl:otherwise>
|
||||
+ </xsl:choose>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<xsl:text> Measurement: </xsl:text>
|
||||
--
|
||||
2.45.2
|
||||
|
84
rteval-Enforce-only-one-latency-measurement-module-a.patch
Normal file
84
rteval-Enforce-only-one-latency-measurement-module-a.patch
Normal file
@ -0,0 +1,84 @@
|
||||
From d6f62a5e52843e0b2651268e350a3c0ebe5c543b Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Thu, 20 Jun 2024 21:24:17 -0500
|
||||
Subject: [PATCH 4/7] rteval: Enforce only one latency measurement module at a
|
||||
time
|
||||
|
||||
Latency modules will step on each other's toes if run at the same time
|
||||
(on the same CPU, though that's an enhancement for later), so only
|
||||
run one of them. A priority mechanism allows selecting
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||||
---
|
||||
rteval/modules/__init__.py | 11 +++++++++++
|
||||
rteval/modules/measurement/cyclictest.py | 1 +
|
||||
rteval/modules/measurement/timerlat.py | 1 +
|
||||
3 files changed, 13 insertions(+)
|
||||
|
||||
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
|
||||
index de1ddc4628c1..2a4eafae71c7 100644
|
||||
--- a/rteval/modules/__init__.py
|
||||
+++ b/rteval/modules/__init__.py
|
||||
@@ -40,6 +40,7 @@ class rtevalModulePrototype(threading.Thread):
|
||||
"finished": threading.Event()}
|
||||
self._donotrun = False
|
||||
self._exclusive = False
|
||||
+ self._latency = False
|
||||
self.__timestamps = {}
|
||||
self.__sleeptime = 2.0
|
||||
|
||||
@@ -67,6 +68,11 @@ class rtevalModulePrototype(threading.Thread):
|
||||
self._exclusive = True
|
||||
|
||||
|
||||
+ def set_latency(self):
|
||||
+ """ Sets the module as an exclusive latency measurer """
|
||||
+ self._latency = True
|
||||
+
|
||||
+
|
||||
def set_donotrun(self):
|
||||
""" set a module's donotrun field to True """
|
||||
self._donotrun = True
|
||||
@@ -412,9 +418,14 @@ class RtEvalModules:
|
||||
|
||||
self._logger.log(Log.INFO, f"Preparing {self._module_type} modules")
|
||||
exclusive = 0
|
||||
+ latency = False
|
||||
for (modname, mod) in self.__modules:
|
||||
if mod.is_exclusive() and mod.WorkloadWillRun():
|
||||
exclusive += 1
|
||||
+ if mod._latency:
|
||||
+ if latency:
|
||||
+ raise RuntimeError("More than one exclusive latency test")
|
||||
+ latency = True
|
||||
for (modname, mod) in self.__modules:
|
||||
if exclusive >= 1:
|
||||
if exclusive != 1:
|
||||
diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py
|
||||
index 3a34c1b988d6..a9f5b0c4fba7 100644
|
||||
--- a/rteval/modules/measurement/cyclictest.py
|
||||
+++ b/rteval/modules/measurement/cyclictest.py
|
||||
@@ -216,6 +216,7 @@ class Cyclictest(rtevalModulePrototype):
|
||||
self.__started = False
|
||||
self.__cyclicoutput = None
|
||||
self.__breaktraceval = None
|
||||
+ self.set_latency()
|
||||
|
||||
|
||||
@staticmethod
|
||||
diff --git a/rteval/modules/measurement/timerlat.py b/rteval/modules/measurement/timerlat.py
|
||||
index f3bdc7098bc0..e4b80c33552e 100644
|
||||
--- a/rteval/modules/measurement/timerlat.py
|
||||
+++ b/rteval/modules/measurement/timerlat.py
|
||||
@@ -216,6 +216,7 @@ class Timerlat(rtevalModulePrototype):
|
||||
logfnc=self._log)
|
||||
self.__timerlatdata['system'].description = (f"({self.__numcores} cores) ") + info['0']['model name']
|
||||
self._log(Log.DEBUG, f"system using {self.__numcores} cpu cores")
|
||||
+ self.set_latency()
|
||||
|
||||
|
||||
def _WorkloadSetup(self):
|
||||
--
|
||||
2.45.2
|
||||
|
42
rteval-Fix-default-measurement-config.patch
Normal file
42
rteval-Fix-default-measurement-config.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From 9a3d515636fcea17690a4639554f8dae5ebd1ca0 Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Fri, 19 Jul 2024 15:02:34 -0500
|
||||
Subject: [PATCH 6/7] rteval: Fix default measurement config
|
||||
|
||||
Commit 761741d15d08e ("rteval: rteval-cmd: Some style changes suggested by pylint-3")
|
||||
accidentally indented the check for missing measurement config, such that
|
||||
it became part of the missing load conditional. This was harmless if
|
||||
the cnofig file was missing entirely, but not if the config file
|
||||
exists but the measurement section is empty.
|
||||
|
||||
Also, remove timerlat from the default as it conflicts with cyclictest,
|
||||
and we're not quite ready to make timerlat the default.
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
---
|
||||
rteval-cmd | 9 ++++-----
|
||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/rteval-cmd b/rteval-cmd
|
||||
index 36b167a034e5..19c82a0b64b3 100755
|
||||
--- a/rteval-cmd
|
||||
+++ b/rteval-cmd
|
||||
@@ -247,11 +247,10 @@ if __name__ == '__main__':
|
||||
'hackbench' : 'module',
|
||||
'stressng' : 'module'})
|
||||
|
||||
- if not config.HasSection('measurement'):
|
||||
- config.AppendConfig('measurement', {
|
||||
- 'cyclictest' : 'module',
|
||||
- 'timerlat' : 'module',
|
||||
- 'sysstat' : 'module'})
|
||||
+ if not config.HasSection('measurement'):
|
||||
+ config.AppendConfig('measurement', {
|
||||
+ 'cyclictest' : 'module',
|
||||
+ 'sysstat' : 'module'})
|
||||
|
||||
# Prepare log levels before loading modules, not to have unwanted log messages
|
||||
rtevcfg = config.GetSection('rteval')
|
||||
--
|
||||
2.45.2
|
||||
|
463
rteval-Remove-MeasurementProfile.patch
Normal file
463
rteval-Remove-MeasurementProfile.patch
Normal file
@ -0,0 +1,463 @@
|
||||
From 70d84e566ddef917373a5eb20acf9d7cbccb1f97 Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Thu, 20 Jun 2024 21:24:15 -0500
|
||||
Subject: [PATCH 2/7] rteval: Remove MeasurementProfile
|
||||
|
||||
Now that the ModuleInfo() flags are gone, remove the remaining infrastructure
|
||||
around measurement profiles.
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||||
---
|
||||
rteval/__init__.py | 25 ++----
|
||||
rteval/modules/measurement/__init__.py | 117 ++++---------------------
|
||||
rteval/rteval_histogram_raw.xsl | 24 ++---
|
||||
rteval/rteval_text.xsl | 41 +++------
|
||||
4 files changed, 54 insertions(+), 153 deletions(-)
|
||||
|
||||
diff --git a/rteval/__init__.py b/rteval/__init__.py
|
||||
index 4a6883e28e5b..226d14f80f48 100644
|
||||
--- a/rteval/__init__.py
|
||||
+++ b/rteval/__init__.py
|
||||
@@ -20,7 +20,7 @@ import time
|
||||
from datetime import datetime
|
||||
import sysconfig
|
||||
from rteval.modules.loads import LoadModules
|
||||
-from rteval.modules.measurement import MeasurementModules, MeasurementProfile
|
||||
+from rteval.modules.measurement import MeasurementModules
|
||||
from rteval.rtevalReport import rtevalReport
|
||||
from rteval.Log import Log
|
||||
from rteval import rtevalConfig
|
||||
@@ -131,10 +131,8 @@ class RtEval(rtevalReport):
|
||||
self._measuremods.Setup(params)
|
||||
|
||||
|
||||
- def __RunMeasurementProfile(self, measure_profile):
|
||||
+ def __RunMeasurement(self):
|
||||
global earlystop
|
||||
- if not isinstance(measure_profile, MeasurementProfile):
|
||||
- raise Exception("measure_profile is not an MeasurementProfile object")
|
||||
|
||||
measure_start = None
|
||||
try:
|
||||
@@ -155,15 +153,14 @@ class RtEval(rtevalReport):
|
||||
print(f" with {self._sysinfo.mem_get_numa_nodes()} numa nodes")
|
||||
else:
|
||||
print("")
|
||||
- cpulist = self._measuremods._MeasurementModules__cfg.GetSection("measurement").cpulist
|
||||
+ cpulist = self._measuremods._cfg.GetSection("measurement").cpulist
|
||||
if cpulist:
|
||||
print(f"started measurement threads on cores {cpulist}")
|
||||
else:
|
||||
print(f"started measurement threads on {onlinecpus} cores")
|
||||
print(f"Run duration: {str(self.__rtevcfg.duration)} seconds")
|
||||
|
||||
- # start the cyclictest thread
|
||||
- measure_profile.Start()
|
||||
+ self._measuremods.Start()
|
||||
|
||||
# Unleash the loads and measurement threads
|
||||
report_interval = int(self.__rtevcfg.report_interval)
|
||||
@@ -172,7 +169,7 @@ class RtEval(rtevalReport):
|
||||
nthreads = threading.active_count()
|
||||
else:
|
||||
nthreads = None
|
||||
- measure_profile.Unleash()
|
||||
+ self._measuremods.Unleash()
|
||||
measure_start = datetime.now()
|
||||
|
||||
# wait for time to expire or thread to die
|
||||
@@ -185,7 +182,7 @@ class RtEval(rtevalReport):
|
||||
load_avg_checked = 5
|
||||
while (currtime <= stoptime) and not stopsig.is_set():
|
||||
stopsig.wait(min(stoptime - currtime, 60.0))
|
||||
- if not measure_profile.isAlive():
|
||||
+ if not self._measuremods.isAlive():
|
||||
stoptime = currtime
|
||||
earlystop = True
|
||||
self.__logger.log(Log.WARN,
|
||||
@@ -218,7 +215,7 @@ class RtEval(rtevalReport):
|
||||
|
||||
finally:
|
||||
# stop measurement threads
|
||||
- measure_profile.Stop()
|
||||
+ self._measuremods.Stop()
|
||||
|
||||
# stop the loads
|
||||
if self._loadmods:
|
||||
@@ -227,7 +224,7 @@ class RtEval(rtevalReport):
|
||||
print(f"stopping run at {time.asctime()}")
|
||||
|
||||
# wait for measurement modules to finish calculating stats
|
||||
- measure_profile.WaitForCompletion()
|
||||
+ self._measuremods.WaitForCompletion()
|
||||
|
||||
return measure_start
|
||||
|
||||
@@ -236,11 +233,7 @@ class RtEval(rtevalReport):
|
||||
""" Run the full measurement suite with reports """
|
||||
global earlystop
|
||||
rtevalres = 0
|
||||
- measure_start = None
|
||||
- for meas_prf in self._measuremods:
|
||||
- mstart = self.__RunMeasurementProfile(meas_prf)
|
||||
- if measure_start is None:
|
||||
- measure_start = mstart
|
||||
+ measure_start = self.__RunMeasurement()
|
||||
|
||||
self._report(measure_start, self.__rtevcfg.xslt_report)
|
||||
if self.__rtevcfg.sysreport:
|
||||
diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py
|
||||
index 7b1d84ef554d..ecadd0885991 100644
|
||||
--- a/rteval/modules/measurement/__init__.py
|
||||
+++ b/rteval/modules/measurement/__init__.py
|
||||
@@ -8,43 +8,14 @@ from rteval.modules import RtEvalModules, ModuleContainer
|
||||
from rteval.systopology import parse_cpulist_from_config
|
||||
import rteval.cpulist_utils as cpulist_utils
|
||||
|
||||
-class MeasurementProfile(RtEvalModules):
|
||||
- """Keeps and controls all the measurement modules with the same measurement profile"""
|
||||
-
|
||||
- def __init__(self, config, modules_root, logger):
|
||||
- self._module_type = "measurement"
|
||||
- self._module_config = "measurement"
|
||||
- self._report_tag = "Profile"
|
||||
- RtEvalModules.__init__(self, config, modules_root, logger)
|
||||
-
|
||||
-
|
||||
- def ImportModule(self, module):
|
||||
- "Imports an exported module from a ModuleContainer() class"
|
||||
- return self._ImportModule(module)
|
||||
-
|
||||
-
|
||||
- def Setup(self, modname):
|
||||
- "Instantiates and prepares a measurement module"
|
||||
-
|
||||
- modobj = self._InstantiateModule(modname, self._cfg.GetSection(modname))
|
||||
- self._RegisterModuleObject(modname, modobj)
|
||||
-
|
||||
-
|
||||
-class MeasurementModules:
|
||||
- """Class which takes care of all measurement modules and groups them into
|
||||
-measurement profiles, based on their characteristics"""
|
||||
+class MeasurementModules(RtEvalModules):
|
||||
+ """Module container for measurement modules"""
|
||||
|
||||
def __init__(self, config, logger):
|
||||
- self.__cfg = config
|
||||
- self.__logger = logger
|
||||
- self.__measureprofiles = []
|
||||
- self.__modules_root = "modules.measurement"
|
||||
- self.__iter_item = None
|
||||
-
|
||||
- # Temporary module container, which is used to evalute measurement modules.
|
||||
- # This will container will be destroyed after Setup() has been called
|
||||
- self.__container = ModuleContainer(self.__modules_root, self.__logger)
|
||||
- self.__LoadModules(self.__cfg.GetSection("measurement"))
|
||||
+ self._module_type = "measurement"
|
||||
+ self._report_tag = "Measurements"
|
||||
+ RtEvalModules.__init__(self, config, "modules.measurement", logger)
|
||||
+ self.__LoadModules(self._cfg.GetSection("measurement"))
|
||||
|
||||
|
||||
def __LoadModules(self, modcfg):
|
||||
@@ -54,37 +25,28 @@ measurement profiles, based on their characteristics"""
|
||||
# hope to eventually have different kinds but module is only on
|
||||
# for now (jcw)
|
||||
if m[1].lower() == 'module':
|
||||
- self.__container.LoadModule(m[0])
|
||||
-
|
||||
-
|
||||
- def GetProfile(self):
|
||||
- "Returns the appropriate MeasurementProfile object, based on the profile type"
|
||||
-
|
||||
- for p in self.__measureprofiles:
|
||||
- return p
|
||||
- return None
|
||||
-
|
||||
+ self._LoadModule(m[0])
|
||||
|
||||
def SetupModuleOptions(self, parser):
|
||||
"Sets up all the measurement modules' parameters for the option parser"
|
||||
- grparser = self.__container.SetupModuleOptions(parser, self.__cfg)
|
||||
+ grparser = super().SetupModuleOptions(parser)
|
||||
|
||||
# Set up options specific for measurement module group
|
||||
grparser.add_argument("--measurement-run-on-isolcpus",
|
||||
dest="measurement___run_on_isolcpus",
|
||||
action="store_true",
|
||||
- default=self.__cfg.GetSection("measurement").setdefault("run-on-isolcpus", "false").lower()
|
||||
+ default=self._cfg.GetSection("measurement").setdefault("run-on-isolcpus", "false").lower()
|
||||
== "true",
|
||||
help="Include isolated CPUs in default cpulist")
|
||||
|
||||
|
||||
def Setup(self, modparams):
|
||||
- "Loads all measurement modules and group them into different measurement profiles"
|
||||
+ "Loads all measurement modules"
|
||||
|
||||
if not isinstance(modparams, dict):
|
||||
raise TypeError("modparams attribute is not of a dictionary type")
|
||||
|
||||
- modcfg = self.__cfg.GetSection("measurement")
|
||||
+ modcfg = self._cfg.GetSection("measurement")
|
||||
cpulist = modcfg.cpulist
|
||||
run_on_isolcpus = modcfg.run_on_isolcpus
|
||||
if cpulist is None:
|
||||
@@ -93,61 +55,20 @@ measurement profiles, based on their characteristics"""
|
||||
|
||||
for (modname, modtype) in modcfg:
|
||||
if isinstance(modtype, str) and modtype.lower() == 'module': # Only 'module' will be supported (ds)
|
||||
- self.__container.LoadModule(modname)
|
||||
-
|
||||
- # Get the correct measurement profile container for this module
|
||||
- mp = self.GetProfile()
|
||||
- if mp is None:
|
||||
- # If not found, create a new measurement profile
|
||||
- mp = MeasurementProfile(self.__cfg,
|
||||
- self.__modules_root, self.__logger)
|
||||
- self.__measureprofiles.append(mp)
|
||||
-
|
||||
- # Export the module imported here and transfer it to the
|
||||
- # measurement profile
|
||||
- mp.ImportModule(self.__container.ExportModule(modname))
|
||||
+ self._cfg.AppendConfig(modname, modparams)
|
||||
+ self._cfg.AppendConfig(modname, {'cpulist':cpulist})
|
||||
+ self._cfg.AppendConfig(modname, {'run-on-isolcpus':run_on_isolcpus})
|
||||
|
||||
- # Setup this imported module inside the appropriate measurement profile
|
||||
- self.__cfg.AppendConfig(modname, modparams)
|
||||
- self.__cfg.AppendConfig(modname, {'cpulist':cpulist})
|
||||
- self.__cfg.AppendConfig(modname, {'run-on-isolcpus':run_on_isolcpus})
|
||||
- mp.Setup(modname)
|
||||
-
|
||||
- del self.__container
|
||||
+ modobj = self._InstantiateModule(modname, self._cfg.GetSection(modname))
|
||||
+ self._RegisterModuleObject(modname, modobj)
|
||||
|
||||
|
||||
def MakeReport(self):
|
||||
- "Generates an XML report for all measurement profiles"
|
||||
+ rep_n = super().MakeReport()
|
||||
|
||||
- # Get the reports from all meaurement modules in all measurement profiles
|
||||
- rep_n = libxml2.newNode("Measurements")
|
||||
- cpulist = self.__cfg.GetSection("measurement").cpulist
|
||||
- run_on_isolcpus = self.__cfg.GetSection("measurement").run_on_isolcpus
|
||||
+ cpulist = self._cfg.GetSection("measurement").cpulist
|
||||
+ run_on_isolcpus = self._cfg.GetSection("measurement").run_on_isolcpus
|
||||
cpulist = parse_cpulist_from_config(cpulist, run_on_isolcpus)
|
||||
rep_n.newProp("measurecpus", cpulist_utils.collapse_cpulist(cpulist))
|
||||
|
||||
- for mp in self.__measureprofiles:
|
||||
- mprep_n = mp.MakeReport()
|
||||
- if mprep_n:
|
||||
- rep_n.addChild(mprep_n)
|
||||
-
|
||||
return rep_n
|
||||
-
|
||||
-
|
||||
- def __iter__(self):
|
||||
- "Initiates an iteration loop for MeasurementProfile objects"
|
||||
-
|
||||
- self.__iter_item = len(self.__measureprofiles)
|
||||
- return self
|
||||
-
|
||||
-
|
||||
- def __next__(self):
|
||||
- """Internal Python iterating method, returns the next
|
||||
-MeasurementProfile object to be processed"""
|
||||
-
|
||||
- if self.__iter_item == 0:
|
||||
- self.__iter_item = None
|
||||
- raise StopIteration
|
||||
-
|
||||
- self.__iter_item -= 1
|
||||
- return self.__measureprofiles[self.__iter_item]
|
||||
diff --git a/rteval/rteval_histogram_raw.xsl b/rteval/rteval_histogram_raw.xsl
|
||||
index 00b2be34f305..35d8e8461f74 100644
|
||||
--- a/rteval/rteval_histogram_raw.xsl
|
||||
+++ b/rteval/rteval_histogram_raw.xsl
|
||||
@@ -11,25 +11,25 @@
|
||||
<xsl:text>core	index	value </xsl:text>
|
||||
|
||||
<!-- Extract overall system histogram data -->
|
||||
- <xsl:apply-templates select="Measurements/Profile/cyclictest/system/histogram/bucket">
|
||||
+ <xsl:apply-templates select="Measurements/cyclictest/system/histogram/bucket">
|
||||
<xsl:with-param name="label" select="'system'"/>
|
||||
- <xsl:sort select="Measurements/Profile/cyclictest/core/histogram/bucket/@index" data-type="number"/>
|
||||
+ <xsl:sort select="Measurements/cyclictest/core/histogram/bucket/@index" data-type="number"/>
|
||||
</xsl:apply-templates>
|
||||
|
||||
- <xsl:apply-templates select="Measurements/Profile/timerlat/system/histogram/bucket">
|
||||
+ <xsl:apply-templates select="Measurements/timerlat/system/histogram/bucket">
|
||||
<xsl:with-param name="label" select="'system'"/>
|
||||
- <xsl:sort select="Measurements/Profile/timerlat/core/histogram/bucket/@index" data-type="number"/>
|
||||
+ <xsl:sort select="Measurements/timerlat/core/histogram/bucket/@index" data-type="number"/>
|
||||
</xsl:apply-templates>
|
||||
|
||||
<!-- Extract per cpu core histogram data -->
|
||||
- <xsl:apply-templates select="Measurements/Profile/cyclictest/core/histogram/bucket">
|
||||
- <xsl:sort select="Measurements/Profile/cyclictest/core/@id" data-type="number"/>
|
||||
- <xsl:sort select="Measurements/Profile/cyclictest/core/histogram/bucket/@index" data-type="number"/>
|
||||
+ <xsl:apply-templates select="Measurements/cyclictest/core/histogram/bucket">
|
||||
+ <xsl:sort select="Measurements/cyclictest/core/@id" data-type="number"/>
|
||||
+ <xsl:sort select="Measurements/cyclictest/core/histogram/bucket/@index" data-type="number"/>
|
||||
</xsl:apply-templates>
|
||||
|
||||
- <xsl:apply-templates select="Measurements/Profile/timerlat/core/histogram/bucket">
|
||||
- <xsl:sort select="Measurements/Profile/timerlat/core/@id" data-type="number"/>
|
||||
- <xsl:sort select="Measurements/Profile/timerlat/core/histogram/bucket/@index" data-type="number"/>
|
||||
+ <xsl:apply-templates select="Measurements/timerlat/core/histogram/bucket">
|
||||
+ <xsl:sort select="Measurements/timerlat/core/@id" data-type="number"/>
|
||||
+ <xsl:sort select="Measurements/timerlat/core/histogram/bucket/@index" data-type="number"/>
|
||||
</xsl:apply-templates>
|
||||
|
||||
</xsl:template>
|
||||
@@ -38,7 +38,7 @@
|
||||
<!-- -->
|
||||
|
||||
<!-- Record formatting -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/cyclictest/*/histogram/bucket">
|
||||
+ <xsl:template match="/rteval/Measurements/cyclictest/*/histogram/bucket">
|
||||
<xsl:param name="label"/>
|
||||
<xsl:choose>
|
||||
<!-- If we don't have a id tag in what should be a 'core' tag, use the given label -->
|
||||
@@ -54,7 +54,7 @@
|
||||
<xsl:text> </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
- <xsl:template match="/rteval/Measurements/Profile/timerlat/*/histogram/bucket">
|
||||
+ <xsl:template match="/rteval/Measurements/timerlat/*/histogram/bucket">
|
||||
<xsl:param name="label"/>
|
||||
<xsl:choose>
|
||||
<!-- If we don't have a id tag in what should be a 'core' tag, use the given label -->
|
||||
diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl
|
||||
index 7ca0ae3a4c66..b801679abcc5 100644
|
||||
--- a/rteval/rteval_text.xsl
|
||||
+++ b/rteval/rteval_text.xsl
|
||||
@@ -154,8 +154,8 @@
|
||||
<xsl:value-of select="SystemInfo/cmdlineInfo/cmdline"/>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
- <!-- Generate a summary report for all measurement profiles -->
|
||||
- <xsl:apply-templates select="Measurements/Profile"/>
|
||||
+ <!-- Generate a summary report for all measurement modules -->
|
||||
+ <xsl:apply-templates select="Measurements"/>
|
||||
<xsl:text> =================================================================== </xsl:text>
|
||||
</xsl:template>
|
||||
<!-- -->
|
||||
@@ -178,21 +178,8 @@
|
||||
</xsl:template>
|
||||
|
||||
|
||||
- <xsl:template match="/rteval/Measurements/Profile">
|
||||
- <xsl:text> Measurement profile </xsl:text>
|
||||
- <xsl:value-of select="position()"/><xsl:text>: </xsl:text>
|
||||
- <xsl:choose>
|
||||
- <xsl:when test="@loads = '1'"><xsl:text>With loads, </xsl:text></xsl:when>
|
||||
- <xsl:otherwise><xsl:text>Without loads, </xsl:text></xsl:otherwise>
|
||||
- </xsl:choose>
|
||||
- <xsl:choose>
|
||||
- <xsl:when test="@parallel = '1'">
|
||||
- <xsl:text>measurements in parallel</xsl:text>
|
||||
- </xsl:when>
|
||||
- <xsl:otherwise>
|
||||
- <xsl:text>measurements serialised</xsl:text>
|
||||
- </xsl:otherwise>
|
||||
- </xsl:choose>
|
||||
+ <xsl:template match="/rteval/Measurements">
|
||||
+ <xsl:text> Measurements: </xsl:text>
|
||||
<xsl:text> </xsl:text>
|
||||
|
||||
<!-- Format other sections of the report, if they are found -->
|
||||
@@ -206,7 +193,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<!-- Format the cyclictest section of the report -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/cyclictest">
|
||||
+ <xsl:template match="/rteval/Measurements/cyclictest">
|
||||
<xsl:text> Latency test </xsl:text>
|
||||
|
||||
<xsl:text> Started: </xsl:text>
|
||||
@@ -238,7 +225,7 @@
|
||||
|
||||
|
||||
<!-- Format the CPU core section in the cyclictest part -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/cyclictest/core">
|
||||
+ <xsl:template match="/rteval/Measurements/cyclictest/core">
|
||||
<xsl:text> CPU core </xsl:text>
|
||||
<xsl:value-of select="@id"/>
|
||||
<xsl:text> Priority: </xsl:text>
|
||||
@@ -251,7 +238,7 @@
|
||||
|
||||
|
||||
<!-- Generic formatting of statistics information -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/cyclictest/*/statistics">
|
||||
+ <xsl:template match="/rteval/Measurements/cyclictest/*/statistics">
|
||||
<xsl:text> Samples: </xsl:text>
|
||||
<xsl:value-of select="samples"/>
|
||||
<xsl:text> </xsl:text>
|
||||
@@ -301,7 +288,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<!-- Format the timerlat section of the report -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/timerlat">
|
||||
+ <xsl:template match="/rteval/Measurements/timerlat">
|
||||
<xsl:text> Latency test </xsl:text>
|
||||
|
||||
<xsl:text> Started: </xsl:text>
|
||||
@@ -345,7 +332,7 @@
|
||||
|
||||
|
||||
<!-- Format the CPU core section in the timerlat part -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/timerlat/core">
|
||||
+ <xsl:template match="/rteval/Measurements/timerlat/core">
|
||||
<xsl:text> CPU core </xsl:text>
|
||||
<xsl:value-of select="@id"/>
|
||||
<xsl:text> Priority: </xsl:text>
|
||||
@@ -358,7 +345,7 @@
|
||||
|
||||
|
||||
<!-- Generic formatting of statistics information -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/timerlat/*/statistics">
|
||||
+ <xsl:template match="/rteval/Measurements/timerlat/*/statistics">
|
||||
<xsl:text> Samples: </xsl:text>
|
||||
<xsl:value-of select="samples"/>
|
||||
<xsl:text> </xsl:text>
|
||||
@@ -409,7 +396,7 @@
|
||||
|
||||
|
||||
<!-- Format the hwlatdetect test section of the report -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/hwlatdetect[@format='1.0' and not(@aborted)]">
|
||||
+ <xsl:template match="/rteval/Measurements/hwlatdetect[@format='1.0' and not(@aborted)]">
|
||||
<xsl:text> Hardware latency detector </xsl:text>
|
||||
|
||||
<xsl:text> Run duration: </xsl:text>
|
||||
@@ -434,12 +421,12 @@
|
||||
<xsl:apply-templates select="samples/sample"/>
|
||||
</xsl:template>
|
||||
|
||||
- <xsl:template match="/rteval/Measurements/Profile/hwlatdetect[@format='1.0' and @aborted > 0]">
|
||||
+ <xsl:template match="/rteval/Measurements/hwlatdetect[@format='1.0' and @aborted > 0]">
|
||||
<xsl:text> Hardware latency detector </xsl:text>
|
||||
<xsl:text> ** WARNING ** hwlatedect failed to run </xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
- <xsl:template match="/rteval/Measurements/Profile/hwlatdetect[@format='1.0']/samples/sample">
|
||||
+ <xsl:template match="/rteval/Measurements/hwlatdetect[@format='1.0']/samples/sample">
|
||||
<xsl:text> - @</xsl:text>
|
||||
<xsl:value-of select="@timestamp"/>
|
||||
<xsl:text> </xsl:text>
|
||||
@@ -448,7 +435,7 @@
|
||||
</xsl:template>
|
||||
|
||||
<!-- Format the cyclictest section of the report -->
|
||||
- <xsl:template match="/rteval/Measurements/Profile/sysstat">
|
||||
+ <xsl:template match="/rteval/Measurements/sysstat">
|
||||
<xsl:text> sysstat measurements </xsl:text>
|
||||
|
||||
<xsl:text> Started: </xsl:text>
|
||||
--
|
||||
2.45.2
|
||||
|
87
rteval-RtEvalModules-Remove-unused-methods.patch
Normal file
87
rteval-RtEvalModules-Remove-unused-methods.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From 7a0bd39fad4fb017f41e32a125e7f4ef4284b8f0 Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Thu, 20 Jun 2024 21:24:16 -0500
|
||||
Subject: [PATCH 3/7] rteval: RtEvalModules: Remove unused methods
|
||||
|
||||
With measurement profiles gone, remove methods that no longer have any
|
||||
users.
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||||
---
|
||||
rteval/modules/__init__.py | 37 -------------------------------------
|
||||
1 file changed, 37 deletions(-)
|
||||
|
||||
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
|
||||
index 0c0ce7202f77..de1ddc4628c1 100644
|
||||
--- a/rteval/modules/__init__.py
|
||||
+++ b/rteval/modules/__init__.py
|
||||
@@ -333,36 +333,11 @@ returned when a ModuleContainer object is iterated over"""
|
||||
self.__modobjects[modname] = modobj
|
||||
|
||||
|
||||
- def ExportModule(self, modname, modroot=None):
|
||||
- "Export module info, used to transfer an imported module to another ModuleContainer"
|
||||
- if modroot is None:
|
||||
- modroot = self.__modules_root
|
||||
-
|
||||
- mod = f"{modroot}.{modname}"
|
||||
- return (mod, self.__modsloaded[mod])
|
||||
-
|
||||
-
|
||||
- def ImportModule(self, module):
|
||||
- "Imports an exported module from another ModuleContainer"
|
||||
- (modname, moduleimp) = module
|
||||
- self.__modsloaded[modname] = moduleimp
|
||||
-
|
||||
-
|
||||
def ModulesLoaded(self):
|
||||
"Returns number of registered module objects"
|
||||
return len(self.__modobjects)
|
||||
|
||||
|
||||
- def GetModulesList(self):
|
||||
- "Returns a list of module names"
|
||||
- return list(self.__modobjects.keys())
|
||||
-
|
||||
-
|
||||
- def GetNamedModuleObject(self, modname):
|
||||
- "Looks up a named module and returns its registered module object"
|
||||
- return self.__modobjects[modname]
|
||||
-
|
||||
-
|
||||
def __iter__(self):
|
||||
"Initiates the iterating process"
|
||||
|
||||
@@ -406,10 +381,6 @@ class RtEvalModules:
|
||||
# Export some of the internal module container methods
|
||||
# Primarily to have better control of the module containers
|
||||
# iteration API
|
||||
- def _ImportModule(self, module):
|
||||
- "Imports a module exported by ModuleContainer::ExportModule()"
|
||||
- return self.__modules.ImportModule(module)
|
||||
-
|
||||
def _InstantiateModule(self, modname, modcfg, modroot=None):
|
||||
"Imports a module and returns an instantiated object from the module"
|
||||
return self.__modules.InstantiateModule(modname, modcfg, modroot)
|
||||
@@ -426,17 +397,9 @@ class RtEvalModules:
|
||||
"Returns number of imported modules"
|
||||
return self.__modules.ModulesLoaded()
|
||||
|
||||
- def GetModulesList(self):
|
||||
- "Returns a list of module names"
|
||||
- return self.__modules.GetModulesList()
|
||||
-
|
||||
def SetupModuleOptions(self, parser):
|
||||
"Sets up argparse based argument groups for the loaded modules"
|
||||
return self.__modules.SetupModuleOptions(parser, self._cfg)
|
||||
-
|
||||
- def GetNamedModuleObject(self, modname):
|
||||
- "Returns a list of module names"
|
||||
- return self.__modules.GetNamedModuleObject(modname)
|
||||
# End of exports
|
||||
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
89
rteval-measurement-Change-latency-flag-to-latency_te.patch
Normal file
89
rteval-measurement-Change-latency-flag-to-latency_te.patch
Normal file
@ -0,0 +1,89 @@
|
||||
From 7cb8c1c14569426e867cbdbdb218d1d9bcd4d520 Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Fri, 26 Jul 2024 13:32:37 -0500
|
||||
Subject: [PATCH 7/7] rteval: measurement: Change latency flag to latency_test
|
||||
|
||||
As requested by John, change the name of the latency flag to avoid
|
||||
looking like it holds an actual latency value.
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||||
---
|
||||
rteval/modules/__init__.py | 14 +++++++-------
|
||||
rteval/modules/measurement/cyclictest.py | 2 +-
|
||||
rteval/modules/measurement/timerlat.py | 2 +-
|
||||
3 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
|
||||
index 2a4eafae71c7..d7792108d5b8 100644
|
||||
--- a/rteval/modules/__init__.py
|
||||
+++ b/rteval/modules/__init__.py
|
||||
@@ -40,7 +40,7 @@ class rtevalModulePrototype(threading.Thread):
|
||||
"finished": threading.Event()}
|
||||
self._donotrun = False
|
||||
self._exclusive = False
|
||||
- self._latency = False
|
||||
+ self._latency_test = False
|
||||
self.__timestamps = {}
|
||||
self.__sleeptime = 2.0
|
||||
|
||||
@@ -68,9 +68,9 @@ class rtevalModulePrototype(threading.Thread):
|
||||
self._exclusive = True
|
||||
|
||||
|
||||
- def set_latency(self):
|
||||
+ def set_latency_test(self):
|
||||
""" Sets the module as an exclusive latency measurer """
|
||||
- self._latency = True
|
||||
+ self._latency_test = True
|
||||
|
||||
|
||||
def set_donotrun(self):
|
||||
@@ -418,14 +418,14 @@ class RtEvalModules:
|
||||
|
||||
self._logger.log(Log.INFO, f"Preparing {self._module_type} modules")
|
||||
exclusive = 0
|
||||
- latency = False
|
||||
+ latency_test = False
|
||||
for (modname, mod) in self.__modules:
|
||||
if mod.is_exclusive() and mod.WorkloadWillRun():
|
||||
exclusive += 1
|
||||
- if mod._latency:
|
||||
- if latency:
|
||||
+ if mod._latency_test:
|
||||
+ if latency_test:
|
||||
raise RuntimeError("More than one exclusive latency test")
|
||||
- latency = True
|
||||
+ latency_test = True
|
||||
for (modname, mod) in self.__modules:
|
||||
if exclusive >= 1:
|
||||
if exclusive != 1:
|
||||
diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py
|
||||
index a9f5b0c4fba7..d919058e927f 100644
|
||||
--- a/rteval/modules/measurement/cyclictest.py
|
||||
+++ b/rteval/modules/measurement/cyclictest.py
|
||||
@@ -216,7 +216,7 @@ class Cyclictest(rtevalModulePrototype):
|
||||
self.__started = False
|
||||
self.__cyclicoutput = None
|
||||
self.__breaktraceval = None
|
||||
- self.set_latency()
|
||||
+ self.set_latency_test()
|
||||
|
||||
|
||||
@staticmethod
|
||||
diff --git a/rteval/modules/measurement/timerlat.py b/rteval/modules/measurement/timerlat.py
|
||||
index e4b80c33552e..92bc07051aa1 100644
|
||||
--- a/rteval/modules/measurement/timerlat.py
|
||||
+++ b/rteval/modules/measurement/timerlat.py
|
||||
@@ -216,7 +216,7 @@ class Timerlat(rtevalModulePrototype):
|
||||
logfnc=self._log)
|
||||
self.__timerlatdata['system'].description = (f"({self.__numcores} cores) ") + info['0']['model name']
|
||||
self._log(Log.DEBUG, f"system using {self.__numcores} cpu cores")
|
||||
- self.set_latency()
|
||||
+ self.set_latency_test()
|
||||
|
||||
|
||||
def _WorkloadSetup(self):
|
||||
--
|
||||
2.45.2
|
||||
|
324
rteval-measurement-Remove-ModuleInfo.patch
Normal file
324
rteval-measurement-Remove-ModuleInfo.patch
Normal file
@ -0,0 +1,324 @@
|
||||
From 5b55c62ff271e9d9278d25f027590aca05bff959 Mon Sep 17 00:00:00 2001
|
||||
From: Crystal Wood <crwood@redhat.com>
|
||||
Date: Thu, 20 Jun 2024 21:24:14 -0500
|
||||
Subject: [PATCH 1/7] rteval: measurement: Remove ModuleInfo()
|
||||
|
||||
All of the measurement modules have identical settings, and the use cases
|
||||
for deviating seem questionable. While we do have a desire to keep
|
||||
cyclictest and timerlat from running together, turning off run_parallel
|
||||
would prevent sysstat from running at the same time. And if there's a
|
||||
desire to run without loads, that seems like it belongs in the realm of
|
||||
user configuration, rather than anything inherent to a given measurement
|
||||
module.
|
||||
|
||||
Any future module flags can be implemented similarly to what is done
|
||||
in load modules (e.g. set_exclusive).
|
||||
|
||||
Places that checked with_loads now check whether a LoadModules container
|
||||
is present at all, which can be wired up to a command line option in the
|
||||
future.
|
||||
|
||||
Signed-off-by: Crystal Wood <crwood@redhat.com>
|
||||
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||||
---
|
||||
rteval/__init__.py | 39 ++++++-------
|
||||
rteval/modules/__init__.py | 13 +----
|
||||
rteval/modules/measurement/__init__.py | 73 ++----------------------
|
||||
rteval/modules/measurement/cyclictest.py | 5 --
|
||||
rteval/modules/measurement/sysstat.py | 7 ---
|
||||
rteval/modules/measurement/timerlat.py | 5 --
|
||||
6 files changed, 26 insertions(+), 116 deletions(-)
|
||||
|
||||
diff --git a/rteval/__init__.py b/rteval/__init__.py
|
||||
index 1a61148ef327..4a6883e28e5b 100644
|
||||
--- a/rteval/__init__.py
|
||||
+++ b/rteval/__init__.py
|
||||
@@ -111,20 +111,21 @@ class RtEval(rtevalReport):
|
||||
except Exception as err:
|
||||
raise RuntimeError(f"Cannot create report directory (NFS with rootsquash on?) [{err}]]")
|
||||
|
||||
- self.__logger.log(Log.INFO, "Preparing load modules")
|
||||
- params = {'workdir':self.__rtevcfg.workdir,
|
||||
- 'reportdir':self.__reportdir and self.__reportdir or "",
|
||||
- 'builddir':builddir,
|
||||
- 'srcdir':self.__rtevcfg.srcdir,
|
||||
- 'verbose': self.__rtevcfg.verbose,
|
||||
- 'debugging': self.__rtevcfg.debugging,
|
||||
- 'numcores':self._sysinfo.cpu_getCores(True),
|
||||
- 'logging':self.__rtevcfg.logging,
|
||||
- 'memsize':self._sysinfo.mem_get_size(),
|
||||
- 'numanodes':self._sysinfo.mem_get_numa_nodes(),
|
||||
- 'duration': float(self.__rtevcfg.duration),
|
||||
- }
|
||||
- self._loadmods.Setup(params)
|
||||
+ if self._loadmods:
|
||||
+ self.__logger.log(Log.INFO, "Preparing load modules")
|
||||
+ params = {'workdir':self.__rtevcfg.workdir,
|
||||
+ 'reportdir':self.__reportdir and self.__reportdir or "",
|
||||
+ 'builddir':builddir,
|
||||
+ 'srcdir':self.__rtevcfg.srcdir,
|
||||
+ 'verbose': self.__rtevcfg.verbose,
|
||||
+ 'debugging': self.__rtevcfg.debugging,
|
||||
+ 'numcores':self._sysinfo.cpu_getCores(True),
|
||||
+ 'logging':self.__rtevcfg.logging,
|
||||
+ 'memsize':self._sysinfo.mem_get_size(),
|
||||
+ 'numanodes':self._sysinfo.mem_get_numa_nodes(),
|
||||
+ 'duration': float(self.__rtevcfg.duration),
|
||||
+ }
|
||||
+ self._loadmods.Setup(params)
|
||||
|
||||
self.__logger.log(Log.INFO, "Preparing measurement modules")
|
||||
self._measuremods.Setup(params)
|
||||
@@ -136,13 +137,11 @@ class RtEval(rtevalReport):
|
||||
raise Exception("measure_profile is not an MeasurementProfile object")
|
||||
|
||||
measure_start = None
|
||||
- (with_loads, run_parallel) = measure_profile.GetProfile()
|
||||
- self.__logger.log(Log.INFO, f"Using measurement profile [loads: {with_loads} parallel: {run_parallel}]")
|
||||
try:
|
||||
nthreads = 0
|
||||
|
||||
# start the loads
|
||||
- if with_loads:
|
||||
+ if self._loadmods:
|
||||
self._loadmods.Start()
|
||||
|
||||
print(f"rteval run on {os.uname()[2]} started at {time.asctime()}")
|
||||
@@ -168,7 +167,7 @@ class RtEval(rtevalReport):
|
||||
|
||||
# Unleash the loads and measurement threads
|
||||
report_interval = int(self.__rtevcfg.report_interval)
|
||||
- if with_loads:
|
||||
+ if self._loadmods:
|
||||
self._loadmods.Unleash()
|
||||
nthreads = threading.active_count()
|
||||
else:
|
||||
@@ -192,7 +191,7 @@ class RtEval(rtevalReport):
|
||||
self.__logger.log(Log.WARN,
|
||||
"Measurement threads did not use the full time slot. Doing a controlled stop.")
|
||||
|
||||
- if with_loads:
|
||||
+ if nthreads:
|
||||
if threading.active_count() < nthreads:
|
||||
raise RuntimeError("load thread died!")
|
||||
|
||||
@@ -222,7 +221,7 @@ class RtEval(rtevalReport):
|
||||
measure_profile.Stop()
|
||||
|
||||
# stop the loads
|
||||
- if with_loads:
|
||||
+ if self._loadmods:
|
||||
self._loadmods.Stop()
|
||||
|
||||
print(f"stopping run at {time.asctime()}")
|
||||
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
|
||||
index 4330a839db6f..0c0ce7202f77 100644
|
||||
--- a/rteval/modules/__init__.py
|
||||
+++ b/rteval/modules/__init__.py
|
||||
@@ -269,14 +269,6 @@ reference from the first import"""
|
||||
return mod
|
||||
|
||||
|
||||
- def ModuleInfo(self, modname, modroot=None):
|
||||
- """Imports a module and calls the modules' ModuleInfo() function and returns
|
||||
-the information provided by the module"""
|
||||
-
|
||||
- mod = self.LoadModule(modname, modroot)
|
||||
- return mod.ModuleInfo()
|
||||
-
|
||||
-
|
||||
def SetupModuleOptions(self, parser, config):
|
||||
"""Sets up a separate argparse ArgumentGroup per module with its supported parameters"""
|
||||
|
||||
@@ -495,9 +487,8 @@ class RtEvalModules:
|
||||
|
||||
|
||||
def Unleash(self):
|
||||
- """Unleashes all the loaded modules workloads"""
|
||||
+ """Unleashes all the loaded modules"""
|
||||
|
||||
- # turn loose the loads
|
||||
nthreads = 0
|
||||
self._logger.log(Log.INFO, f"Sending start event to all {self._module_type} modules")
|
||||
for (modname, mod) in self.__modules:
|
||||
@@ -508,7 +499,7 @@ class RtEvalModules:
|
||||
return nthreads
|
||||
|
||||
|
||||
- def _isAlive(self):
|
||||
+ def isAlive(self):
|
||||
"""Returns True if all modules are running"""
|
||||
|
||||
for (modname, mod) in self.__modules:
|
||||
diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py
|
||||
index 43c0fda30ce1..7b1d84ef554d 100644
|
||||
--- a/rteval/modules/measurement/__init__.py
|
||||
+++ b/rteval/modules/measurement/__init__.py
|
||||
@@ -11,24 +11,13 @@ import rteval.cpulist_utils as cpulist_utils
|
||||
class MeasurementProfile(RtEvalModules):
|
||||
"""Keeps and controls all the measurement modules with the same measurement profile"""
|
||||
|
||||
- def __init__(self, config, with_load, run_parallel, modules_root, logger):
|
||||
- self.__with_load = with_load
|
||||
- self.__run_parallel = run_parallel
|
||||
-
|
||||
- # Only used when running modules serialised
|
||||
- self.__run_serialised_mods = None
|
||||
-
|
||||
+ def __init__(self, config, modules_root, logger):
|
||||
self._module_type = "measurement"
|
||||
self._module_config = "measurement"
|
||||
self._report_tag = "Profile"
|
||||
RtEvalModules.__init__(self, config, modules_root, logger)
|
||||
|
||||
|
||||
- def GetProfile(self):
|
||||
- "Returns the profile characteristic as (with_load, run_parallel)"
|
||||
- return (self.__with_load, self.__run_parallel)
|
||||
-
|
||||
-
|
||||
def ImportModule(self, module):
|
||||
"Imports an exported module from a ModuleContainer() class"
|
||||
return self._ImportModule(module)
|
||||
@@ -41,54 +30,6 @@ class MeasurementProfile(RtEvalModules):
|
||||
self._RegisterModuleObject(modname, modobj)
|
||||
|
||||
|
||||
- def Unleash(self):
|
||||
- """Unleashes all the measurement modules"""
|
||||
-
|
||||
- if self.__run_parallel:
|
||||
- # Use the inherrited method if running
|
||||
- # measurements in parallel
|
||||
- return RtEvalModules.Unleash(self)
|
||||
-
|
||||
- # Get a list of all registered modules,
|
||||
- # and start the first one
|
||||
- self.__serialised_mods = self.GetModulesList()
|
||||
- mod = self.GetNamedModuleObject(self.__serialised_mods[0])
|
||||
- mod.setStart()
|
||||
- return 1
|
||||
-
|
||||
-
|
||||
- def MakeReport(self):
|
||||
- "Generates an XML report for all run measurement modules in this profile"
|
||||
- rep_n = RtEvalModules.MakeReport(self)
|
||||
- rep_n.newProp("loads", self.__with_load and "1" or "0")
|
||||
- rep_n.newProp("parallel", self.__run_parallel and "1" or "0")
|
||||
- return rep_n
|
||||
-
|
||||
-
|
||||
- def isAlive(self):
|
||||
- """Returns True if all modules which are supposed to run runs"""
|
||||
-
|
||||
- if self.__run_parallel:
|
||||
- return self._isAlive()
|
||||
-
|
||||
- if self.__serialised_mods:
|
||||
- # If running serialised, first check if measurement is still running,
|
||||
- # if so - return True.
|
||||
- mod = self.GetNamedModuleObject(self.__serialised_mods[0])
|
||||
- if mod.WorkloadAlive():
|
||||
- return True
|
||||
-
|
||||
- # If not, go to next on the list and kick it off
|
||||
- self.__serialised_mods.remove(self.__serialised_mods[0])
|
||||
- if self.__serialised_mods:
|
||||
- mod = self.GetNamedModuleObject(self.__serialised_mods[0])
|
||||
- mod.setStart()
|
||||
- return True
|
||||
-
|
||||
- # If we've been through everything, nothing is running
|
||||
- return False
|
||||
-
|
||||
-
|
||||
class MeasurementModules:
|
||||
"""Class which takes care of all measurement modules and groups them into
|
||||
measurement profiles, based on their characteristics"""
|
||||
@@ -116,13 +57,11 @@ measurement profiles, based on their characteristics"""
|
||||
self.__container.LoadModule(m[0])
|
||||
|
||||
|
||||
- def GetProfile(self, with_load, run_parallel):
|
||||
+ def GetProfile(self):
|
||||
"Returns the appropriate MeasurementProfile object, based on the profile type"
|
||||
|
||||
for p in self.__measureprofiles:
|
||||
- mp = p.GetProfile()
|
||||
- if mp == (with_load, run_parallel):
|
||||
- return p
|
||||
+ return p
|
||||
return None
|
||||
|
||||
|
||||
@@ -154,15 +93,13 @@ measurement profiles, based on their characteristics"""
|
||||
|
||||
for (modname, modtype) in modcfg:
|
||||
if isinstance(modtype, str) and modtype.lower() == 'module': # Only 'module' will be supported (ds)
|
||||
- # Extract the measurement modules info
|
||||
- modinfo = self.__container.ModuleInfo(modname)
|
||||
+ self.__container.LoadModule(modname)
|
||||
|
||||
# Get the correct measurement profile container for this module
|
||||
- mp = self.GetProfile(modinfo["loads"], modinfo["parallel"])
|
||||
+ mp = self.GetProfile()
|
||||
if mp is None:
|
||||
# If not found, create a new measurement profile
|
||||
mp = MeasurementProfile(self.__cfg,
|
||||
- modinfo["loads"], modinfo["parallel"],
|
||||
self.__modules_root, self.__logger)
|
||||
self.__measureprofiles.append(mp)
|
||||
|
||||
diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py
|
||||
index 3301e1b45e11..3a34c1b988d6 100644
|
||||
--- a/rteval/modules/measurement/cyclictest.py
|
||||
+++ b/rteval/modules/measurement/cyclictest.py
|
||||
@@ -394,11 +394,6 @@ class Cyclictest(rtevalModulePrototype):
|
||||
return rep_n
|
||||
|
||||
|
||||
-def ModuleInfo():
|
||||
- return {"parallel": True,
|
||||
- "loads": True}
|
||||
-
|
||||
-
|
||||
def ModuleParameters():
|
||||
""" default parameters """
|
||||
return {"interval": {"descr": "Base interval of the threads in microseconds",
|
||||
diff --git a/rteval/modules/measurement/sysstat.py b/rteval/modules/measurement/sysstat.py
|
||||
index d4646c1646f4..a0efd8953659 100644
|
||||
--- a/rteval/modules/measurement/sysstat.py
|
||||
+++ b/rteval/modules/measurement/sysstat.py
|
||||
@@ -93,13 +93,6 @@ class sysstat(rtevalModulePrototype):
|
||||
|
||||
|
||||
|
||||
-def ModuleInfo():
|
||||
- # sysstat features - run in parallel with outher measurement modules with loads
|
||||
- return {"parallel": True,
|
||||
- "loads": True}
|
||||
-
|
||||
-
|
||||
-
|
||||
def ModuleParameters():
|
||||
return {} # No arguments available
|
||||
|
||||
diff --git a/rteval/modules/measurement/timerlat.py b/rteval/modules/measurement/timerlat.py
|
||||
index dc6226ccc991..f3bdc7098bc0 100644
|
||||
--- a/rteval/modules/measurement/timerlat.py
|
||||
+++ b/rteval/modules/measurement/timerlat.py
|
||||
@@ -499,11 +499,6 @@ class Timerlat(rtevalModulePrototype):
|
||||
return rep_n
|
||||
|
||||
|
||||
-def ModuleInfo():
|
||||
- """ Required measurement module information """
|
||||
- return {"parallel": True,
|
||||
- "loads": True}
|
||||
-
|
||||
def ModuleParameters():
|
||||
""" default parameters """
|
||||
return {"priority": {"descr": "Run rtla timerlat with this priority",
|
||||
--
|
||||
2.45.2
|
||||
|
24
rteval.spec
24
rteval.spec
@ -1,6 +1,6 @@
|
||||
Name: rteval
|
||||
Version: 3.8
|
||||
Release: 7%{?dist}
|
||||
Release: 8%{?dist}
|
||||
Summary: Utility to evaluate system suitability for RT Linux
|
||||
|
||||
Group: Development/Tools
|
||||
@ -40,6 +40,13 @@ Patch3: rteval-timerlat-Add-timerlat-tracing-to-rteval.patch
|
||||
Patch4: rteval-sysstat-Convert-base64-data-to-text-before-wr.patch
|
||||
Patch5: rteval-Fix-sysreport-traceback-when-utility-sos-not-.patch
|
||||
Patch6: rteval-timerlat-tracing-clean-up.patch
|
||||
Patch7: rteval-measurement-Remove-ModuleInfo.patch
|
||||
Patch8: rteval-Remove-MeasurementProfile.patch
|
||||
Patch9: rteval-RtEvalModules-Remove-unused-methods.patch
|
||||
Patch10: rteval-Enforce-only-one-latency-measurement-module-a.patch
|
||||
Patch11: rteval-Add-noload-option.patch
|
||||
Patch12: rteval-Fix-default-measurement-config.patch
|
||||
Patch13: rteval-measurement-Change-latency-flag-to-latency_te.patch
|
||||
|
||||
%description
|
||||
The rteval script is a utility for measuring various aspects of
|
||||
@ -51,13 +58,7 @@ a statistical analysis of the event response times is done and printed
|
||||
to the screen.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%autosetup -p1
|
||||
|
||||
%build
|
||||
%{__python3} setup.py build
|
||||
@ -78,6 +79,13 @@ to the screen.
|
||||
%{_bindir}/rteval
|
||||
|
||||
%changelog
|
||||
* Mon Jul 29 2024 Crystal Wood <crwood@redhat.com> - 3.8-8
|
||||
- Prevent using cyclictest and timerlat and the same time
|
||||
- Add a --noload option
|
||||
- Switch to autosetup
|
||||
Resolves: RHEL-35507
|
||||
Resolves: RHEL-50324
|
||||
|
||||
* Mon Jun 24 2024 John Kacur <jkacur@redhat.com> - 3.8-7
|
||||
- Rename some patches
|
||||
- Add timerlat tracing
|
||||
|
Loading…
Reference in New Issue
Block a user