[PATCH v2 0/3] lparstat: Fixes for since boot reports

36 views
Skip to first unread message

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
Apr 12, 2024, 5:46:32 AMApr 12
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com
Currently when no options are specifies in lparstat, it is expected to
give the reports since LPAR boot. It shows wrong values of physc, APP,
purr and idle_purr utilization.


To fix the APP(Available Processor Pool), use the boot pool idle time
exported in lparcfg. This is a new field. More details are in PATCH 1/3.
PATCH 1/3 depends on *powerpc/pseries: Add pool idle time at LPAR boot*
to be in the kernel[1]

Patch 2/3 changes how time calculations are done. Instead of using
gettimeofday, it uses the /proc/uptime. It is correct interface to use
for accurate boot reports. It works for interval related reports as
well. Kepts this patch so it is easier to follow. This would be replaced
by PATCH 3/3.

Nathan Suggested to use CLOCK_BOOTTIME instead of parsing /proc/uptime.
That works fine and it simplifies the code. PATCH 3/3 does that.


PATCH 2/3 and PATCH 3/3 are independent of any kernel change.


v1 -> v2:
- Nathan pointed out to use CLOKC_BOOTTIME instead. Did that.

v1: https://groups.google.com/g/powerpc-utils-devel/c/WZFxrm2aCzU
[1]: https://lore.kernel.org/all/20240412092047....@linux.ibm.com/

Shrikanth Hegde (3):
lparstat: app: Use pic value at boot for accurate boot time reporting
lparstat: Use /proc/uptime instead for get_time()
lparstat: Use CLOCK_BOOTTIME instead of /proc/uptime

src/lparstat.c | 60 ++++++++++----------------------------------------
src/lparstat.h | 8 ++-----
2 files changed, 14 insertions(+), 54 deletions(-)

--
2.39.3

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
Apr 12, 2024, 5:46:35 AMApr 12
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com
When there are no options specified for lparstat, it is expected to
give reports since LPAR(Logical Partition) boot. APP(Available Physical
Processors) is an indicator for available cores in an Shared Processor
LPAR(SPLPAR). APP is derived using pool_idle_time which is obtained
using H_PIC call.

The interval based reports show correct APP value while since boot
report shows very high APP values. This happens because in that case APP
is obtained by dividing pool idle time by LPAR uptime. Since pool idle
time is reported by the PowerVM hypervisor since its boot, it need not
align with LPAR boot.

To fix that use the boot pool idle time added newly in the lparcfg as
below.

APP = (pool idle time - boot pool idle time) / (uptime * timebase)

*This depends on "powerpc/pseries: Add pool idle time at LPAR boot" be
merged into kernel*

Results: (Observe APP values)
========================================================================
lparstat
System Configuration
type=Shared mode=Uncapped smt=8 lcpu=12 mem=15573440 kB cpus=37 ent=12.00

reboot
stress-ng --cpu=$(nproc) -t 600
sleep 600
So in this case app is expected to close to 37-6=31.

====== 6.9-rc1 and lparstat 1.3.10 =============
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 0.00 0.00 47.49 69099.72 541547 21

=== With this patch and this patch to do the above equation ===
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 5.73 47.75 47.49 31.21 541753 21

Signed-off-by: Shrikanth Hegde <ssh...@linux.ibm.com>
---
src/lparstat.c | 3 ++-
src/lparstat.h | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/lparstat.c b/src/lparstat.c
index d2fdb3f..612ffd0 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -460,7 +460,8 @@ void get_cpu_app(struct sysentry *unused_se, char *buf)
se = get_sysentry("pool_idle_time");
new_app = strtoll(se->value, NULL, 0);
if (se->old_value[0] == '\0') {
- old_app = 0;
+ se = get_sysentry("boot_pool_idle_time");
+ old_app = strtoll(se->value, NULL, 0);
} else {
old_app = strtoll(se->old_value, NULL, 0);
}
diff --git a/src/lparstat.h b/src/lparstat.h
index b7c88e9..77203e1 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h
@@ -124,6 +124,8 @@ struct sysentry system_data[] = {
.get = &get_percent_entry},
{.name = "pool_idle_time",
.descr = "Shared Processor Pool Idle Time"},
+ {.name = "boot_pool_idle_time",
+ .descr = "Shared Processor Pool Idle Time"},
{.name = "pool_num_procs",
.descr = "Shared Processor Pool Processors"},
{.name = "unallocated_capacity_weight",
--
2.39.3

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
Apr 12, 2024, 5:46:42 AMApr 12
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com
CLOCK_BOOTTIME exports the same information as parsing /proc/uptime and
it simplifies the code as well. So use that instead to get the "time" in
lparstat.

Remove "uptime" in lparstat since its not needed anymore. "time"
essentially is the system uptime now.

Signed-off-by: Shrikanth Hegde <ssh...@linux.ibm.com>
---
src/lparstat.c | 35 ++++++-----------------------------
src/lparstat.h | 6 ------
2 files changed, 6 insertions(+), 35 deletions(-)

diff --git a/src/lparstat.c b/src/lparstat.c
index 9d651da..3f93b37 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -36,6 +36,7 @@
#include "lparstat.h"
#include "pseries_platform.h"
#include "cpu_info_helpers.h"
+#include <time.h>

#define LPARCFG_FILE "/proc/ppc64/lparcfg"
#define SE_NOT_FOUND "???"
@@ -255,16 +256,17 @@ long long get_delta_value(char *se_name)

void get_time()
{
- char *descr, uptime[32];
struct sysentry *se;
+ struct timespec ts;
+ int err;

- get_sysdata("uptime", &descr, uptime);
- if (!strcmp(uptime, SE_NOT_VALID))
+ err = clock_gettime(CLOCK_BOOTTIME, &ts);
+ if (err)
return;

se = get_sysentry("time");
sprintf(se->value, "%lld",
- (long long)atof(uptime));
+ (long long)ts.tv_sec);
}

int get_time_base()
@@ -313,31 +315,6 @@ double get_scaled_tb(void)
return (timebase * elapsed) * online_cores;
}

-void get_sys_uptime(struct sysentry *unused_se, char *uptime)
-{
- FILE *f;
- char buf[80];
-
- f = fopen("/proc/uptime", "r");
- if (!f) {
- fprintf(stderr, "Could not open /proc/uptime\n");
- sprintf(uptime, SE_NOT_VALID);
- return;
- }
-
- if ((fgets(buf, 80, f)) != NULL) {
- char *value;
-
- value = strchr(buf, ' ');
- *value = '\0';
- sprintf(uptime, "%s", buf);
- } else {
- sprintf(uptime, SE_NOT_VALID);
- }
-
- fclose(f);
-}
-
int get_nominal_frequency(void)
{
FILE *f;
diff --git a/src/lparstat.h b/src/lparstat.h
index 77203e1..86e45e4 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h
@@ -60,7 +60,6 @@ extern void get_cpu_stat(struct sysentry *, char *);
extern void get_cpu_physc(struct sysentry *, char *);
extern void get_per_entc(struct sysentry *, char *);
extern void get_cpu_app(struct sysentry *, char *);
-extern void get_sys_uptime(struct sysentry *, char *);
extern void get_cpu_util_purr(struct sysentry *unused_se, char *buf);
extern void get_cpu_idle_purr(struct sysentry *unused_se, char *buf);
extern void get_cpu_util_spurr(struct sysentry *unused_se, char *buf);
@@ -272,11 +271,6 @@ struct sysentry system_data[] = {
{.name = "phint",
.descr = "Phantom Interrupts"},

- /* /proc/uptime */
- {.name = "uptime",
- .descr = "System Uptime",
- .get = &get_sys_uptime},
-
/* /sys/devices/system/cpu/cpu<n>/ */
/* Sum of per CPU SPURR registers */
{.name = "spurr",
--
2.39.3

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
Apr 12, 2024, 5:48:32 AMApr 12
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com
"time" is used in lparstat.c to find the time elapsed either since boot
or between two intervals. But it is using gettimeofday which returns the
time elapsed since Epoch. This works for intervals calculations but it
doesn't work for since boot reports.

Instead use the /proc/uptime interface to get the elapsed time. This
fixes physc, utilization based on purr being wrong since boot

Test::
reboot
stress-ng --cpu=$(nproc) -t 600
sleep 600

Results::
==================== Shared LPAR ==================================
System Configuration
type=Shared mode=Uncapped smt=8 lcpu=12 mem=15573440 kB cpus=37 ent=12.00

lparstat -E <-- Observe utilization values
====== 6.9-rc1 and lparstat 1.3.10 =============
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
0.00 0.00 3.87GHz[106%] 0.00 0.00

==== With this patch and patch 2/3 =============
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
38.72 0.11 3.87GHz[106%] 41.04 0.12

lparstat <-- Observe physc values
====== 6.9-rc1 and lparstat 1.3.10 ===================================
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 0.00 0.00 47.49 69099.72 541547 21

=== With this patch and this patch ================================ ===
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 5.73 47.75 47.49 31.21 541753 21

==================== Dedicated LPAR ==================================
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=12 mem=15573248 kB cpus=0 ent=12.00

::lparstat -E:: <-- Observe utilization values.
======= 6.9-rc1 and lparstat 1.3.10 =============
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
0.00 0.00 3.87GHz[106%] 0.00 0.00

=== With this patch and powerpc-utils patch to do the above equation ===
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
48.87 51.51 3.87GHz[106%] 51.81 54.60

::lparstat:: <-- Observe physc values.
======= 6.9-rc1 and lparstat 1.3.10 =============
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
48.38 0.01 0.00 51.61 0.03 0.25 48.39 0.00 344661 8

=== With this patch and powerpc-utils patch to do the above equation ===
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
48.38 0.01 0.00 51.61 12.05 100.42 48.39 0.00 344877 8

=============================================================================

Interval based lparstat values are same. With this patch the physc and
busy purr/idle purr values show correctly for since boot reports.

Note: this patch doesn't fix the idle purr being incorrect. That is
currently being investigated.

Signed-off-by: Shrikanth Hegde <ssh...@linux.ibm.com>
---
src/lparstat.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)

diff --git a/src/lparstat.c b/src/lparstat.c
index 612ffd0..9d651da 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -255,14 +255,16 @@ long long get_delta_value(char *se_name)

void get_time()
{
- struct timeval t;
+ char *descr, uptime[32];
struct sysentry *se;

- gettimeofday(&t, 0);
+ get_sysdata("uptime", &descr, uptime);
+ if (!strcmp(uptime, SE_NOT_VALID))
+ return;

se = get_sysentry("time");
sprintf(se->value, "%lld",
- (long long)t.tv_sec * 1000000LL + (long long)t.tv_usec);
+ (long long)atof(uptime));
}

int get_time_base()
@@ -304,7 +306,6 @@ double get_scaled_tb(void)
online_cores = atoi(se->value);

elapsed = get_delta_value("time");
- elapsed = elapsed / 1000000.0;

se = get_sysentry("timebase");
timebase = atoi(se->value);
@@ -403,13 +404,12 @@ void get_cpu_physc(struct sysentry *unused_se, char *buf)
delta_purr = get_delta_value("purr");

se = get_sysentry("tbr");
- if (se->value[0] != '\0') {
+ if (se->old_value[0] != '\0') {
delta_tb = get_delta_value("tbr");

physc = delta_purr / delta_tb;
} else {
elapsed = get_delta_value("time");
- elapsed = elapsed / 1000000.0;

se = get_sysentry("timebase");
timebase = atoi(se->value);
@@ -436,23 +436,9 @@ void get_cpu_app(struct sysentry *unused_se, char *buf)
{
struct sysentry *se;
float timebase, app, elapsed_time;
- long long new_app, old_app, delta_time;
- char *descr, uptime[32];
-
- se = get_sysentry("time");
- if (se->old_value[0] == '\0') {
- /* Single report since boot */
- get_sysdata("uptime", &descr, uptime);
+ long long new_app, old_app;

- if (!strcmp(uptime, SE_NOT_VALID)) {
- sprintf(buf, "-");
- return;
- }
- elapsed_time = atof(uptime);
- } else {
- delta_time = get_delta_value("time");
- elapsed_time = delta_time / 1000000.0;
- }
+ elapsed_time = get_delta_value("time");

se = get_sysentry("timebase");
timebase = atof(se->value);
--
2.39.3

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
May 5, 2024, 10:50:52 AMMay 5
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com


On 4/12/24 3:16 PM, Shrikanth Hegde wrote:
> Currently when no options are specifies in lparstat, it is expected to
> give the reports since LPAR boot. It shows wrong values of physc, APP,
> purr and idle_purr utilization.
>
>

Hi Tyrel,Nathan,
Any comments on these patches?

Given that kernel part is queued for powerpc/next, can we have these patches in lparstat
if there is no objection?
https://lore.kernel.org/all/171473286291.451432.53...@ellerman.id.au/


Tyrel Datwyler

<tyreld@linux.ibm.com>
unread,
May 13, 2024, 5:32:23 PMMay 13
to Shrikanth Hegde, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com
I'm not really a fan of modifying get_time() in the previous patch to use
uptime, and then turning around and switching it to use CLOCK_BOOTTIME in the
next patch. I would prefer just doing that all in one go as this seems like
unnecessary churn.

I think the remainder is ok as a standalone patch with a commit message and a
log documenting that we are removing get_sys_uptime as there are no users in the
code base.

-Tyrel

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
May 14, 2024, 10:36:15 AMMay 14
to Tyrel Datwyler, powerpc-utils-devel@googlegroups.com, nathanl@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, mahesh@linux.ibm.com
Alright, we can squash Patch 2/3. I kept it for easier understanding.

>
> I think the remainder is ok as a standalone patch with a commit message and a
> log documenting that we are removing get_sys_uptime as there are no users in the
> code base.
>

Let me send v3 with only two commits.

1/2. lparstat: app: Use pic value at boot for accurate boot time reporting
2/2. lparstat: Use CLOCK_BOOTTIME for get_time interface and Deprecate get_sys_upttime

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
May 14, 2024, 11:17:08 AMMay 14
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, nathanl@linux.ibm.com
Currently when no options are specifies in lparstat, it is expected to
give the reports since LPAR boot. It shows wrong values of physc, APP,
purr and idle_purr utilization.


To fix the APP(Available Processor Pool), use the boot pool idle time
exported in lparcfg. This is a new field. More details are in PATCH 1/2.
PATCH 1/2 depends on *powerpc/pseries: Add pool idle time at LPAR boot*
to be in the kernel[1]. It is currently part of powerpc/next tree.

Patch 2/2 changes how time calculations are done. Instead of using
gettimeofday, it uses CLOCK_BOOTTIME. It is correct interface to use
for accurate boot reports. It works for interval related reports as
well. This patch is independent of any kernel change.

v2 -> v3:
- Tyrel suggested we drop intermediary patch involving /proc/uptime.
Removed that patch.

v1 -> v2:
- Nathan pointed out to use CLOKC_BOOTTIME instead. Did that.

v1: https://groups.google.com/g/powerpc-utils-devel/c/WZFxrm2aCzU
v2: https://groups.google.com/g/powerpc-utils-devel/c/0W6BAWquhcg
[1]: https://lore.kernel.org/all/20240412092047....@linux.ibm.com/


Shrikanth Hegde (2):
lparstat: app: Use pic value at boot for accurate boot time reporting
lparstat: Use CLOCK_BOOTTIME for get_time interface and Deprecate
get_sys_upttime

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
May 14, 2024, 11:17:10 AMMay 14
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, nathanl@linux.ibm.com
When there are no options specified for lparstat, it is expected to
give reports since LPAR(Logical Partition) boot. APP(Available Physical
Processors) is an indicator for available cores in an Shared Processor
LPAR(SPLPAR). APP is derived using pool_idle_time which is obtained
using H_PIC call.

The interval based reports show correct APP value while since boot
report shows very high APP values. This happens because in that case APP
is obtained by dividing pool idle time by LPAR uptime. Since pool idle
time is reported by the PowerVM hypervisor since its boot, it need not
align with LPAR boot.

To fix that use the boot pool idle time added newly in the lparcfg as
below.

APP = (pool idle time - boot pool idle time) / (uptime * timebase)

*This depends on "powerpc/pseries: Add pool idle time at LPAR boot" be
merged into kernel*

Results: (Observe APP values)
========================================================================
lparstat
System Configuration
type=Shared mode=Uncapped smt=8 lcpu=12 mem=15573440 kB cpus=37 ent=12.00

reboot
stress-ng --cpu=$(nproc) -t 600
sleep 600
So in this case app is expected to close to 37-6=31.

====== 6.9-rc1 and lparstat 1.3.10 =============
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 0.00 0.00 47.49 69099.72 541547 21

=== With this patch and this patch to do the above equation ===
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 5.73 47.75 47.49 31.21 541753 21

Signed-off-by: Shrikanth Hegde <ssh...@linux.ibm.com>
---
src/lparstat.c | 3 ++-
src/lparstat.h | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/lparstat.c b/src/lparstat.c
index d2fdb3f..612ffd0 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -460,7 +460,8 @@ void get_cpu_app(struct sysentry *unused_se, char *buf)
se = get_sysentry("pool_idle_time");
new_app = strtoll(se->value, NULL, 0);
if (se->old_value[0] == '\0') {
- old_app = 0;
+ se = get_sysentry("boot_pool_idle_time");
+ old_app = strtoll(se->value, NULL, 0);
} else {
old_app = strtoll(se->old_value, NULL, 0);
}
diff --git a/src/lparstat.h b/src/lparstat.h
index b7c88e9..77203e1 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h

Shrikanth Hegde

<sshegde@linux.ibm.com>
unread,
May 14, 2024, 11:17:12 AMMay 14
to tyreld@linux.ibm.com, powerpc-utils-devel@googlegroups.com, sshegde@linux.ibm.com, mpe@ellerman.id.au, naveen.n.rao@linux.ibm.com, nathanl@linux.ibm.com
"time" is used in lparstat.c to find the time elapsed either since boot
or between two intervals. But it is using gettimeofday which returns the
time elapsed since Epoch. This works for intervals calculations but it
doesn't work for since boot reports.

Instead use the CLOCK_BOOTTIME interface to get the elapsed time. This
fixes physc, utilization based on purr being wrong since boot.

Remove "uptime" interface since there are no users of it. One can get
the system uptime by calling "time" itself.


=============================== ::Test:: ==========================
reboot
stress-ng --cpu=$(nproc) -t 600
sleep 600

Results::
==================== Shared LPAR ==================================
System Configuration
type=Shared mode=Uncapped smt=8 lcpu=12 mem=15573440 kB cpus=37 ent=12.00

lparstat -E <-- Observe utilization values
====== 6.9-rc1 and lparstat 1.3.10 =============
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
0.00 0.00 3.87GHz[106%] 0.00 0.00

==== With this patch and patch 2/3 =============
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
38.72 0.11 3.87GHz[106%] 41.04 0.12

lparstat <-- Observe physc values
====== 6.9-rc1 and lparstat 1.3.10 ===================================
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 0.00 0.00 47.49 69099.72 541547 21

=== With this patch and this patch ================================ ===
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
47.48 0.01 0.00 52.51 5.73 47.75 47.49 31.21 541753 21

==================== Dedicated LPAR ==================================
System Configuration
type=Dedicated mode=Capped smt=8 lcpu=12 mem=15573248 kB cpus=0 ent=12.00

::lparstat -E:: <-- Observe utilization values.
======= 6.9-rc1 and lparstat 1.3.10 =============
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
0.00 0.00 3.87GHz[106%] 0.00 0.00

=== With this patch and powerpc-utils patch to do the above equation ===
---Actual--- -Normalized-
%busy %idle Frequency %busy %idle
------ ------ ------------- ------ ------
48.87 51.51 3.87GHz[106%] 51.81 54.60

::lparstat:: <-- Observe physc values.
======= 6.9-rc1 and lparstat 1.3.10 =============
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
48.38 0.01 0.00 51.61 0.03 0.25 48.39 0.00 344661 8

=== With this patch and powerpc-utils patch to do the above equation ===
%user %sys %wait %idle physc %entc lbusy app vcsw phint
----- ----- ----- ----- ----- ----- ----- ----- ----- -----
48.38 0.01 0.00 51.61 12.05 100.42 48.39 0.00 344877 8

=============================================================================

Interval based lparstat values are same. With this patch the physc and
busy purr/idle purr values show correctly for since boot reports.

Note: this patch doesn't fix the idle purr being incorrect. That is
currently being investigated.

Signed-off-by: Shrikanth Hegde <ssh...@linux.ibm.com>
---
src/lparstat.c | 57 +++++++++-----------------------------------------
src/lparstat.h | 6 ------
2 files changed, 10 insertions(+), 53 deletions(-)

diff --git a/src/lparstat.c b/src/lparstat.c
index 612ffd0..3f93b37 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -36,6 +36,7 @@
#include "lparstat.h"
#include "pseries_platform.h"
#include "cpu_info_helpers.h"
+#include <time.h>

#define LPARCFG_FILE "/proc/ppc64/lparcfg"
#define SE_NOT_FOUND "???"
@@ -255,14 +256,17 @@ long long get_delta_value(char *se_name)

void get_time()
{
- struct timeval t;
struct sysentry *se;
+ struct timespec ts;
+ int err;

- gettimeofday(&t, 0);
+ err = clock_gettime(CLOCK_BOOTTIME, &ts);
+ if (err)
+ return;

se = get_sysentry("time");
sprintf(se->value, "%lld",
- (long long)t.tv_sec * 1000000LL + (long long)t.tv_usec);
+ (long long)ts.tv_sec);
}

int get_time_base()
@@ -304,7 +308,6 @@ double get_scaled_tb(void)
online_cores = atoi(se->value);

elapsed = get_delta_value("time");
- elapsed = elapsed / 1000000.0;

se = get_sysentry("timebase");
timebase = atoi(se->value);
@@ -312,31 +315,6 @@ double get_scaled_tb(void)
@@ -403,13 +381,12 @@ void get_cpu_physc(struct sysentry *unused_se, char *buf)
delta_purr = get_delta_value("purr");

se = get_sysentry("tbr");
- if (se->value[0] != '\0') {
+ if (se->old_value[0] != '\0') {
delta_tb = get_delta_value("tbr");

physc = delta_purr / delta_tb;
} else {
elapsed = get_delta_value("time");
- elapsed = elapsed / 1000000.0;

se = get_sysentry("timebase");
timebase = atoi(se->value);
@@ -436,23 +413,9 @@ void get_cpu_app(struct sysentry *unused_se, char *buf)
{
struct sysentry *se;
float timebase, app, elapsed_time;
- long long new_app, old_app, delta_time;
- char *descr, uptime[32];
+ long long new_app, old_app;

- se = get_sysentry("time");
- if (se->old_value[0] == '\0') {
- /* Single report since boot */
- get_sysdata("uptime", &descr, uptime);
-
- if (!strcmp(uptime, SE_NOT_VALID)) {
- sprintf(buf, "-");
- return;
- }
- elapsed_time = atof(uptime);
- } else {
- delta_time = get_delta_value("time");
- elapsed_time = delta_time / 1000000.0;
- }
+ elapsed_time = get_delta_value("time");

se = get_sysentry("timebase");
timebase = atof(se->value);
diff --git a/src/lparstat.h b/src/lparstat.h
index 77203e1..86e45e4 100644
--- a/src/lparstat.h
+++ b/src/lparstat.h
Reply all
Reply to author
Forward
0 new messages