chpstat: Use SI units for default scaling

chpstat uses power-of-two based IEC units such as KiB/s (1024 B/s) when
scaling throughput values in human readable reports. A user interpreting
these numbers can easily be confused by chpstat's default column header
("B/s") to assume that numbers are scaled using power-of-ten based SI
units such as kB/s (1000 B/s).

In addition, users that have worked with similar z/OS tooling to display
channel path activity are used to SI-based scaling, which increases the
chance of chpstat reports being misinterpreted.

To reduce this confusion, use SI units for throughput scaling:

Option          Old factor      New factor
==========================================
--scale k       1024            1000
--scale m       1048576         1000000
--scale g       1073741824      1000000000
--scale auto    IEC units       SI units

Note that machine-readable format produced via option --format is not
affected by scaling.

Reviewed-by: Jimmy Brison <jbrisson@linux.ibm.com>
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
Peter Oberparleiter
2025-08-15 15:36:39 +02:00
committed by Steffen Eiden
parent cb1c002bed
commit 4b76530788
3 changed files with 34 additions and 23 deletions

View File

@@ -290,7 +290,8 @@ values are:
.IP \(bu 3
.B auto:
Scale automatically to fit value into each column. This is the default.
Scale automatically to fit value into each column. To indicate the current scaling factor,
an SI-suffix is added to each scaled number (e.g. K for 1000). This is the default.
.PP
.IP \(bu 3
.IR number :
@@ -299,19 +300,19 @@ Scale by
.PP
.IP \(bu 3
.B K:
Scale by 1024 (KiB)
Scale by 1000 (KB)
.PP
.IP \(bu 3
.B M:
Scale by 1,048,576 (MiB)
Scale by 1,000,000 (MB)
.PP
.IP \(bu 3
.B G:
Scale by 1,073,741,824 (GiB)
Scale by 1,000,000,000 (GB)
.PP
.IP \(bu 3
.B T:
Scale by 1,099,511,627,776 (TiB)
Scale by 1,000,000,000,000 (TB)
.PP
.RE

View File

@@ -459,6 +459,30 @@ static void parse_cmgs(char *arg)
}
}
static bool suffix_to_unit(char *arg, unsigned long *unit_ptr, char *suffix_ptr)
{
const char *suffixes = "KMGT";
unsigned long unit, base;
size_t len = strlen(arg);
char suffix;
int i;
if (len != 1)
return false;
suffix = (char)toupper(*arg);
base = UNIT_DEC;
unit = base;
for (i = 0; suffixes[i]; i++) {
if (suffix == suffixes[i]) {
*unit_ptr = unit;
*suffix_ptr = suffix;
return true;
}
unit *= base;
}
return false;
}
/*
* Parse a scale unit value in @arg and return the resulting scaling factor.
*/
@@ -467,22 +491,8 @@ static unsigned long parse_unit(char *arg)
unsigned long unit;
char *endptr;
if (strlen(arg) == 1) {
opts.unit_suffix = (char)toupper(*arg);
switch (opts.unit_suffix) {
case 'K':
return UNIT_BIN;
case 'M':
return UNIT_BIN * UNIT_BIN;
case 'G':
return UNIT_BIN * UNIT_BIN * UNIT_BIN;
case 'T':
return UNIT_BIN * UNIT_BIN * UNIT_BIN * UNIT_BIN;
default:
break;
}
}
opts.unit_suffix = 0;
if (suffix_to_unit(arg, &unit, &opts.unit_suffix))
return unit;
if (strcmp(arg, "auto") == 0)
return UNIT_AUTO;
/* Parse as number. */
@@ -1355,7 +1365,7 @@ static void add_pair_value(struct util_rec *table, struct column_t *col,
suffix = scale_auto(pair, UNIT_DEC);
} else if (pair->unit == CMG_BPS) {
if (opts.unit == UNIT_AUTO)
suffix = scale_auto(pair, UNIT_BIN);
suffix = scale_auto(pair, UNIT_DEC);
else
scale_fixed(pair, opts.unit);
}

View File

@@ -486,7 +486,7 @@ void column_update_bps_suffix(bool auto_scale, char suffix_char)
if (auto_scale)
util_asprintf(&str, "(B/s)");
else if (suffix_char)
util_asprintf(&str, "(%ciB/s)", suffix_char);
util_asprintf(&str, "(%cB/s)", suffix_char);
else
str = util_strdup("(*)");