From: Gautham R. Shenoy <hidden> Date: 2020-02-21 05:19:10
From: "Gautham R. Shenoy" <redacted>
Hi,
This is the second version of the patches to track and expose idle
PURR and SPURR ticks. These patches are required by tools such as
lparstat to compute system utilization for capacity planning purposes.
v1 can be found here: https://lore.kernel.org/patchwork/cover/1159341/
The key changes from v1 are
- The sysfs reads of idle PURR and SPURR now send an
smp_call_function to the target CPU in order to read the most
recent value of idle PURR and SPURR. This is required if the
target CPU was idle for a long duration, in which case the
cycles corresponding to its latest idle duration would not be
updated in the variable tracking idle PURR/SPURR. Thus merely
reading the variable would not reflect the most accurate idle
PURR/SPURR ticks.
- Ensured that even when idle PURR/SPURR values are read in an
interrupt context in-between idle_loop_prolog() and
idle_loop_epilog(), we return the value that includes the cycles
spent in the most recent idle period.
- The sysfs files for idle_purr and idle_spurr are created only
when the FW_FEATURE_LPAR is enabled (the earlier version was
checking for FW_FEATURE_SPLPAR)
Motivation:
===========
On PSeries LPARs, the data centers planners desire a more accurate
view of system utilization per resource such as CPU to plan the system
capacity requirements better. Such accuracy can be obtained by reading
PURR/SPURR registers for CPU resource utilization.
Tools such as lparstat which are used to compute the utilization need
to know [S]PURR ticks when the cpu was busy or idle. The [S]PURR
counters are already exposed through sysfs. We already account for
PURR ticks when we go to idle so that we can update the VPA area. This
patchset extends support to account for SPURR ticks when idle, and
expose both via per-cpu sysfs files.
These patches are required for enhancement to the lparstat utility
that compute the CPU utilization based on PURR and SPURR which can be
found here :
https://groups.google.com/forum/#!topic/powerpc-utils-devel/fYRo69xO9r4
With the patches, when lparstat is run on a LPAR running CPU-Hogs,
=========================================================================
$sudo ./src/lparstat -E 1 3
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=2 mem=4834176 kB cpus=0 ent=2.00
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
99.99 0.00 3.35GHz[111%] 110.99 0.00
100.00 0.00 3.35GHz[111%] 111.00 0.00
100.00 0.00 3.35GHz[111%] 111.00 0.00
=========================================================================
When lparstat is run on an LPAR that is idle,
=========================================================================
$ sudo ./src/lparstat -E 1 3
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=2 mem=4834176 kB cpus=0 ent=2.00
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
0.09 99.91 2.11GHz[ 70%] 0.11 69.90
0.32 99.68 2.17GHz[ 72%] 0.25 71.75
0.56 99.44 2.18GHz[ 72%] 0.42 71.58
=========================================================================
Gautham R. Shenoy (5):
powerpc: Move idle_loop_prolog()/epilog() functions to header file
powerpc/idle: Add accessor function to always read latest idle PURR
powerpc/pseries: Account for SPURR ticks on idle CPUs
powerpc/sysfs: Show idle_purr and idle_spurr for every CPU
Documentation: Document sysfs interfaces purr, spurr, idle_purr,
idle_spurr
Documentation/ABI/testing/sysfs-devices-system-cpu | 39 ++++++++++
arch/powerpc/include/asm/idle.h | 88 ++++++++++++++++++++++
arch/powerpc/kernel/sysfs.c | 54 ++++++++++++-
arch/powerpc/platforms/pseries/setup.c | 8 +-
drivers/cpuidle/cpuidle-pseries.c | 39 ++--------
5 files changed, 191 insertions(+), 37 deletions(-)
create mode 100644 arch/powerpc/include/asm/idle.h
--
1.9.4
From: Gautham R. Shenoy <hidden> Date: 2020-02-21 05:19:00
From: "Gautham R. Shenoy" <redacted>
Currently prior to entering an idle state on a Linux Guest, the
pseries cpuidle driver implement an idle_loop_prolog() and
idle_loop_epilog() functions which ensure that idle_purr is correctly
computed, and the hypervisor is informed that the CPU cycles have been
donated.
These prolog and epilog functions are also required in the default
idle call, i.e pseries_lpar_idle(). Hence move these accessor
functions to a common header file and call them from
pseries_lpar_idle(). Since the existing header files such as
asm/processor.h have enough clutter, create a new header file
asm/idle.h.
Signed-off-by: Gautham R. Shenoy <redacted>
---
arch/powerpc/include/asm/idle.h | 27 +++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/setup.c | 7 +++++--
drivers/cpuidle/cpuidle-pseries.c | 24 +-----------------------
3 files changed, 33 insertions(+), 25 deletions(-)
create mode 100644 arch/powerpc/include/asm/idle.h
@@ -319,6 +320,8 @@ static int alloc_dispatch_log_kmem_cache(void)staticvoidpseries_lpar_idle(void){+unsignedlongin_purr;+/**Defaulthandlertogointolowthreadpriorityandpossibly*lowpowermodebycedingprocessortohypervisor
@@ -328,7 +331,7 @@ static void pseries_lpar_idle(void)return;/* Indicate to hypervisor that we are idle. */-get_lppaca()->idle=1;+idle_loop_prolog(&in_purr);/**Yieldtheprocessortothehypervisor.Wereturnif
@@ -580,3 +580,42 @@ Description: Secure Virtual Machine If 1, it means the system is using the Protected Execution Facility in POWER9 and newer processors. i.e., it is a Secure Virtual Machine.++What: /sys/devices/system/cpu/cpuX/purr+Date: Apr 2005+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: PURR ticks for this CPU since the system boot.++ The Processor Utilization Resources Register (PURR) is+ a 64-bit counter which provides an estimate of the+ resources used by the CPU thread. The contents of this+ register increases monotonically. This sysfs interface+ exposes the number of PURR ticks for cpuX.++What: /sys/devices/system/cpu/cpuX/spurr+Date: Dec 2006+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: SPURR ticks for this CPU since the system boot.++ The Scaled Processor Utilization Resources Register+ (SPURR) is a 64-bit counter that provides a frequency+ invariant estimate of the resources used by the CPU+ thread. The contents of this register increases+ monotonically. This sysfs interface exposes the number+ of SPURR ticks for cpuX.++What: /sys/devices/system/cpu/cpuX/idle_purr+Date: Nov 2019+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: PURR ticks for cpuX when it was idle.++ This sysfs interface exposes the number of PURR ticks+ for cpuX when it was idle.++What: /sys/devices/system/cpu/cpuX/spurr+Date: Nov 2019+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: SPURR ticks for cpuX when it was idle.++ This sysfs interface exposes the number of SPURR ticks+ for cpuX when it was idle.
From: Gautham R. Shenoy <hidden> Date: 2020-02-21 05:19:08
From: "Gautham R. Shenoy" <redacted>
On Pseries LPARs, to calculate utilization, we need to know the
[S]PURR ticks when the CPUs were busy or idle.
The total PURR and SPURR ticks are already exposed via the per-cpu
sysfs files "purr" and "spurr". This patch adds support for exposing
the idle PURR and SPURR ticks via new per-cpu sysfs files named
"idle_purr" and "idle_spurr".
Signed-off-by: Gautham R. Shenoy <redacted>
---
arch/powerpc/kernel/sysfs.c | 54 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 51 insertions(+), 3 deletions(-)
@@ -794,10 +831,15 @@ static int register_cpu_online(unsigned int cpu)if(!firmware_has_feature(FW_FEATURE_LPAR))add_write_permission_dev_attr(&dev_attr_purr);device_create_file(s,&dev_attr_purr);+if(firmware_has_feature(FW_FEATURE_LPAR))+device_create_file(s,&dev_attr_idle_purr);}-if(cpu_has_feature(CPU_FTR_SPURR))+if(cpu_has_feature(CPU_FTR_SPURR)){device_create_file(s,&dev_attr_spurr);+if(firmware_has_feature(FW_FEATURE_LPAR))+device_create_file(s,&dev_attr_idle_spurr);+}if(cpu_has_feature(CPU_FTR_DSCR))device_create_file(s,&dev_attr_dscr);
@@ -879,11 +921,17 @@ static int unregister_cpu_online(unsigned int cpu)if(cpu_has_feature(CPU_FTR_MMCRA))device_remove_file(s,&dev_attr_mmcra);-if(cpu_has_feature(CPU_FTR_PURR))+if(cpu_has_feature(CPU_FTR_PURR)){device_remove_file(s,&dev_attr_purr);+if(firmware_has_feature(FW_FEATURE_LPAR))+device_remove_file(s,&dev_attr_idle_purr);+}-if(cpu_has_feature(CPU_FTR_SPURR))+if(cpu_has_feature(CPU_FTR_SPURR)){device_remove_file(s,&dev_attr_spurr);+if(firmware_has_feature(FW_FEATURE_LPAR))+device_remove_file(s,&dev_attr_idle_spurr);+}if(cpu_has_feature(CPU_FTR_DSCR))device_remove_file(s,&dev_attr_dscr);
From: Gautham R. Shenoy <hidden> Date: 2020-02-21 05:19:12
From: "Gautham R. Shenoy" <redacted>
Currently when CPU goes idle, we take a snapshot of PURR via
idle_loop_prolog() which is used at the CPU idle exit to compute the
idle PURR cycles via the function idle_loop_epilog(). Thus, the value
of idle PURR cycle thus read before idle_loop_prolog() and after
idle_loop_epilog() is always correct.
However, if we were to read the idle PURR cycles from an interrupt
context between idle_loop_prolog() and idle_loop_epilog() (this will
be done in a future patch), then, the value of the idle PURR thus read
will not include the cycles spent in the most recent idle period.
This patch addresses the issue by providing accessor function to read
the idle PURR such such that it includes the cycles spent in the most
recent idle period, if we read it between idle_loop_prolog() and
idle_loop_epilog(). In order to achieve it, the patch saves the
snapshot of PURR in idle_loop_prolog() in a per-cpu variable, instead
of on the stack, so that it can be accessed from an interrupt context.
Signed-off-by: Gautham R. Shenoy <redacted>
---
arch/powerpc/include/asm/idle.h | 46 +++++++++++++++++++++++++++-------
arch/powerpc/platforms/pseries/setup.c | 7 +++---
drivers/cpuidle/cpuidle-pseries.c | 15 +++++------
3 files changed, 46 insertions(+), 22 deletions(-)
@@ -318,10 +318,9 @@ static int alloc_dispatch_log_kmem_cache(void)}machine_early_initcall(pseries,alloc_dispatch_log_kmem_cache);+DEFINE_PER_CPU(u64,idle_entry_purr_snap);staticvoidpseries_lpar_idle(void){-unsignedlongin_purr;-/**Defaulthandlertogointolowthreadpriorityandpossibly*lowpowermodebycedingprocessortohypervisor
@@ -331,7 +330,7 @@ static void pseries_lpar_idle(void)return;/* Indicate to hypervisor that we are idle. */-idle_loop_prolog(&in_purr);+idle_loop_prolog();/**Yieldtheprocessortothehypervisor.Wereturnif
From: Gautham R. Shenoy <hidden> Date: 2020-02-21 05:19:14
From: "Gautham R. Shenoy" <redacted>
On Pseries LPARs, to calculate utilization, we need to know the
[S]PURR ticks when the CPUs were busy or idle.
Via idle_loop_prolog(), idle_loop_epilog(), we track the idle PURR
ticks in the VPA variable "wait_state_cycles". This patch extends the
support to account for the idle SPURR ticks. It also provides an
accessor function to accurately reads idle SPURR ticks.
Signed-off-by: Gautham R. Shenoy <redacted>
---
arch/powerpc/include/asm/idle.h | 33 +++++++++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/setup.c | 2 ++
2 files changed, 35 insertions(+)
From: "Gautham R. Shenoy" <redacted>
Currently prior to entering an idle state on a Linux Guest, the
pseries cpuidle driver implement an idle_loop_prolog() and
idle_loop_epilog() functions which ensure that idle_purr is correctly
computed, and the hypervisor is informed that the CPU cycles have been
donated.
These prolog and epilog functions are also required in the default
idle call, i.e pseries_lpar_idle(). Hence move these accessor
functions to a common header file and call them from
pseries_lpar_idle(). Since the existing header files such as
asm/processor.h have enough clutter, create a new header file
asm/idle.h.
Signed-off-by: Gautham R. Shenoy <redacted>
---
arch/powerpc/include/asm/idle.h | 27 +++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/setup.c | 7 +++++--
drivers/cpuidle/cpuidle-pseries.c | 24 +-----------------------
3 files changed, 33 insertions(+), 25 deletions(-)
create mode 100644 arch/powerpc/include/asm/idle.h
Looks fine and correct as a cleanup, but asm/include/idle.h and
idle_loop_prolog, idle_loop_epilog, strike me as too generic for
pseries-specific code.
+static inline u64 read_this_idle_spurr(void)
+{
+ /*
+ * If we are reading from an idle context, update the
+ * idle-spurr cycles corresponding to the last idle period.
+ * Since the idle context is not yet over, take a fresh
+ * snapshot of the idle-spurr.
+ */
+ if (get_lppaca()->idle == 1) {
+ update_idle_spurr_accounting();
+ snapshot_spurr_idle_entry();
This samples spurr twice when it could do with just one. I don't know
the performance implications, but will the results be coherent?
It's regrettable that we have to wake up potentially idle CPUs in order
to derive correct idle statistics for them, but I suppose the main user
(lparstat) of these interfaces already is causing this to happen by
polling the existing per-cpu purr and spurr attributes.
So now lparstat will incur at minimum four syscalls and four IPIs per
CPU per polling interval -- one for each of purr, spurr, idle_purr and
idle_spurr. Correct?
At some point it's going to make sense to batch sampling of remote CPUs'
SPRs.
quoted hunk
static int register_cpu_online(unsigned int cpu)
{
struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -794,10 +831,15 @@ static int register_cpu_online(unsigned int cpu) if (!firmware_has_feature(FW_FEATURE_LPAR)) add_write_permission_dev_attr(&dev_attr_purr); device_create_file(s, &dev_attr_purr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_create_file(s, &dev_attr_idle_purr); }- if (cpu_has_feature(CPU_FTR_SPURR))+ if (cpu_has_feature(CPU_FTR_SPURR)) { device_create_file(s, &dev_attr_spurr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_create_file(s, &dev_attr_idle_spurr);+ } if (cpu_has_feature(CPU_FTR_DSCR)) device_create_file(s, &dev_attr_dscr);
@@ -879,11 +921,17 @@ static int unregister_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_MMCRA)) device_remove_file(s, &dev_attr_mmcra);- if (cpu_has_feature(CPU_FTR_PURR))+ if (cpu_has_feature(CPU_FTR_PURR)) { device_remove_file(s, &dev_attr_purr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_remove_file(s, &dev_attr_idle_purr);+ }- if (cpu_has_feature(CPU_FTR_SPURR))+ if (cpu_has_feature(CPU_FTR_SPURR)) { device_remove_file(s, &dev_attr_spurr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_remove_file(s, &dev_attr_idle_spurr);+ } if (cpu_has_feature(CPU_FTR_DSCR)) device_remove_file(s, &dev_attr_dscr);
The cpu register/unregister stuff here looks correct.
@@ -580,3 +580,42 @@ Description: Secure Virtual Machine If 1, it means the system is using the Protected Execution Facility in POWER9 and newer processors. i.e., it is a Secure Virtual Machine.++What: /sys/devices/system/cpu/cpuX/purr+Date: Apr 2005+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: PURR ticks for this CPU since the system boot.++ The Processor Utilization Resources Register (PURR) is+ a 64-bit counter which provides an estimate of the+ resources used by the CPU thread. The contents of this+ register increases monotonically. This sysfs interface+ exposes the number of PURR ticks for cpuX.++What: /sys/devices/system/cpu/cpuX/spurr+Date: Dec 2006+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: SPURR ticks for this CPU since the system boot.++ The Scaled Processor Utilization Resources Register+ (SPURR) is a 64-bit counter that provides a frequency+ invariant estimate of the resources used by the CPU+ thread. The contents of this register increases+ monotonically. This sysfs interface exposes the number+ of SPURR ticks for cpuX.++What: /sys/devices/system/cpu/cpuX/idle_purr+Date: Nov 2019+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: PURR ticks for cpuX when it was idle.++ This sysfs interface exposes the number of PURR ticks+ for cpuX when it was idle.++What: /sys/devices/system/cpu/cpuX/spurr
Copy-paste error? This should be:
/sys/devices/system/cpu/cpuX/idle_spurr
+Date: Nov 2019
And I suppose Nov 2019 is no longer accurate.
+Contact: Linux for PowerPC mailing list [off-list ref]
+Description: SPURR ticks for cpuX when it was idle.
+
+ This sysfs interface exposes the number of SPURR ticks
+ for cpuX when it was idle.
--
1.9.4
From: Gautham R Shenoy <hidden> Date: 2020-02-24 04:55:20
Hello Nathan,
On Fri, Feb 21, 2020 at 09:03:16AM -0600, Nathan Lynch wrote:
"Gautham R. Shenoy" [off-list ref] writes:
quoted
From: "Gautham R. Shenoy" <redacted>
Currently prior to entering an idle state on a Linux Guest, the
pseries cpuidle driver implement an idle_loop_prolog() and
idle_loop_epilog() functions which ensure that idle_purr is correctly
computed, and the hypervisor is informed that the CPU cycles have been
donated.
These prolog and epilog functions are also required in the default
idle call, i.e pseries_lpar_idle(). Hence move these accessor
functions to a common header file and call them from
pseries_lpar_idle(). Since the existing header files such as
asm/processor.h have enough clutter, create a new header file
asm/idle.h.
Signed-off-by: Gautham R. Shenoy <redacted>
---
arch/powerpc/include/asm/idle.h | 27 +++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/setup.c | 7 +++++--
drivers/cpuidle/cpuidle-pseries.c | 24 +-----------------------
3 files changed, 33 insertions(+), 25 deletions(-)
create mode 100644 arch/powerpc/include/asm/idle.h
Looks fine and correct as a cleanup, but asm/include/idle.h and
idle_loop_prolog, idle_loop_epilog, strike me as too generic for
pseries-specific code.
Should it be prefixed with pseries , i.e pseries_idle_prolog()
and pseries_idle_epilog() ?
Also, I am planning another round of cleanup to move all the
idle-related declaration from asm/include/processor.h to
asm/include/idle.h
+static inline u64 read_this_idle_spurr(void)
+{
+ /*
+ * If we are reading from an idle context, update the
+ * idle-spurr cycles corresponding to the last idle period.
+ * Since the idle context is not yet over, take a fresh
+ * snapshot of the idle-spurr.
+ */
+ if (get_lppaca()->idle == 1) {
+ update_idle_spurr_accounting();
+ snapshot_spurr_idle_entry();
This samples spurr twice when it could do with just one. I don't know
the performance implications, but will the results be coherent?
We would have taken the snapshot in idle_loop_prolog() just before
entering idle. That fact that the "if" condition is true above in
read_this_idle_spurr() implies that we are reading the idle_spurr
value from an interrupt context and since get_lppaca()->idle == 1, we
haven't yet called idle_loop_epilog(), where we would have updated the
idle_spurr ticks for the last idle period.
Hence, in this function, we first update the idle_spurr accounting
from the time of the last snapshot to now. We update the snapshot to
the current SPURR value so that when we eventually call
idle_loop_epilog(), we will account for the remaining idle duration,
i.e from the read_this_idle_spurr() call to idle_loop_epilog()
The results are therefore coherant, in that we do not perform double
accounting the second time we invoke update_idle_spurr_accounting()
from idle_loop_epilog(), but only add the spurr ticks from
read_this_idle_spurr() to idle_loop_epilog().
--
Thanks and Regards
gautham.
It's regrettable that we have to wake up potentially idle CPUs in order
to derive correct idle statistics for them, but I suppose the main user
(lparstat) of these interfaces already is causing this to happen by
polling the existing per-cpu purr and spurr attributes.
So now lparstat will incur at minimum four syscalls and four IPIs per
CPU per polling interval -- one for each of purr, spurr, idle_purr and
idle_spurr. Correct?
Yes, it is unforunate that we will end up making four syscalls and
generating IPI noise, and this is something that I discussed with
Naveen and Kamalesh. We have the following two constraints:
1) These values of PURR and SPURR required are per-cpu. Hence putting
them in lparcfg is not an option.
2) sysfs semantics encourages a single value per key, the key being
the sysfs-file. Something like the following would have made far more
sense.
cat /sys/devices/system/cpu/cpuX/purr_spurr_accounting
purr:A
idle_purr:B
spurr:C
idle_spurr:D
There are some sysfs files which allow something like this. Eg:
/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
Thoughts on any other alternatives?
At some point it's going to make sense to batch sampling of remote CPUs'
SPRs.
quoted
static int register_cpu_online(unsigned int cpu)
{
struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -794,10 +831,15 @@ static int register_cpu_online(unsigned int cpu) if (!firmware_has_feature(FW_FEATURE_LPAR)) add_write_permission_dev_attr(&dev_attr_purr); device_create_file(s, &dev_attr_purr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_create_file(s, &dev_attr_idle_purr); }- if (cpu_has_feature(CPU_FTR_SPURR))+ if (cpu_has_feature(CPU_FTR_SPURR)) { device_create_file(s, &dev_attr_spurr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_create_file(s, &dev_attr_idle_spurr);+ } if (cpu_has_feature(CPU_FTR_DSCR)) device_create_file(s, &dev_attr_dscr);
@@ -879,11 +921,17 @@ static int unregister_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_MMCRA)) device_remove_file(s, &dev_attr_mmcra);- if (cpu_has_feature(CPU_FTR_PURR))+ if (cpu_has_feature(CPU_FTR_PURR)) { device_remove_file(s, &dev_attr_purr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_remove_file(s, &dev_attr_idle_purr);+ }- if (cpu_has_feature(CPU_FTR_SPURR))+ if (cpu_has_feature(CPU_FTR_SPURR)) { device_remove_file(s, &dev_attr_spurr);+ if (firmware_has_feature(FW_FEATURE_LPAR))+ device_remove_file(s, &dev_attr_idle_spurr);+ } if (cpu_has_feature(CPU_FTR_DSCR)) device_remove_file(s, &dev_attr_dscr);
The cpu register/unregister stuff here looks correct.
Thanks for reviewing the patch.
--
Thanks and Regards
gautham.
@@ -580,3 +580,42 @@ Description: Secure Virtual Machine If 1, it means the system is using the Protected Execution Facility in POWER9 and newer processors. i.e., it is a Secure Virtual Machine.++What: /sys/devices/system/cpu/cpuX/purr+Date: Apr 2005+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: PURR ticks for this CPU since the system boot.++ The Processor Utilization Resources Register (PURR) is+ a 64-bit counter which provides an estimate of the+ resources used by the CPU thread. The contents of this+ register increases monotonically. This sysfs interface+ exposes the number of PURR ticks for cpuX.++What: /sys/devices/system/cpu/cpuX/spurr+Date: Dec 2006+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: SPURR ticks for this CPU since the system boot.++ The Scaled Processor Utilization Resources Register+ (SPURR) is a 64-bit counter that provides a frequency+ invariant estimate of the resources used by the CPU+ thread. The contents of this register increases+ monotonically. This sysfs interface exposes the number+ of SPURR ticks for cpuX.++What: /sys/devices/system/cpu/cpuX/idle_purr+Date: Nov 2019+Contact: Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>+Description: PURR ticks for cpuX when it was idle.++ This sysfs interface exposes the number of PURR ticks+ for cpuX when it was idle.++What: /sys/devices/system/cpu/cpuX/spurr
Copy-paste error? This should be:
Yes, this should have been idle_spurr. Will fix it in the next
version.
/sys/devices/system/cpu/cpuX/idle_spurr
quoted
+Date: Nov 2019
And I suppose Nov 2019 is no longer accurate.
My bad. I will resend this with the updated date.
quoted
+Contact: Linux for PowerPC mailing list [off-list ref]
+Description: SPURR ticks for cpuX when it was idle.
+
+ This sysfs interface exposes the number of SPURR ticks
+ for cpuX when it was idle.
--
1.9.4
It's regrettable that we have to wake up potentially idle CPUs in order
to derive correct idle statistics for them, but I suppose the main user
(lparstat) of these interfaces already is causing this to happen by
polling the existing per-cpu purr and spurr attributes.
So now lparstat will incur at minimum four syscalls and four IPIs per
CPU per polling interval -- one for each of purr, spurr, idle_purr and
idle_spurr. Correct?
Yes, it is unforunate that we will end up making four syscalls and
generating IPI noise, and this is something that I discussed with
Naveen and Kamalesh. We have the following two constraints:
1) These values of PURR and SPURR required are per-cpu. Hence putting
them in lparcfg is not an option.
2) sysfs semantics encourages a single value per key, the key being
the sysfs-file. Something like the following would have made far more
sense.
cat /sys/devices/system/cpu/cpuX/purr_spurr_accounting
purr:A
idle_purr:B
spurr:C
idle_spurr:D
There are some sysfs files which allow something like this. Eg:
/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
Thoughts on any other alternatives?
Umm... procfs?
/me ducks
quoted
At some point it's going to make sense to batch sampling of remote CPUs'
SPRs.
How did you mean this? It looks like we first need to provide a separate
user interface, since with the existing sysfs interface providing
separate files, I am not sure if we can batch such reads.
- Naveen
On Fri, Feb 21, 2020 at 10:50:12AM -0600, Nathan Lynch wrote:
quoted
It's regrettable that we have to wake up potentially idle CPUs in order
to derive correct idle statistics for them, but I suppose the main user
(lparstat) of these interfaces already is causing this to happen by
polling the existing per-cpu purr and spurr attributes.
So now lparstat will incur at minimum four syscalls and four IPIs per
CPU per polling interval -- one for each of purr, spurr, idle_purr and
idle_spurr. Correct?
Yes, it is unforunate that we will end up making four syscalls and
generating IPI noise, and this is something that I discussed with
Naveen and Kamalesh. We have the following two constraints:
1) These values of PURR and SPURR required are per-cpu. Hence putting
them in lparcfg is not an option.
2) sysfs semantics encourages a single value per key, the key being
the sysfs-file. Something like the following would have made far more
sense.
cat /sys/devices/system/cpu/cpuX/purr_spurr_accounting
purr:A
idle_purr:B
spurr:C
idle_spurr:D
There are some sysfs files which allow something like this. Eg:
/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
Thoughts on any other alternatives?
Umm... procfs?
/me ducks
I had wondered about perf events but I'm not sure that's any more suitable.
quoted
quoted
At some point it's going to make sense to batch sampling of remote CPUs'
SPRs.
How did you mean this? It looks like we first need to provide a separate
user interface, since with the existing sysfs interface providing
separate files, I am not sure if we can batch such reads.
I mean in order to minimize IPI traffic something like: sample/calculate
all of a CPU's purr, idle_purr, spurr, idle_spurr in a single IPI upon a
read of any of the attributes, and cache the result for some time, so
that the anticipated subsequent reads of the other attributes use the
cached results instead of generating more IPIs.
That would keep the current sysfs interface at the cost of imposing a
certain coarseness in the results.
Anyway, that's a mitigation that could be considered if the
implementation in this patch is found to be too expensive in practice.
On Fri, Feb 21, 2020 at 09:03:16AM -0600, Nathan Lynch wrote:
quoted
Looks fine and correct as a cleanup, but asm/include/idle.h and
idle_loop_prolog, idle_loop_epilog, strike me as too generic for
pseries-specific code.
Should it be prefixed with pseries , i.e pseries_idle_prolog()
and pseries_idle_epilog() ?
From: Naveen N. Rao <hidden> Date: 2020-03-06 17:39:35
Nathan Lynch wrote:
"Naveen N. Rao" [off-list ref] writes:
quoted
Gautham R Shenoy wrote:
quoted
On Fri, Feb 21, 2020 at 10:50:12AM -0600, Nathan Lynch wrote:
quoted
It's regrettable that we have to wake up potentially idle CPUs in order
to derive correct idle statistics for them, but I suppose the main user
(lparstat) of these interfaces already is causing this to happen by
polling the existing per-cpu purr and spurr attributes.
So now lparstat will incur at minimum four syscalls and four IPIs per
CPU per polling interval -- one for each of purr, spurr, idle_purr and
idle_spurr. Correct?
Yes, it is unforunate that we will end up making four syscalls and
generating IPI noise, and this is something that I discussed with
Naveen and Kamalesh. We have the following two constraints:
1) These values of PURR and SPURR required are per-cpu. Hence putting
them in lparcfg is not an option.
2) sysfs semantics encourages a single value per key, the key being
the sysfs-file. Something like the following would have made far more
sense.
cat /sys/devices/system/cpu/cpuX/purr_spurr_accounting
purr:A
idle_purr:B
spurr:C
idle_spurr:D
There are some sysfs files which allow something like this. Eg:
/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state
Thoughts on any other alternatives?
Umm... procfs?
/me ducks
I had wondered about perf events but I'm not sure that's any more suitable.
Yes, we considered that, but it looks like the event reads are not
"batched" in any manner. So, the IPI overhead will be similar.
quoted
quoted
quoted
At some point it's going to make sense to batch sampling of remote CPUs'
SPRs.
How did you mean this? It looks like we first need to provide a separate
user interface, since with the existing sysfs interface providing
separate files, I am not sure if we can batch such reads.
I mean in order to minimize IPI traffic something like: sample/calculate
all of a CPU's purr, idle_purr, spurr, idle_spurr in a single IPI upon a
read of any of the attributes, and cache the result for some time, so
that the anticipated subsequent reads of the other attributes use the
cached results instead of generating more IPIs.
That would keep the current sysfs interface at the cost of imposing a
certain coarseness in the results.
Thanks for clarifying, that makes sense. Though we need to be careful in
ensuring the sysfs semantics work as expected.
Anyway, that's a mitigation that could be considered if the
implementation in this patch is found to be too expensive in practice.
That's a good point. We can optimize later if this turns out to be a
problem in practice, if we end up using this approach.
- Naveen