Skip to content

Commit

Permalink
lparstat: Use CLOCK_BOOTTIME for get_time interface and Deprecate get…
Browse files Browse the repository at this point in the history
…_sys_upttime

"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 <[email protected]>
Signed-off-by: Tyrel Datwyler <[email protected]>
  • Loading branch information
Shrikanth Hegde authored and tyreld committed Jul 26, 2024
1 parent 81c51b5 commit 9572f8c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 53 deletions.
57 changes: 10 additions & 47 deletions src/lparstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 "???"
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -304,39 +308,13 @@ 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);

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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 0 additions & 6 deletions src/lparstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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",
Expand Down

0 comments on commit 9572f8c

Please sign in to comment.