From patchwork Fri Jun 21 02:24:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Crystal Wood X-Patchwork-Id: 806592 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A405D83CD4 for ; Fri, 21 Jun 2024 02:24:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936666; cv=none; b=TBCpPM9ISIspNgsPCObhSdICfwYdgvc5tBOIv1H3RByN0OVdMLkVwes3N7xW/vUpTtZrmsMbk7kETQwNP+2dmJ8GJCxx5bvvPwWOq4/81XQq9NTiglLYFnLKtz2EwMcrM6HRg60F0ZMVK3o/3k3F+6hiVySWUSoKHqFOOYCnn88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936666; c=relaxed/simple; bh=ruaxv44U3JsJmigocK/xiS8npG0/ky8Ntyg7IBcJyhQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=a0vWyOs6dnDYPOBjUS+rYiF7yOGzeFN7m4k2VGlU8h+76Vk2yn/KiObI+S/cYjrq4l/FkfdyNTTEJ9jrhdSShIGgIGlNpzF7AjDh7gMaZpTzDPsmyrk8IEIa2h2UIS8iAcpHTlS9Co6Sh/x3WQrnm0GUJ63zY0GxSZcTlEWSPdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=h+q7AN7M; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="h+q7AN7M" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1718936663; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YJry7iiHm8dpzuEo0tuK+dtMLVxeW8qjYkubYvZKDjc=; b=h+q7AN7M8V7QVW3xWh/XGASwCA3ZUJCzYN5AUYoSU1o72fmyf3mPCSIW5k9YABhQdXls6u H1WXed9i6zO+vzOglg34dMoK6PGEsiAR0dycsHiOfSEgjk6XVkpKX6rqOdM26v+paRl6xl Q5IWEX/yohhS0WMc9B8zbaQPW59c2Lg= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-527-s7-WfR0kOouPfOYG-x9wBw-1; Thu, 20 Jun 2024 22:24:22 -0400 X-MC-Unique: s7-WfR0kOouPfOYG-x9wBw-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3406919560AD for ; Fri, 21 Jun 2024 02:24:21 +0000 (UTC) Received: from p1g2.hsd1.mn.comcast.net (unknown [10.2.16.179]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C47761956048; Fri, 21 Jun 2024 02:24:19 +0000 (UTC) From: Crystal Wood To: John Kacur , Clark Williams Cc: linux-rt-users@vger.kernel.org, Crystal Wood Subject: [PATCH 1/4] rteval: measurement: Remove ModuleInfo() Date: Thu, 20 Jun 2024 21:24:14 -0500 Message-ID: <20240621022417.2086751-2-crwood@redhat.com> In-Reply-To: <20240621022417.2086751-1-crwood@redhat.com> References: <20240621022417.2086751-1-crwood@redhat.com> Precedence: bulk X-Mailing-List: linux-rt-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 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 --- 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 e8345fab1ad7..19dd30732936 100644 --- a/rteval/modules/measurement/timerlat.py +++ b/rteval/modules/measurement/timerlat.py @@ -329,11 +329,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", From patchwork Fri Jun 21 02:24:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Crystal Wood X-Patchwork-Id: 807195 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0E0D384052 for ; Fri, 21 Jun 2024 02:24:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936669; cv=none; b=LJvFxBPEhJ2jqt5DKx6gpujzCjY+JFC9Dbo+Wmv6tasJvO6cV2H3xjI8dQYoiOKHx/DPOvrggB0FrVRnrqYmzoNnakMsfw+Qck+nyjz5b1xtfUoEb3NDqAGpunPgpwzaQlRaCEsGNRu5LW8XvBl7SdKOt6tiMBW/tM/7jOlqQs4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936669; c=relaxed/simple; bh=KNE04tsQb7pS7cGTxbdNy7KDC6/kr633Yg+JcUXVzbA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bKSTdmLcHCtw/QqasiaPRXKf6MwkacEbkJSUXLwimc2QcKnVnvMmODJeRWmBA2PTRJ8O+v23/jnPAk1/ReMkdECB4prxXFl3g+dUDjJNVjakFWR1dkypX4TCJac7AUkpiQeeMwAuxGdKNrzn9F95HhHuXkRCcyhnhnBQKmnHLVo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=JMcwwHmV; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="JMcwwHmV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1718936664; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=08QkzcTSfpQlDxGnM4YigW8fTADvwzjj5NIeIzgBa70=; b=JMcwwHmV4gX0UmmqzGpQReD0MFk0963isDvZDx+Wf57zkiadHL1yq9YMR0sBZbrAqeVGUX NRdacISu+NoEJi6dODgDo8T9IHQbKbaugU4AxrkZZ5Qar1qsqHZQKPAhX2eFH5pGeiTy6v eyU8Jzryv4S1p14JcRufD4LRwzJnnT4= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-661-xoOdizgOMQuxEPYNMAE95Q-1; Thu, 20 Jun 2024 22:24:23 -0400 X-MC-Unique: xoOdizgOMQuxEPYNMAE95Q-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4E4DF195608F for ; Fri, 21 Jun 2024 02:24:22 +0000 (UTC) Received: from p1g2.hsd1.mn.comcast.net (unknown [10.2.16.179]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1BB6D1956053; Fri, 21 Jun 2024 02:24:20 +0000 (UTC) From: Crystal Wood To: John Kacur , Clark Williams Cc: linux-rt-users@vger.kernel.org, Crystal Wood Subject: [PATCH 2/4] rteval: Remove MeasurementProfile Date: Thu, 20 Jun 2024 21:24:15 -0500 Message-ID: <20240621022417.2086751-3-crwood@redhat.com> In-Reply-To: <20240621022417.2086751-1-crwood@redhat.com> References: <20240621022417.2086751-1-crwood@redhat.com> Precedence: bulk X-Mailing-List: linux-rt-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Now that the ModuleInfo() flags are gone, remove the remaining infrastructure around measurement profiles. Signed-off-by: Crystal Wood --- 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 @@ core index value - + - + - + - + - - - + + + - - - + + + @@ -38,7 +38,7 @@ - + @@ -54,7 +54,7 @@ - + diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl index 2f03bda0bb55..1297b12f77e6 100644 --- a/rteval/rteval_text.xsl +++ b/rteval/rteval_text.xsl @@ -154,8 +154,8 @@ - - + + =================================================================== @@ -178,21 +178,8 @@ - - Measurement profile - : - - With loads, - Without loads, - - - - measurements in parallel - - - measurements serialised - - + + Measurements: @@ -206,7 +193,7 @@ - + Latency test Started: @@ -238,7 +225,7 @@ - + CPU core Priority: @@ -251,7 +238,7 @@ - + Samples: @@ -301,7 +288,7 @@ - + Latency test Started: @@ -333,7 +320,7 @@ - + CPU core Priority: @@ -346,7 +333,7 @@ - + Samples: @@ -397,7 +384,7 @@ - + Hardware latency detector Run duration: @@ -422,12 +409,12 @@ - + Hardware latency detector ** WARNING ** hwlatedect failed to run - + - @ @@ -436,7 +423,7 @@ - + sysstat measurements Started: From patchwork Fri Jun 21 02:24:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Crystal Wood X-Patchwork-Id: 806591 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56F3784A2F for ; Fri, 21 Jun 2024 02:24:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936669; cv=none; b=OkCvYhCpCI+PGUWJ2spUS5Y9QmUDSATFUMUdcsppy5IL0Vt2TdExb5lzyLl9iYWJ7B4ZAUdzYvygNPmJwNrdGZ+ineU4HutMB31VAYfBbgOJU4lpdt7ISA5JCceSuPYTofee9YPzmuhBm8nKZ4cY3UvSuFGC6FchdSzZ/AmQC/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936669; c=relaxed/simple; bh=rnQ8d55E4nRkj9VaLYTtBaKsZdZlGIxeYqizhAJqQjM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qHINLQgT8ezdBq1wPWqeFZntdntnZJdNED/wQV8rahIMHLJ21I5udT2NVca/cw/KZRNFyAXwkPedOYkrc6+9q9HFnL1eU3GRVwiGihoggHAQanXZF4QhChdoC2FAc3xbv1RulOKKQfupsmHVlimO7biT1gxkjD0SastWzsGxC5E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=gZrn2uCt; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="gZrn2uCt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1718936666; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=p+x9fcL9dIpnIkj8cwuPDSdHV30EDf0t11I71DgIxtc=; b=gZrn2uCt9+ldtGAxnQZd/XDRG2lwa7cnCtnzMqsfQYPKFT297V3tSH4w22HMHpfJz3CAxn 9KdWrB7i9czxio+sgNRUXHDzaP12IwIvm7GF65Q0Tao68ZS9Q4jYg7xJlkLQ5SxR2M5QdE QGvJMcpXLXhWdJvovKBMzsbzHVcY290= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-679-81GrI_X0MDGDerJTU8VnkA-1; Thu, 20 Jun 2024 22:24:24 -0400 X-MC-Unique: 81GrI_X0MDGDerJTU8VnkA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id CDC27195608E for ; Fri, 21 Jun 2024 02:24:23 +0000 (UTC) Received: from p1g2.hsd1.mn.comcast.net (unknown [10.2.16.179]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 889851956048; Fri, 21 Jun 2024 02:24:22 +0000 (UTC) From: Crystal Wood To: John Kacur , Clark Williams Cc: linux-rt-users@vger.kernel.org, Crystal Wood Subject: [PATCH 3/4] rteval: RtEvalModules: Remove unused methods Date: Thu, 20 Jun 2024 21:24:16 -0500 Message-ID: <20240621022417.2086751-4-crwood@redhat.com> In-Reply-To: <20240621022417.2086751-1-crwood@redhat.com> References: <20240621022417.2086751-1-crwood@redhat.com> Precedence: bulk X-Mailing-List: linux-rt-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 With measurement profiles gone, remove methods that no longer have any users. Signed-off-by: Crystal Wood --- 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 From patchwork Fri Jun 21 02:24:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Crystal Wood X-Patchwork-Id: 807194 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFF9083CD4 for ; Fri, 21 Jun 2024 02:24:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936670; cv=none; b=SZOn5dBLKkeBcNPCB4xbcly/41zeowtGqvHbD1kScF5cqJGDyF6e/7HpwnEXyor5aXhoi1wfyFWpGFxiptRjDLltFQNJWvkTwZ5x5gSIFaZ3R9K/ZlhkJDWSs4+SGh0O0Fd/OQ80MQ9vLMTKYFO31QcxFtqPhj1s/H/MvPKj7ik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718936670; c=relaxed/simple; bh=wTeTT5w8XKrJfQ7mt9QJw3NFnyd8ZQmBSlTSt+3u7sQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Lj/HuOSNSRD6kJ0fiwy3nQeCopIsxyWfgxnYSL1ovrwfkeyBrzDaQiCByuLvRKT6qN3iaxy166raI2i6InGJmmVmFdV67F0Wea8hhsb+o2i8/o4J7581O4S0Zu7YGMBTjmxrGYUzvEaI8ZP10Z0rh8WMf8u+bAubft2TzUOITkI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=itLA+Naw; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="itLA+Naw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1718936667; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iQFmeZ/Hi+Syg5tzZxyH+U1DjdQyotDHQrBwt9/UZYc=; b=itLA+NawOUUX3czK5oVL5O0Id79AXkFyQKMcHwlO4yd10YioRphtqUiRB8Bf3iaTCKjHlz hsq4+gg2MQpYSpVYOKFOVXnsrtvfzaD9D2B/DFs/itf3zzBG6+Jg40cyLYsXXM07LMkmHa g9BZsi419p9Hwd6/1vU4zQtQrOJ+RiI= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-631-wwiwPuJ1MH6bNx7CI0YSrA-1; Thu, 20 Jun 2024 22:24:26 -0400 X-MC-Unique: wwiwPuJ1MH6bNx7CI0YSrA-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 352691956086 for ; Fri, 21 Jun 2024 02:24:25 +0000 (UTC) Received: from p1g2.hsd1.mn.comcast.net (unknown [10.2.16.179]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E5D411956048; Fri, 21 Jun 2024 02:24:23 +0000 (UTC) From: Crystal Wood To: John Kacur , Clark Williams Cc: linux-rt-users@vger.kernel.org, Crystal Wood Subject: [PATCH 4/4] rteval: Enforce only one latency measurement module at a time Date: Thu, 20 Jun 2024 21:24:17 -0500 Message-ID: <20240621022417.2086751-5-crwood@redhat.com> In-Reply-To: <20240621022417.2086751-1-crwood@redhat.com> References: <20240621022417.2086751-1-crwood@redhat.com> Precedence: bulk X-Mailing-List: linux-rt-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 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 --- 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 19dd30732936..793b80cc0dac 100644 --- a/rteval/modules/measurement/timerlat.py +++ b/rteval/modules/measurement/timerlat.py @@ -206,6 +206,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):