linux-rt-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] rteval: Handle isolcpus correctly
@ 2023-06-30  9:19 Tomas Glozar
  2023-06-30  9:19 ` [PATCH 1/6] rteval: Detect isolcpus in systopology Tomas Glozar
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

This is a patch set that enables rteval to do load calculations and reporting
correctly on systems with isolated CPUs.

Tomas Glozar (6):
  rteval: Detect isolcpus in systopology
  rteval: Report isolated CPUs
  rteval: Exclude isolcpus from kcompile by default
  rteval: Exclude isolcpus from stressng by default
  rteval: Fix CPU count calculation for hackbench
  rteval: Exclude isolcpus from loads report

 rteval/modules/loads/__init__.py       |  2 +-
 rteval/modules/loads/hackbench.py      |  6 +++-
 rteval/modules/loads/kcompile.py       |  8 +++--
 rteval/modules/loads/stressng.py       |  5 +++
 rteval/modules/measurement/__init__.py |  2 +-
 rteval/rteval_text.xsl                 |  4 +++
 rteval/sysinfo/cputopology.py          | 11 +++++++
 rteval/systopology.py                  | 43 ++++++++++++++++++++++++++
 8 files changed, 76 insertions(+), 5 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/6] rteval: Detect isolcpus in systopology
  2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
@ 2023-06-30  9:19 ` Tomas Glozar
  2023-07-25 13:33   ` John Kacur
  2023-07-25 13:36   ` John Kacur
  2023-06-30  9:19 ` [PATCH 2/6] rteval: Report isolated CPUs Tomas Glozar
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

Works similarly to online_cpus:
- add CpuList.isolated_cpulist to filter isolated CPUs
- add SysTopology.isolated_cpus to get list of isolated CPUs
- add CpuList.nonisolated_cpulist to do the opposite filter
- add SysTopology.default_cpus to get CPUs that are used for scheduling
  by default, i.e. online and non-isolated CPUs

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 rteval/systopology.py | 47 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/rteval/systopology.py b/rteval/systopology.py
index c8f85c5..19443f9 100644
--- a/rteval/systopology.py
+++ b/rteval/systopology.py
@@ -127,6 +127,11 @@ class CpuList:
             return True
         return False
 
+    @staticmethod
+    def isolated_file_exists():
+        """ Check whether machine / kernel is configured with isolated file """
+        return os.path.exists(os.path.join(CpuList.cpupath, "isolated"))
+
     @staticmethod
     def longest_sequence(cpulist):
         """ return index of last element of a sequence that steps by one """
@@ -214,6 +219,24 @@ class CpuList:
                 newlist.append(cpu)
         return newlist
 
+    @staticmethod
+    def isolated_cpulist(cpulist):
+        """Given a cpulist, return a cpulist of isolated CPUs"""
+        if not CpuList.isolated_file_exists():
+            return cpulist
+        isolated_cpulist = sysread(CpuList.cpupath, "isolated")
+        isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist)
+        return list(set(isolated_cpulist) & set(cpulist))
+
+    @staticmethod
+    def nonisolated_cpulist(cpulist):
+        """Given a cpulist, return a cpulist of non-isolated CPUs"""
+        if not CpuList.isolated_file_exists():
+            return cpulist
+        isolated_cpulist = sysread(CpuList.cpupath, "isolated")
+        isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist)
+        return list(set(cpulist).difference(set(isolated_cpulist)))
+
 #
 # class to abstract access to NUMA nodes in /sys filesystem
 #
@@ -362,11 +385,35 @@ class SysTopology:
         cpulist.sort()
         return cpulist
 
+    def isolated_cpus(self):
+        """ return a list of integers of all isolated cpus """
+        cpulist = []
+        for n in self.nodes:
+            cpulist += CpuList.isolated_cpulist(self.getcpus(n))
+        cpulist.sort()
+        return cpulist
+
+    def default_cpus(self):
+        """ return a list of integers of all default schedulable cpus, i.e. online non-isolated cpus """
+        cpulist = []
+        for n in self.nodes:
+            cpulist += CpuList.nonisolated_cpulist(self.getcpus(n))
+        cpulist.sort()
+        return cpulist
+
     def online_cpus_str(self):
         """ return a list of strings of numbers of all online cpus """
         cpulist = [str(cpu) for cpu in self.online_cpus()]
         return cpulist
 
+    def isolated_cpus_str(self):
+        cpulist = [str(cpu) for cpu in self.isolated_cpus()]
+        return cpulist
+
+    def default_cpus_str(self):
+        cpulist = [str(cpu) for cpu in self.default_cpus()]
+        return cpulist
+
     def invert_cpulist(self, cpulist):
         """ return a list of online cpus not in cpulist """
         return [c for c in self.online_cpus() if c not in cpulist]
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/6] rteval: Report isolated CPUs
  2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
  2023-06-30  9:19 ` [PATCH 1/6] rteval: Detect isolcpus in systopology Tomas Glozar
@ 2023-06-30  9:19 ` Tomas Glozar
  2023-07-25 13:38   ` John Kacur
  2023-06-30  9:19 ` [PATCH 3/6] rteval: Exclude isolcpus from kcompile by default Tomas Glozar
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

Add a flag for whether a CPU is isolated in CPUtopology and display
the number of isolated CPUs in text report.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 rteval/rteval_text.xsl        |  4 ++++
 rteval/sysinfo/cputopology.py | 11 +++++++++++
 2 files changed, 15 insertions(+)

diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl
index 7ecfac6..0ef649b 100644
--- a/rteval/rteval_text.xsl
+++ b/rteval/rteval_text.xsl
@@ -59,6 +59,10 @@
 	<xsl:value-of select="SystemInfo/CPUtopology/@num_cpu_cores"/>
 	<xsl:text> (online: </xsl:text>
 	<xsl:value-of select="SystemInfo/CPUtopology/@num_cpu_cores_online"/>
+    <xsl:if test="SystemInfo/CPUtopology/@num_cpu_cores_isolated != 0">
+      <xsl:text>, isolated: </xsl:text>
+      <xsl:value-of select="SystemInfo/CPUtopology/@num_cpu_cores_isolated"/>
+    </xsl:if>
 	<xsl:text>)</xsl:text>
       </xsl:when>
       <xsl:when test="hardware/cpu_topology">
diff --git a/rteval/sysinfo/cputopology.py b/rteval/sysinfo/cputopology.py
index 2bb6323..f60b059 100644
--- a/rteval/sysinfo/cputopology.py
+++ b/rteval/sysinfo/cputopology.py
@@ -25,6 +25,7 @@
 
 import os
 import libxml2
+from rteval.systopology import SysTopology
 
 class CPUtopology:
     "Retrieves an overview over the installed CPU cores and the system topology"
@@ -34,6 +35,7 @@ class CPUtopology:
         self.__cputop_n = None
         self.__cpu_cores = 0
         self.__online_cores = 0
+        self.__isolated_cores = 0
         self.__cpu_sockets = 0
 
     def __read(self, dirname, fname):
@@ -51,6 +53,10 @@ class CPUtopology:
 
         self.__cputop_n = libxml2.newNode('CPUtopology')
 
+        # Get list of isolated CPUs from SysTopology
+        systopology = SysTopology()
+        isolated_cpus = {'cpu' + n for n in systopology.isolated_cpus_str()}
+
         cpusockets = []
         for dirname in os.listdir(self.sysdir):
             # Only parse directories which starts with 'cpu'
@@ -82,6 +88,10 @@ class CPUtopology:
                                                       'physical_package_id')
                             cpu_n.newProp('physical_package_id', str(phys_pkg_id))
                             cpusockets.append(phys_pkg_id)
+                            is_isolated = dirname in isolated_cpus
+                            if is_isolated:
+                             self.__isolated_cores += 1
+                            cpu_n.newProp('isolated', str(int(dirname in isolated_cpus)))
                         break
 
         # Count unique CPU sockets
@@ -97,6 +107,7 @@ class CPUtopology:
         # Summarise the core counts
         self.__cputop_n.newProp('num_cpu_cores', str(self.__cpu_cores))
         self.__cputop_n.newProp('num_cpu_cores_online', str(self.__online_cores))
+        self.__cputop_n.newProp('num_cpu_cores_isolated', str(self.__isolated_cores))
         self.__cputop_n.newProp('num_cpu_sockets', str(self.__cpu_sockets))
 
         return self.__cputop_n
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/6] rteval: Exclude isolcpus from kcompile by default
  2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
  2023-06-30  9:19 ` [PATCH 1/6] rteval: Detect isolcpus in systopology Tomas Glozar
  2023-06-30  9:19 ` [PATCH 2/6] rteval: Report isolated CPUs Tomas Glozar
@ 2023-06-30  9:19 ` Tomas Glozar
  2023-07-25 13:40   ` John Kacur
  2023-06-30  9:19 ` [PATCH 4/6] rteval: Exclude isolcpus from stressng " Tomas Glozar
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

Allows correct calculation of make job count that does not include
isolated CPUs, on which the loads won't be scheduled.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 rteval/modules/loads/kcompile.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/rteval/modules/loads/kcompile.py b/rteval/modules/loads/kcompile.py
index 35ee5cb..30c5965 100644
--- a/rteval/modules/loads/kcompile.py
+++ b/rteval/modules/loads/kcompile.py
@@ -37,6 +37,7 @@ from rteval.systopology import CpuList, SysTopology
 
 expand_cpulist = CpuList.expand_cpulist
 compress_cpulist = CpuList.compress_cpulist
+nonisolated_cpulist = CpuList.nonisolated_cpulist
 
 DEFAULT_KERNEL_PREFIX = "linux-6.1"
 
@@ -55,17 +56,20 @@ class KBuildJob:
         if not os.path.isdir(self.objdir):
             os.mkdir(self.objdir)
 
+        # Exclude isolated CPUs if cpulist not set
+        cpus_available = len(nonisolated_cpulist(self.node.cpus.cpulist))
+
         if os.path.exists('/usr/bin/numactl') and not cpulist:
             # Use numactl
             self.binder = f'numactl --cpunodebind {int(self.node)}'
-            self.jobs = self.calc_jobs_per_cpu() * len(self.node)
+            self.jobs = self.calc_jobs_per_cpu() * cpus_available
         elif cpulist:
             # Use taskset
             self.jobs = self.calc_jobs_per_cpu() * len(cpulist)
             self.binder = f'taskset -c {compress_cpulist(cpulist)}'
         else:
             # Without numactl calculate number of jobs from the node
-            self.jobs = self.calc_jobs_per_cpu() * len(self.node)
+            self.jobs = self.calc_jobs_per_cpu() * cpus_available
 
         self.runcmd = f"make O={self.objdir} -C {self.kdir} -j{self.jobs}"
         self.cleancmd = f"make O={self.objdir} -C {self.kdir} clean allmodconfig"
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/6] rteval: Exclude isolcpus from stressng by default
  2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
                   ` (2 preceding siblings ...)
  2023-06-30  9:19 ` [PATCH 3/6] rteval: Exclude isolcpus from kcompile by default Tomas Glozar
@ 2023-06-30  9:19 ` Tomas Glozar
  2023-07-25 13:42   ` John Kacur
  2023-06-30  9:19 ` [PATCH 5/6] rteval: Fix CPU count calculation for hackbench Tomas Glozar
  2023-06-30  9:19 ` [PATCH 6/6] rteval: Exclude isolcpus from loads report Tomas Glozar
  5 siblings, 1 reply; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

Note: this has little effect now, because the cpus variables is only
used for removing empty nodes unless a cpulist is specified by the user.
However, this can change in the future.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 rteval/modules/loads/stressng.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/rteval/modules/loads/stressng.py b/rteval/modules/loads/stressng.py
index 85cb473..800fdec 100644
--- a/rteval/modules/loads/stressng.py
+++ b/rteval/modules/loads/stressng.py
@@ -9,6 +9,7 @@ from rteval.Log import Log
 from rteval.systopology import CpuList, SysTopology
 
 expand_cpulist = CpuList.expand_cpulist
+nonisolated_cpulist = CpuList.nonisolated_cpulist
 
 class Stressng(CommandLineLoad):
     " This class creates a load module that runs stress-ng "
@@ -69,6 +70,10 @@ class Stressng(CommandLineLoad):
             # if a cpulist was specified, only allow cpus in that list on the node
             if self.cpulist:
                 cpus[n] = [c for c in cpus[n] if c in expand_cpulist(self.cpulist)]
+            # if a cpulist was not specified, exclude isolated cpus
+            else:
+                cpus[n] = CpuList.nonisolated_cpulist(cpus[n])
+
 
         # remove nodes with no cpus available for running
         for node, cpu in cpus.items():
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/6] rteval: Fix CPU count calculation for hackbench
  2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
                   ` (3 preceding siblings ...)
  2023-06-30  9:19 ` [PATCH 4/6] rteval: Exclude isolcpus from stressng " Tomas Glozar
@ 2023-06-30  9:19 ` Tomas Glozar
  2023-07-25 13:44   ` John Kacur
  2023-06-30  9:19 ` [PATCH 6/6] rteval: Exclude isolcpus from loads report Tomas Glozar
  5 siblings, 1 reply; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

Use count from cpulist when specified and all CPUs on node excluding
offline ones and isolated ones if not specified.

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 rteval/modules/loads/hackbench.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/rteval/modules/loads/hackbench.py b/rteval/modules/loads/hackbench.py
index 14e60d1..f5a547e 100644
--- a/rteval/modules/loads/hackbench.py
+++ b/rteval/modules/loads/hackbench.py
@@ -38,6 +38,7 @@ from rteval.Log import Log
 from rteval.systopology import CpuList, SysTopology
 
 expand_cpulist = CpuList.expand_cpulist
+isolated_cpulist = CpuList.isolated_cpulist
 
 class Hackbench(CommandLineLoad):
     def __init__(self, config, logger):
@@ -77,9 +78,12 @@ class Hackbench(CommandLineLoad):
             # if a cpulist was specified, only allow cpus in that list on the node
             if self.cpulist:
                 self.cpus[n] = [c for c in self.cpus[n] if c in expand_cpulist(self.cpulist)]
+            # if a cpulist was not specified, exclude isolated cpus
+            else:
+                self.cpus[n] = CpuList.nonisolated_cpulist(self.cpus[n])
 
             # track largest number of cpus used on a node
-            node_biggest = len(sysTop.getcpus(int(n)))
+            node_biggest = len(self.cpus[n])
             if node_biggest > biggest:
                 biggest = node_biggest
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 6/6] rteval: Exclude isolcpus from loads report
  2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
                   ` (4 preceding siblings ...)
  2023-06-30  9:19 ` [PATCH 5/6] rteval: Fix CPU count calculation for hackbench Tomas Glozar
@ 2023-06-30  9:19 ` Tomas Glozar
  2023-07-25 14:32   ` John Kacur
  5 siblings, 1 reply; 14+ messages in thread
From: Tomas Glozar @ 2023-06-30  9:19 UTC (permalink / raw)
  To: linux-rt-users; +Cc: Tomas Glozar

Use SysTopology.default_cpus() to report cores on which measurements and
loads and run by default to reflect the default behavior (no isolcpus).

Signed-off-by: Tomas Glozar <tglozar@redhat.com>
---
 rteval/modules/loads/__init__.py       | 2 +-
 rteval/modules/measurement/__init__.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py
index 761cc8c..74aad58 100644
--- a/rteval/modules/loads/__init__.py
+++ b/rteval/modules/loads/__init__.py
@@ -138,7 +138,7 @@ class LoadModules(RtEvalModules):
             # Convert str to list and remove offline cpus
             cpulist = CpuList(cpulist).cpulist
         else:
-            cpulist = SysTop().online_cpus()
+            cpulist = SysTop().default_cpus()
         rep_n.newProp("loadcpus", collapse_cpulist(cpulist))
 
         return rep_n
diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py
index d99873e..0e395be 100644
--- a/rteval/modules/measurement/__init__.py
+++ b/rteval/modules/measurement/__init__.py
@@ -194,7 +194,7 @@ measurement profiles, based on their characteristics"""
             # Convert str to list and remove offline cpus
             cpulist = CpuList(cpulist).cpulist
         else:
-            cpulist = SysTop().online_cpus()
+            cpulist = SysTop().default_cpus()
         rep_n.newProp("measurecpus", collapse_cpulist(cpulist))
 
         for mp in self.__measureprofiles:
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/6] rteval: Detect isolcpus in systopology
  2023-06-30  9:19 ` [PATCH 1/6] rteval: Detect isolcpus in systopology Tomas Glozar
@ 2023-07-25 13:33   ` John Kacur
  2023-07-25 13:36   ` John Kacur
  1 sibling, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 13:33 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Works similarly to online_cpus:
> - add CpuList.isolated_cpulist to filter isolated CPUs
> - add SysTopology.isolated_cpus to get list of isolated CPUs
> - add CpuList.nonisolated_cpulist to do the opposite filter
> - add SysTopology.default_cpus to get CPUs that are used for scheduling
>   by default, i.e. online and non-isolated CPUs
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/systopology.py | 47 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/rteval/systopology.py b/rteval/systopology.py
> index c8f85c5..19443f9 100644
> --- a/rteval/systopology.py
> +++ b/rteval/systopology.py
> @@ -127,6 +127,11 @@ class CpuList:
>              return True
>          return False
>  
> +    @staticmethod
> +    def isolated_file_exists():
> +        """ Check whether machine / kernel is configured with isolated file """
> +        return os.path.exists(os.path.join(CpuList.cpupath, "isolated"))
> +
>      @staticmethod
>      def longest_sequence(cpulist):
>          """ return index of last element of a sequence that steps by one """
> @@ -214,6 +219,24 @@ class CpuList:
>                  newlist.append(cpu)
>          return newlist
>  
> +    @staticmethod
> +    def isolated_cpulist(cpulist):
> +        """Given a cpulist, return a cpulist of isolated CPUs"""
> +        if not CpuList.isolated_file_exists():
> +            return cpulist
> +        isolated_cpulist = sysread(CpuList.cpupath, "isolated")
> +        isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist)
> +        return list(set(isolated_cpulist) & set(cpulist))
> +
> +    @staticmethod
> +    def nonisolated_cpulist(cpulist):
> +        """Given a cpulist, return a cpulist of non-isolated CPUs"""
> +        if not CpuList.isolated_file_exists():
> +            return cpulist
> +        isolated_cpulist = sysread(CpuList.cpupath, "isolated")
> +        isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist)
> +        return list(set(cpulist).difference(set(isolated_cpulist)))
> +
>  #
>  # class to abstract access to NUMA nodes in /sys filesystem
>  #
> @@ -362,11 +385,35 @@ class SysTopology:
>          cpulist.sort()
>          return cpulist
>  
> +    def isolated_cpus(self):
> +        """ return a list of integers of all isolated cpus """
> +        cpulist = []
> +        for n in self.nodes:
> +            cpulist += CpuList.isolated_cpulist(self.getcpus(n))
> +        cpulist.sort()
> +        return cpulist
> +
> +    def default_cpus(self):
> +        """ return a list of integers of all default schedulable cpus, i.e. online non-isolated cpus """
> +        cpulist = []
> +        for n in self.nodes:
> +            cpulist += CpuList.nonisolated_cpulist(self.getcpus(n))
> +        cpulist.sort()
> +        return cpulist
> +
>      def online_cpus_str(self):
>          """ return a list of strings of numbers of all online cpus """
>          cpulist = [str(cpu) for cpu in self.online_cpus()]
>          return cpulist
>  
> +    def isolated_cpus_str(self):
> +        cpulist = [str(cpu) for cpu in self.isolated_cpus()]
> +        return cpulist
> +
> +    def default_cpus_str(self):
> +        cpulist = [str(cpu) for cpu in self.default_cpus()]
> +        return cpulist
> +
>      def invert_cpulist(self, cpulist):
>          """ return a list of online cpus not in cpulist """
>          return [c for c in self.online_cpus() if c not in cpulist]
> -- 
> 2.41.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>
--
The code is good, but I don't love the name "default_cpus", but it will 
do. isolated_cpus_str() and default_cpus_str() require docstrings.
I'm signing off on this to move it forward so please send that in a 
separate patch.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/6] rteval: Detect isolcpus in systopology
  2023-06-30  9:19 ` [PATCH 1/6] rteval: Detect isolcpus in systopology Tomas Glozar
  2023-07-25 13:33   ` John Kacur
@ 2023-07-25 13:36   ` John Kacur
  1 sibling, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 13:36 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Works similarly to online_cpus:
> - add CpuList.isolated_cpulist to filter isolated CPUs
> - add SysTopology.isolated_cpus to get list of isolated CPUs
> - add CpuList.nonisolated_cpulist to do the opposite filter
> - add SysTopology.default_cpus to get CPUs that are used for scheduling
>   by default, i.e. online and non-isolated CPUs
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/systopology.py | 47 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/rteval/systopology.py b/rteval/systopology.py
> index c8f85c5..19443f9 100644
> --- a/rteval/systopology.py
> +++ b/rteval/systopology.py
> @@ -127,6 +127,11 @@ class CpuList:
>              return True
>          return False
>  
> +    @staticmethod
> +    def isolated_file_exists():
> +        """ Check whether machine / kernel is configured with isolated file """
> +        return os.path.exists(os.path.join(CpuList.cpupath, "isolated"))
> +
>      @staticmethod
>      def longest_sequence(cpulist):
>          """ return index of last element of a sequence that steps by one """
> @@ -214,6 +219,24 @@ class CpuList:
>                  newlist.append(cpu)
>          return newlist
>  
> +    @staticmethod
> +    def isolated_cpulist(cpulist):
> +        """Given a cpulist, return a cpulist of isolated CPUs"""
> +        if not CpuList.isolated_file_exists():
> +            return cpulist
> +        isolated_cpulist = sysread(CpuList.cpupath, "isolated")
> +        isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist)
> +        return list(set(isolated_cpulist) & set(cpulist))
> +
> +    @staticmethod
> +    def nonisolated_cpulist(cpulist):
> +        """Given a cpulist, return a cpulist of non-isolated CPUs"""
> +        if not CpuList.isolated_file_exists():
> +            return cpulist
> +        isolated_cpulist = sysread(CpuList.cpupath, "isolated")
> +        isolated_cpulist = CpuList.expand_cpulist(isolated_cpulist)
> +        return list(set(cpulist).difference(set(isolated_cpulist)))
> +
>  #
>  # class to abstract access to NUMA nodes in /sys filesystem
>  #
> @@ -362,11 +385,35 @@ class SysTopology:
>          cpulist.sort()
>          return cpulist
>  
> +    def isolated_cpus(self):
> +        """ return a list of integers of all isolated cpus """
> +        cpulist = []
> +        for n in self.nodes:
> +            cpulist += CpuList.isolated_cpulist(self.getcpus(n))
> +        cpulist.sort()
> +        return cpulist
> +
> +    def default_cpus(self):
> +        """ return a list of integers of all default schedulable cpus, i.e. online non-isolated cpus """
> +        cpulist = []
> +        for n in self.nodes:
> +            cpulist += CpuList.nonisolated_cpulist(self.getcpus(n))
> +        cpulist.sort()
> +        return cpulist
> +
>      def online_cpus_str(self):
>          """ return a list of strings of numbers of all online cpus """
>          cpulist = [str(cpu) for cpu in self.online_cpus()]
>          return cpulist
>  
> +    def isolated_cpus_str(self):
> +        cpulist = [str(cpu) for cpu in self.isolated_cpus()]
> +        return cpulist
> +
> +    def default_cpus_str(self):
> +        cpulist = [str(cpu) for cpu in self.default_cpus()]
> +        return cpulist
> +
>      def invert_cpulist(self, cpulist):
>          """ return a list of online cpus not in cpulist """
>          return [c for c in self.online_cpus() if c not in cpulist]
> -- 
> 2.41.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/6] rteval: Report isolated CPUs
  2023-06-30  9:19 ` [PATCH 2/6] rteval: Report isolated CPUs Tomas Glozar
@ 2023-07-25 13:38   ` John Kacur
  0 siblings, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 13:38 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Add a flag for whether a CPU is isolated in CPUtopology and display
> the number of isolated CPUs in text report.
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/rteval_text.xsl        |  4 ++++
>  rteval/sysinfo/cputopology.py | 11 +++++++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/rteval/rteval_text.xsl b/rteval/rteval_text.xsl
> index 7ecfac6..0ef649b 100644
> --- a/rteval/rteval_text.xsl
> +++ b/rteval/rteval_text.xsl
> @@ -59,6 +59,10 @@
>  	<xsl:value-of select="SystemInfo/CPUtopology/@num_cpu_cores"/>
>  	<xsl:text> (online: </xsl:text>
>  	<xsl:value-of select="SystemInfo/CPUtopology/@num_cpu_cores_online"/>
> +    <xsl:if test="SystemInfo/CPUtopology/@num_cpu_cores_isolated != 0">
> +      <xsl:text>, isolated: </xsl:text>
> +      <xsl:value-of select="SystemInfo/CPUtopology/@num_cpu_cores_isolated"/>
> +    </xsl:if>
>  	<xsl:text>)</xsl:text>
>        </xsl:when>
>        <xsl:when test="hardware/cpu_topology">
> diff --git a/rteval/sysinfo/cputopology.py b/rteval/sysinfo/cputopology.py
> index 2bb6323..f60b059 100644
> --- a/rteval/sysinfo/cputopology.py
> +++ b/rteval/sysinfo/cputopology.py
> @@ -25,6 +25,7 @@
>  
>  import os
>  import libxml2
> +from rteval.systopology import SysTopology
>  
>  class CPUtopology:
>      "Retrieves an overview over the installed CPU cores and the system topology"
> @@ -34,6 +35,7 @@ class CPUtopology:
>          self.__cputop_n = None
>          self.__cpu_cores = 0
>          self.__online_cores = 0
> +        self.__isolated_cores = 0
>          self.__cpu_sockets = 0
>  
>      def __read(self, dirname, fname):
> @@ -51,6 +53,10 @@ class CPUtopology:
>  
>          self.__cputop_n = libxml2.newNode('CPUtopology')
>  
> +        # Get list of isolated CPUs from SysTopology
> +        systopology = SysTopology()
> +        isolated_cpus = {'cpu' + n for n in systopology.isolated_cpus_str()}
> +
>          cpusockets = []
>          for dirname in os.listdir(self.sysdir):
>              # Only parse directories which starts with 'cpu'
> @@ -82,6 +88,10 @@ class CPUtopology:
>                                                        'physical_package_id')
>                              cpu_n.newProp('physical_package_id', str(phys_pkg_id))
>                              cpusockets.append(phys_pkg_id)
> +                            is_isolated = dirname in isolated_cpus
> +                            if is_isolated:
> +                             self.__isolated_cores += 1
> +                            cpu_n.newProp('isolated', str(int(dirname in isolated_cpus)))
>                          break
>  
>          # Count unique CPU sockets
> @@ -97,6 +107,7 @@ class CPUtopology:
>          # Summarise the core counts
>          self.__cputop_n.newProp('num_cpu_cores', str(self.__cpu_cores))
>          self.__cputop_n.newProp('num_cpu_cores_online', str(self.__online_cores))
> +        self.__cputop_n.newProp('num_cpu_cores_isolated', str(self.__isolated_cores))
>          self.__cputop_n.newProp('num_cpu_sockets', str(self.__cpu_sockets))
>  
>          return self.__cputop_n
> -- 
> 2.41.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/6] rteval: Exclude isolcpus from kcompile by default
  2023-06-30  9:19 ` [PATCH 3/6] rteval: Exclude isolcpus from kcompile by default Tomas Glozar
@ 2023-07-25 13:40   ` John Kacur
  0 siblings, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 13:40 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Allows correct calculation of make job count that does not include
> isolated CPUs, on which the loads won't be scheduled.
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/modules/loads/kcompile.py | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/rteval/modules/loads/kcompile.py b/rteval/modules/loads/kcompile.py
> index 35ee5cb..30c5965 100644
> --- a/rteval/modules/loads/kcompile.py
> +++ b/rteval/modules/loads/kcompile.py
> @@ -37,6 +37,7 @@ from rteval.systopology import CpuList, SysTopology
>  
>  expand_cpulist = CpuList.expand_cpulist
>  compress_cpulist = CpuList.compress_cpulist
> +nonisolated_cpulist = CpuList.nonisolated_cpulist
>  
>  DEFAULT_KERNEL_PREFIX = "linux-6.1"
>  
> @@ -55,17 +56,20 @@ class KBuildJob:
>          if not os.path.isdir(self.objdir):
>              os.mkdir(self.objdir)
>  
> +        # Exclude isolated CPUs if cpulist not set
> +        cpus_available = len(nonisolated_cpulist(self.node.cpus.cpulist))
> +
>          if os.path.exists('/usr/bin/numactl') and not cpulist:
>              # Use numactl
>              self.binder = f'numactl --cpunodebind {int(self.node)}'
> -            self.jobs = self.calc_jobs_per_cpu() * len(self.node)
> +            self.jobs = self.calc_jobs_per_cpu() * cpus_available
>          elif cpulist:
>              # Use taskset
>              self.jobs = self.calc_jobs_per_cpu() * len(cpulist)
>              self.binder = f'taskset -c {compress_cpulist(cpulist)}'
>          else:
>              # Without numactl calculate number of jobs from the node
> -            self.jobs = self.calc_jobs_per_cpu() * len(self.node)
> +            self.jobs = self.calc_jobs_per_cpu() * cpus_available
>  
>          self.runcmd = f"make O={self.objdir} -C {self.kdir} -j{self.jobs}"
>          self.cleancmd = f"make O={self.objdir} -C {self.kdir} clean allmodconfig"
> -- 
> 2.41.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 4/6] rteval: Exclude isolcpus from stressng by default
  2023-06-30  9:19 ` [PATCH 4/6] rteval: Exclude isolcpus from stressng " Tomas Glozar
@ 2023-07-25 13:42   ` John Kacur
  0 siblings, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 13:42 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Note: this has little effect now, because the cpus variables is only
> used for removing empty nodes unless a cpulist is specified by the user.
> However, this can change in the future.
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/modules/loads/stressng.py | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/rteval/modules/loads/stressng.py b/rteval/modules/loads/stressng.py
> index 85cb473..800fdec 100644
> --- a/rteval/modules/loads/stressng.py
> +++ b/rteval/modules/loads/stressng.py
> @@ -9,6 +9,7 @@ from rteval.Log import Log
>  from rteval.systopology import CpuList, SysTopology
>  
>  expand_cpulist = CpuList.expand_cpulist
> +nonisolated_cpulist = CpuList.nonisolated_cpulist
>  
>  class Stressng(CommandLineLoad):
>      " This class creates a load module that runs stress-ng "
> @@ -69,6 +70,10 @@ class Stressng(CommandLineLoad):
>              # if a cpulist was specified, only allow cpus in that list on the node
>              if self.cpulist:
>                  cpus[n] = [c for c in cpus[n] if c in expand_cpulist(self.cpulist)]
> +            # if a cpulist was not specified, exclude isolated cpus
> +            else:
> +                cpus[n] = CpuList.nonisolated_cpulist(cpus[n])
> +
>  
>          # remove nodes with no cpus available for running
>          for node, cpu in cpus.items():
> -- 
> 2.41.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/6] rteval: Fix CPU count calculation for hackbench
  2023-06-30  9:19 ` [PATCH 5/6] rteval: Fix CPU count calculation for hackbench Tomas Glozar
@ 2023-07-25 13:44   ` John Kacur
  0 siblings, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 13:44 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Use count from cpulist when specified and all CPUs on node excluding
> offline ones and isolated ones if not specified.
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/modules/loads/hackbench.py | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/rteval/modules/loads/hackbench.py b/rteval/modules/loads/hackbench.py
> index 14e60d1..f5a547e 100644
> --- a/rteval/modules/loads/hackbench.py
> +++ b/rteval/modules/loads/hackbench.py
> @@ -38,6 +38,7 @@ from rteval.Log import Log
>  from rteval.systopology import CpuList, SysTopology
>  
>  expand_cpulist = CpuList.expand_cpulist
> +isolated_cpulist = CpuList.isolated_cpulist
>  
>  class Hackbench(CommandLineLoad):
>      def __init__(self, config, logger):
> @@ -77,9 +78,12 @@ class Hackbench(CommandLineLoad):
>              # if a cpulist was specified, only allow cpus in that list on the node
>              if self.cpulist:
>                  self.cpus[n] = [c for c in self.cpus[n] if c in expand_cpulist(self.cpulist)]
> +            # if a cpulist was not specified, exclude isolated cpus
> +            else:
> +                self.cpus[n] = CpuList.nonisolated_cpulist(self.cpus[n])
>  
>              # track largest number of cpus used on a node
> -            node_biggest = len(sysTop.getcpus(int(n)))
> +            node_biggest = len(self.cpus[n])
>              if node_biggest > biggest:
>                  biggest = node_biggest
>  
> -- 
> 2.41.0
> 
> 

Signed-off-by: John Kacur <jkacur@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 6/6] rteval: Exclude isolcpus from loads report
  2023-06-30  9:19 ` [PATCH 6/6] rteval: Exclude isolcpus from loads report Tomas Glozar
@ 2023-07-25 14:32   ` John Kacur
  0 siblings, 0 replies; 14+ messages in thread
From: John Kacur @ 2023-07-25 14:32 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: linux-rt-users



On Fri, 30 Jun 2023, Tomas Glozar wrote:

> Use SysTopology.default_cpus() to report cores on which measurements and
> loads and run by default to reflect the default behavior (no isolcpus).
> 
> Signed-off-by: Tomas Glozar <tglozar@redhat.com>
> ---
>  rteval/modules/loads/__init__.py       | 2 +-
>  rteval/modules/measurement/__init__.py | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py
> index 761cc8c..74aad58 100644
> --- a/rteval/modules/loads/__init__.py
> +++ b/rteval/modules/loads/__init__.py
> @@ -138,7 +138,7 @@ class LoadModules(RtEvalModules):
>              # Convert str to list and remove offline cpus
>              cpulist = CpuList(cpulist).cpulist
>          else:
> -            cpulist = SysTop().online_cpus()
> +            cpulist = SysTop().default_cpus()
>          rep_n.newProp("loadcpus", collapse_cpulist(cpulist))
>  
>          return rep_n
> diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py
> index d99873e..0e395be 100644
> --- a/rteval/modules/measurement/__init__.py
> +++ b/rteval/modules/measurement/__init__.py
> @@ -194,7 +194,7 @@ measurement profiles, based on their characteristics"""
>              # Convert str to list and remove offline cpus
>              cpulist = CpuList(cpulist).cpulist
>          else:
> -            cpulist = SysTop().online_cpus()
> +            cpulist = SysTop().default_cpus()
>          rep_n.newProp("measurecpus", collapse_cpulist(cpulist))
>  
>          for mp in self.__measureprofiles:
> -- 
> 2.41.0
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-07-25 14:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-30  9:19 [PATCH 0/6] rteval: Handle isolcpus correctly Tomas Glozar
2023-06-30  9:19 ` [PATCH 1/6] rteval: Detect isolcpus in systopology Tomas Glozar
2023-07-25 13:33   ` John Kacur
2023-07-25 13:36   ` John Kacur
2023-06-30  9:19 ` [PATCH 2/6] rteval: Report isolated CPUs Tomas Glozar
2023-07-25 13:38   ` John Kacur
2023-06-30  9:19 ` [PATCH 3/6] rteval: Exclude isolcpus from kcompile by default Tomas Glozar
2023-07-25 13:40   ` John Kacur
2023-06-30  9:19 ` [PATCH 4/6] rteval: Exclude isolcpus from stressng " Tomas Glozar
2023-07-25 13:42   ` John Kacur
2023-06-30  9:19 ` [PATCH 5/6] rteval: Fix CPU count calculation for hackbench Tomas Glozar
2023-07-25 13:44   ` John Kacur
2023-06-30  9:19 ` [PATCH 6/6] rteval: Exclude isolcpus from loads report Tomas Glozar
2023-07-25 14:32   ` John Kacur

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).