3db03791e8
Add timerlat as a measurement module Resolves: RHEL-28058 Signed-off-by: John Kacur <jkacur@redhat.com>
190 lines
6.1 KiB
Diff
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
|
|
|