"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 | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/src/lparstat.c b/src/lparstat.c
index 612ffd0..b56fe6d 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,7 +436,7 @@ 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;
+ long long new_app, old_app;
char *descr, uptime[32];
se = get_sysentry("time");
@@ -450,8 +450,7 @@ void get_cpu_app(struct sysentry *unused_se, char *buf)
}
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");
--
2.39.3