Idle and busy PURR/SPURR values are not adding upto 100% in case of
dedicated-donate and shared partitions, with the present formula.
Because of this, users might get a false impression of resource
utilisation. This is expected because a core can be in either
idle or busy state out of total of 100(core's shared resource can
either be consumed or be left idle). When lpar is in dedicated-donate
or shared,the purr values are not being counted when the CPU is ceded.
The idle_purr is calculated by taking snapshots of purr values at
every idle entry and idle exit. So, when a CPU is ceded, the calculation
for idle_purr will be wrong as purr is not being counted.
Before Change:
|-----------------------------------------------------------------|
| Dedicated-donate (8 cores) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.02 | 0.11 | 0.02 | 0.12 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 30.01 | 32.53 | 32.41 | 35.14 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 50.30 | 24.71 | 54.33 | 26.68 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 58.35 | 16.66 | 63.02 | 17.99 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 65.57 | 9.44 | 70.82 | 10.19 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 80.96 | 19.03 | 87.44 | 20.56 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 90.57 | 9.44 | 97.82 | 10.19 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 96.09 | 3.91 | 103.78 | 4.22 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 100.00 | 0.00 | 103.78 | 4.22 |
|----------------------|----------|----------|---------|----------|
|-----------------------------------------------------------------|
| Shared Capped (8 VP / 4 EC) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.04 | 0.18 | 0.03 | 0.19 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 29.94 | 20.05 | 32.33 | 21.65 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 30.26 | 19.65 | 32.36 | 21.04 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 34.77 | 15.11 | 37.55 | 16.31 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 39.31 | 10.57 | 42.03 | 11.33 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 42.83 | 7.04 | 46.25 | 7.60 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 45.56 | 4.36 | 48.72 | 4.69 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 47.73 | 2.12 | 51.07 | 2.27 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 49.89 | 0.00 | 53.88 | 0.00 |
|----------------------|----------|----------|---------|----------|
This commit, rather than considering delta_idle_purr for calculation of
idle ticks, takes (delta_tb - delta_purr) as ticks for which the CPUs
were in CEDE and hence idle. Following similar logic, delta_purr would
represent busy ticks when CPUs were not ceded. Since, the output was
correct for dedicated capped mode, changes has been made only for
shared and dedicated-donate mode.
After Change:
|-----------------------------------------------------------------|
| Dedicated-donate (8 cores) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.09 | 99.91 | 0.09 | 99.45 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 62.55 | 37.45 | 67.55 | 32.81 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 75.01 | 24.99 | 81.01 | 19.35 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 87.50 | 12.50 | 94.50 | 5.86 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 87.51 | 12.49 | 94.51 | 5.86 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 100.00 | 0.00 | 108.00 | 0.00 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 100.00 | 0.00 | 108.00 | 0.00 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 100.00 | 0.00 | 108.00 | 0.00 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 100.00 | 0.00 | 108.00 | 0.00 |
|----------------------|----------|----------|---------|----------|
|-----------------------------------------------------------------|
| Shared Capped (8 VP / 4 EC) : |
|----------------------|---------------------|--------------------|
| | Actual | Normalized |
| Stress-ng threads |---------------------|--------------------|
| | %busy | %idle | %busy | %idle |
|----------------------|----------|----------|---------|----------|
| 0 threads | 0.18 | 99.82 | 0.19 | 99.44 |
|----------------------|----------|----------|---------|----------|
| 8 threads | 49.99 | 50.01 | 53.99 | 45.89 |
|----------------------|----------|----------|---------|----------|
| 16 threads | 49.66 | 50.34 | 53.63 | 46.71 |
|----------------------|----------|----------|---------|----------|
| 24 threads | 49.93 | 50.07 | 53.42 | 46.08 |
|----------------------|----------|----------|---------|----------|
| 32 threads | 49.92 | 50.08 | 53.41 | 46.08 |
|----------------------|----------|----------|---------|----------|
| 40 threads | 49.89 | 50.11 | 53.88 | 46.52 |
|----------------------|----------|----------|---------|----------|
| 48 threads | 49.88 | 50.12 | 53.87 | 46.41 |
|----------------------|----------|----------|---------|----------|
| 56 threads | 49.90 | 50.10 | 53.40 | 46.10 |
|----------------------|----------|----------|---------|----------|
| 64 threads | 49.90 | 50.10 | 54.39 | 45.36 |
|----------------------|----------|----------|---------|----------|
Before Change:
%busy = (delta_purr - delta_idle_purr) / delta_tb * 100
%idle = delta_idle_purr / delta_tb * 100
After Change:
%busy = delta_purr / delta_tb * 100
%idle = (delta_tb - delta_purr) / delta_tb * 100
Signed-off-by: Saket Kumar Bhaskar <
sk...@linux.ibm.com>
---
src/lparstat.c | 83 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 73 insertions(+), 10 deletions(-)
diff --git a/src/lparstat.c b/src/lparstat.c
index d2fdb3f..e74ca17 100644
--- a/src/lparstat.c
+++ b/src/lparstat.c
@@ -491,11 +491,16 @@ void get_cpu_util_purr(struct sysentry *unused_se, char *buf)
{
double delta_tb, delta_purr, delta_idle_purr;
double physc;
+ char *descr;
+ char mode[32];
delta_tb = get_scaled_tb();
delta_purr = get_delta_value("purr");
delta_idle_purr = get_delta_value("idle_purr");
+ get_sysdata("shared_processor_mode", &descr, mode);
+ if (!strcmp(mode, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, mode);
/*
* Given that these values are read from different
* sources (purr from lparcfg and idle_purr from sysfs),
@@ -505,8 +510,15 @@ void get_cpu_util_purr(struct sysentry *unused_se, char *buf)
if (delta_idle_purr > delta_purr)
delta_idle_purr = delta_purr;
- physc = (delta_purr - delta_idle_purr) / delta_tb;
- physc *= 100.00;
+ if (!strcmp(mode, "Capped")) {
+ /* For dedicated - capped mode */
+ physc = (delta_purr - delta_idle_purr) / delta_tb;
+ physc *= 100.00;
+ } else {
+ /* For shared and dedicated - donate mode */
+ physc = delta_purr / delta_tb;
+ physc *= 100.00;
+ }
sprintf(buf, "%.2f", physc);
}
@@ -515,11 +527,17 @@ void get_cpu_idle_purr(struct sysentry *unused_se, char *buf)
{
double delta_tb, delta_purr, delta_idle_purr;
double physc, idle;
+ char *descr;
+ char mode[32];
delta_tb = get_scaled_tb();
delta_purr = get_delta_value("purr");
delta_idle_purr = get_delta_value("idle_purr");
+ get_sysdata("shared_processor_mode", &descr, mode);
+ if (!strcmp(mode, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, mode);
+
/*
* Given that these values are read from different
* sources (purr from lparcfg and idle_purr from sysfs),
@@ -529,9 +547,19 @@ void get_cpu_idle_purr(struct sysentry *unused_se, char *buf)
if (delta_idle_purr > delta_purr)
delta_idle_purr = delta_purr;
- physc = (delta_purr - delta_idle_purr) / delta_tb;
- idle = (delta_purr / delta_tb) - physc;
- idle *= 100.00;
+ if (delta_purr > delta_tb)
+ delta_purr = delta_tb;
+
+ if (!strcmp(mode, "Capped")) {
+ /* For dedicated - capped mode */
+ physc = (delta_purr - delta_idle_purr) / delta_tb;
+ idle = (delta_purr / delta_tb) - physc;
+ idle *= 100.00;
+ } else {
+ /* For shared and dedicated - donate mode */
+ idle = (delta_tb - delta_purr) / delta_tb;
+ idle *= 100.00;
+ }
sprintf(buf, "%.2f", idle);
}
@@ -540,13 +568,29 @@ void get_cpu_util_spurr(struct sysentry *unused_se, char *buf)
{
double delta_tb, delta_spurr, delta_idle_spurr;
double physc, rfreq;
+ char *descr;
+ char mode[32];
delta_tb = get_scaled_tb();
delta_spurr = get_delta_value("spurr");
delta_idle_spurr = get_delta_value("idle_spurr");
- physc = (delta_spurr - delta_idle_spurr) / delta_tb;
- physc *= 100.00;
+ get_sysdata("shared_processor_mode", &descr, mode);
+ if (!strcmp(mode, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, mode);
+
+ if (delta_idle_spurr > delta_spurr)
+ delta_idle_spurr = delta_spurr;
+
+ if (!strcmp(mode, "Capped")) {
+ /* For dedicated - capped mode */
+ physc = (delta_spurr - delta_idle_spurr) / delta_tb;
+ physc *= 100.00;
+ } else {
+ /* For shared and dedicated - donate mode */
+ physc = delta_spurr / delta_tb;
+ physc *= 100.00;
+ }
rfreq = round_off_freq();
physc += ((physc * rfreq) / 100);
@@ -559,14 +603,33 @@ void get_cpu_idle_spurr(struct sysentry *unused_se, char *buf)
double delta_tb, delta_spurr, delta_idle_spurr;
double physc, idle;
double rfreq;
+ char *descr;
+ char mode[32];
delta_tb = get_scaled_tb();
delta_spurr = get_delta_value("spurr");
delta_idle_spurr = get_delta_value("idle_spurr");
- physc = (delta_spurr - delta_idle_spurr) / delta_tb;
- idle = (delta_spurr / delta_tb) - physc;
- idle *= 100.00;
+ get_sysdata("shared_processor_mode", &descr, mode);
+ if (!strcmp(mode, "Dedicated"))
+ get_sysdata("DedDonMode", &descr, mode);
+
+ if (delta_idle_spurr > delta_spurr)
+ delta_idle_spurr = delta_spurr;
+
+ if (delta_spurr > delta_tb)
+ delta_spurr = delta_tb;
+
+ if (!strcmp(mode, "Capped")) {
+ /* For dedicated - capped mode */
+ physc = (delta_spurr - delta_idle_spurr) / delta_tb;
+ idle = (delta_spurr / delta_tb) - physc;
+ idle *= 100.00;
+ } else {
+ /* For shared and dedicated - donate mode */
+ idle = (delta_tb - delta_spurr) / delta_tb;
+ idle *= 100.00;
+ }
rfreq = round_off_freq();
idle += ((idle * rfreq) / 100);
--
2.39.3