rteval/rteval-Add-rtla-timerlat-as-a-measurement-module.patch
John Kacur 3db03791e8 Add timerlat as a measurement module
Add timerlat as a measurement module

Resolves: RHEL-28058
Signed-off-by: John Kacur <jkacur@redhat.com>
2024-05-06 17:15:09 -04:00

190 lines
6.1 KiB
Diff

From 393c95ee69ec98816a26aa0583f6b1cac4acb5e7 Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Fri, 12 Apr 2024 14:40:37 -0400
Subject: [PATCH 02/13] rteval: Add rtla timerlat as a measurement module
This is the first step to adding timerlat as a measurement module
With this change you can run timerlat as a standalone rteval file like
this (as root)
python rteval/modules/measurement/timerlat.py
You can also modify your rteval.conf to list timerlat in the
[measurement] section, for example like this
[measurement]
cyclictest: module
timerlat: module
and then both measurement moduels will be run from rteval, for example
rteval -D -d5m --measurement-cpulist=1-5
Will run rteval with Debug info, for 5m and cyclictest and timerlat will
run on cpus 1-5 and load modules will run on the other available cpus.
Currently MakeReport just prints to standard out the same information
that timerlat outputs, in otherwords, there is no processing into xml
yet. Also, there is no way to invoke tracing at the time, but that will
be added soon!
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval-cmd | 1 +
rteval/modules/measurement/timerlat.py | 131 +++++++++++++++++++++++++
2 files changed, 132 insertions(+)
create mode 100644 rteval/modules/measurement/timerlat.py
diff --git a/rteval-cmd b/rteval-cmd
index c72bc614ad78..5cb6d7a44523 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -247,6 +247,7 @@ if __name__ == '__main__':
if not config.HasSection('measurement'):
config.AppendConfig('measurement', {
'cyclictest' : 'module',
+ 'timerlat' : 'module',
'sysstat' : 'module'})
# Prepare log levels before loading modules, not to have unwanted log messages
diff --git a/rteval/modules/measurement/timerlat.py b/rteval/modules/measurement/timerlat.py
new file mode 100644
index 000000000000..d4e78de8d2a2
--- /dev/null
+++ b/rteval/modules/measurement/timerlat.py
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright 2024 John Kacur <jkacur@redhat.com>
+#
+""" timerlat.py - objectd to manage rtla timerlat """
+import os
+import subprocess
+import signal
+import time
+import tempfile
+import libxml2
+from rteval.Log import Log
+from rteval.modules import rtevalModulePrototype
+from rteval.systopology import cpuinfo, SysTopology
+from rteval.cpulist_utils import expand_cpulist, collapse_cpulist
+
+class Timerlat(rtevalModulePrototype):
+ """ measurement modules for rteval """
+ def __init__(self, config, logger=None):
+ rtevalModulePrototype.__init__(self, 'measurement', 'timerlat', logger)
+
+ self.__cfg = config
+
+ self.__numanodes = int(self.__cfg.setdefault('numanodes', 0))
+ self.__priority = int(self.__cfg.setdefault('priority', 95))
+
+ self.__cpulist = self.__cfg.setdefault('cpulist', "")
+ self.__cpus = [str(c) for c in expand_cpulist(self.__cpulist)]
+ self.__numcores = len(self.__cpus)
+
+ self.__timerlat_out = None
+ self.__timerlat_err = None
+ self.__started = False
+ self._log(Log.DEBUG, f"system using {self.__numcores} cpu cores")
+
+
+ def _WorkloadSetup(self):
+ self.__timerlat_process = None
+
+ def _WorkloadBuild(self):
+ self._setReady()
+
+ def _WorkloadPrepare(self):
+ self.__cmd = ['rtla', 'timerlat', 'hist', '-P', f'f:{int(self.__priority)}', '-u']
+ self.__cmd.append(f'-c{self.__cpulist}')
+ self._log(Log.DEBUG, f'self.__cmd = {self.__cmd}')
+ self.__timerlat_out = tempfile.SpooledTemporaryFile(mode='w+b')
+ self.__timerlat_err = tempfile.SpooledTemporaryFile(mode='w+b')
+
+ def _WorkloadTask(self):
+ if self.__started:
+ return
+
+ self._log(Log.DEBUG, f'starting with cmd: {" ".join(self.__cmd)}')
+
+ self.__timerlat_out.seek(0)
+ self.__timerlat_err.seek(0)
+ try:
+ self.__timerlat_process = subprocess.Popen(self.__cmd,
+ stdout=self.__timerlat_out,
+ stderr=self.__timerlat_err,
+ stdin=None)
+ self.__started = True
+ except OSError:
+ self.__started = False
+
+ def WorkloadAlive(self):
+ if self.__started:
+ return self.__timerlat_process.poll() is None
+ return False
+
+ def _WorkloadCleanup(self):
+ if not self.__started:
+ return
+ while self.__timerlat_process.poll() is None:
+ self._log(Log.DEBUG, "Sending SIGINT")
+ os.kill(self.__timerlat_process.pid, signal.SIGINT)
+ time.sleep(2)
+
+ self._setFinished()
+ self.__started = False
+
+ def MakeReport(self):
+ self.__timerlat_out.seek(0)
+ for line in self.__timerlat_out:
+ line = bytes.decode(line)
+ print(line)
+ self.__timerlat_out.close()
+
+
+def ModuleInfo():
+ """ Required measurement module information """
+ return {"parallel": True,
+ "loads": True}
+
+def ModuleParameters():
+ """ default parameters """
+ return {"priority": {"descr": "Run rtla timerlat with this priority",
+ "default": 95,
+ "metavar": "PRIO" }
+ }
+
+def create(params, logger):
+ """ Instantiate a Timerlat measurement module object"""
+ return Timerlat(params, logger)
+
+if __name__ == '__main__':
+ from rteval.rtevalConfig import rtevalConfig
+
+ l = Log()
+ l.SetLogVerbosity(Log.INFO|Log.DEBUG|Log.ERR|Log.WARN)
+
+ cfg = rtevalConfig({}, logger=l)
+ prms = {}
+ modprms = ModuleParameters()
+ for c, p in list(modprms.items()):
+ prms[c] = p['default']
+ cfg.AppendConfig('timerlat', prms)
+
+ cfg_tl = cfg.GetSection('timerlat')
+ cfg_tl.cpulist = collapse_cpulist(SysTopology().online_cpus())
+
+ RUNTIME = 10
+
+ tl = Timerlat(cfg_tl, l)
+ tl._WorkloadSetup()
+ tl._WorkloadPrepare()
+ tl._WorkloadTask()
+ time.sleep(RUNTIME)
+ tl._WorkloadCleanup()
+ tl.MakeReport()
--
2.44.0