chpstat: Add data bandwidth utilization column

Add column 'UTIL DATA' that indicates the percentage of channel-path
data bandwidth currently in use. Since channel-paths are bidirectional,
this column represents the maximum of read or write bandwidth
utilization.

Also use this new column in place of 'UTIL BUS' for CMG 4 and 5 default
views since the bus utilization no longer provides a relevant value for
DPU-based channel-path types.

Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Peter Oberparleiter
2024-11-19 14:03:14 +01:00
committed by Jan Höppner
parent 482bd93e2e
commit de18a72249
6 changed files with 62 additions and 6 deletions

View File

@@ -21,7 +21,7 @@
#define PARTIAL_CMCB_SIZE (CMCB_SIZE - PARTIAL_CMCB_OFFSET * sizeof(u32))
#define CUE_SIZE (8 * sizeof(u32))
#define EXT_CUE_SIZE (16 * sizeof(u32))
#define METRICS_SIZE (17 * sizeof(double))
#define METRICS_SIZE (18 * sizeof(double))
/* Bit-width of CUE timestamp field. */
#define CUE_TS_WIDTH 24

View File

@@ -65,6 +65,7 @@ struct metrics2_t {
double util_total;
double util_part;
double util_bus;
double util_data;
double read_total;
double read_part;
double write_total;
@@ -154,6 +155,7 @@ static void pr_metrics(struct cmg_pair_t **a, unsigned int *n,
pr_metric(a, n, metrics, util_total, CMG_PERCENT, COL_UTIL_TOTAL);
pr_metric(a, n, metrics, util_part, CMG_PERCENT, COL_UTIL_PART);
pr_metric(a, n, metrics, util_bus, CMG_PERCENT, COL_UTIL_BUS);
pr_metric(a, n, metrics, util_data, CMG_PERCENT, COL_UTIL_DATA);
pr_metric(a, n, metrics, read_total, CMG_BPS, COL_READ_TOTAL);
pr_metric(a, n, metrics, read_part, CMG_BPS, COL_READ_PART);
pr_metric(a, n, metrics, write_total, CMG_BPS, COL_WRITE_TOTAL);
@@ -194,6 +196,7 @@ static void init_metrics(struct metrics2_t *m)
m->util_total = METRICS_INIT;
m->util_part = METRICS_INIT;
m->util_bus = METRICS_INIT;
m->util_data = METRICS_INIT;
m->read_total = METRICS_INIT;
m->read_part = METRICS_INIT;
m->write_total = METRICS_INIT;
@@ -214,7 +217,10 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
struct cmcb2_t *cmcb = get_cmcb(data);
struct cue2_t *a = get_cue(data, util_a);
struct cue2_t *b = get_cue(data, util_b);
double delta, max;
double delta, max, data_read, data_write;
data_read = METRICS_INIT;
data_write = METRICS_INIT;
/* util_total = 100.0 * work_units_cpc / max_work_units */
if (cue_valid2(a, b, channel_work_units_cpc)) {
@@ -241,6 +247,7 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
if (cue_valid2(a, b, data_units_read_cpc)) {
delta = field_delta(data_units_read_cpc, a, b);
m->read_total = (double)delta * cmcb->data_unit_size / seconds;
data_read = 100.0 * delta / cmcb->max_read_data_units / seconds;
}
/* read_part = data_units_read * unit_size / seconds */
if (cue_valid2(a, b, data_units_read)) {
@@ -252,12 +259,20 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
delta = field_delta(data_units_written_cpc, a, b);
m->write_total = (double)delta * cmcb->data_unit_size /
seconds;
data_write = 100.0 * delta / cmcb->max_write_data_units /
seconds;
}
/* write_part = data_units_written * unit_size / seconds */
if (cue_valid2(a, b, data_units_written)) {
delta = field_delta(data_units_written, a, b);
m->write_part = (double)delta * cmcb->data_unit_size / seconds;
}
/*
* util_data = max (
* 100.0 * data_units_read_cpc / max_read_data_units / seconds),
* 100.0 * data_units_written_cpc / max_write_data_units / seconds)
*/
m->util_data = MAX(data_read, data_write);
}
/* Calculate metrics base on CMG 2 extended CUEs. */

View File

@@ -64,6 +64,7 @@ struct metrics4_t {
double util_total;
double util_part;
double util_bus;
double util_data;
double read_total;
double read_part;
double write_total;
@@ -85,7 +86,7 @@ static const enum column_id_t default_column_ids[] = {
COL_SPEED,
COL_UTIL_PART,
COL_UTIL_TOTAL,
COL_UTIL_BUS,
COL_UTIL_DATA,
COL_DPU_ID,
COL_DPU_UTIL_PART,
COL_DPU_UTIL_TOTAL,
@@ -146,6 +147,7 @@ static void pr_metrics(struct cmg_pair_t **a, unsigned int *n,
pr_metric(a, n, metrics, util_total, CMG_PERCENT, COL_UTIL_TOTAL);
pr_metric(a, n, metrics, util_part, CMG_PERCENT, COL_UTIL_PART);
pr_metric(a, n, metrics, util_bus, CMG_PERCENT, COL_UTIL_BUS);
pr_metric(a, n, metrics, util_data, CMG_PERCENT, COL_UTIL_DATA);
pr_metric(a, n, metrics, read_total, CMG_BPS, COL_READ_TOTAL);
pr_metric(a, n, metrics, read_part, CMG_BPS, COL_READ_PART);
pr_metric(a, n, metrics, write_total, CMG_BPS, COL_WRITE_TOTAL);
@@ -186,6 +188,7 @@ static void init_metrics(struct metrics4_t *m)
m->util_total = METRICS_INIT;
m->util_part = METRICS_INIT;
m->util_bus = METRICS_INIT;
m->util_data = METRICS_INIT;
m->read_total = METRICS_INIT;
m->read_part = METRICS_INIT;
m->write_total = METRICS_INIT;
@@ -203,7 +206,10 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
struct cmcb4_t *cmcb = get_cmcb(data);
struct cue4_t *a = get_cue(data, util_a);
struct cue4_t *b = get_cue(data, util_b);
double delta, max;
double delta, max, data_read, data_write;
data_read = METRICS_INIT;
data_write = METRICS_INIT;
/* util_total = 100.0 * work_units_cpc / max_work_units */
if (cue_valid2(a, b, channel_work_units_cpc)) {
@@ -230,6 +236,7 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
if (cue_valid2(a, b, data_units_read_cpc)) {
delta = field_delta(data_units_read_cpc, a, b);
m->read_total = (double)delta * cmcb->data_unit_size / seconds;
data_read = 100.0 * delta / cmcb->max_read_data_units / seconds;
}
/* read_part = data_units_read * unit_size / seconds */
if (cue_valid2(a, b, data_units_read)) {
@@ -240,12 +247,20 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
if (cue_valid2(a, b, data_units_written_cpc)) {
delta = field_delta(data_units_written_cpc, a, b);
m->write_total = (double)delta * cmcb->data_unit_size / seconds;
data_write = 100.0 * delta / cmcb->max_write_data_units /
seconds;
}
/* write_part = data_units_written * unit_size / seconds */
if (cue_valid2(a, b, data_units_written)) {
delta = field_delta(data_units_written, a, b);
m->write_part = (double)delta * cmcb->data_unit_size / seconds;
}
/*
* util_data = max (
* 100.0 * data_units_read_cpc / max_read_data_units / seconds),
* 100.0 * data_units_written_cpc / max_write_data_units / seconds)
*/
m->util_data = MAX(data_read, data_write);
}
/* Calculate metrics base on CMG 4 extended CUEs. */

View File

@@ -70,6 +70,7 @@ struct metrics5_t {
double util_total;
double util_part;
double util_bus;
double util_data;
double read_total;
double read_part;
double write_total;
@@ -97,7 +98,7 @@ static const enum column_id_t default_column_ids[] = {
COL_SPEED,
COL_UTIL_PART,
COL_UTIL_TOTAL,
COL_UTIL_BUS,
COL_UTIL_DATA,
COL_DPU_ID,
COL_DPU_UTIL_PART,
COL_DPU_UTIL_TOTAL,
@@ -167,6 +168,7 @@ static void pr_metrics(struct cmg_pair_t **a, unsigned int *n,
pr_metric(a, n, metrics, util_total, CMG_PERCENT, COL_UTIL_TOTAL);
pr_metric(a, n, metrics, util_part, CMG_PERCENT, COL_UTIL_PART);
pr_metric(a, n, metrics, util_bus, CMG_PERCENT, COL_UTIL_BUS);
pr_metric(a, n, metrics, util_data, CMG_PERCENT, COL_UTIL_DATA);
pr_metric(a, n, metrics, read_total, CMG_BPS, COL_READ_TOTAL);
pr_metric(a, n, metrics, read_part, CMG_BPS, COL_READ_PART);
pr_metric(a, n, metrics, write_total, CMG_BPS, COL_WRITE_TOTAL);
@@ -213,6 +215,7 @@ static void init_metrics(struct metrics5_t *m)
m->util_total = METRICS_INIT;
m->util_part = METRICS_INIT;
m->util_bus = METRICS_INIT;
m->util_data = METRICS_INIT;
m->read_total = METRICS_INIT;
m->read_part = METRICS_INIT;
m->write_total = METRICS_INIT;
@@ -236,7 +239,10 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
struct cmcb5_t *cmcb = get_cmcb(data);
struct cue5_t *a = get_cue(data, util_a);
struct cue5_t *b = get_cue(data, util_b);
double delta, max;
double delta, max, data_read, data_write;
data_read = METRICS_INIT;
data_write = METRICS_INIT;
/* util_total = 100.0 * work_units_cpc / max_work_units */
if (cue_valid2(a, b, channel_work_units_cpc)) {
@@ -263,6 +269,7 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
if (cue_valid2(a, b, data_units_read_cpc)) {
delta = field_delta(data_units_read_cpc, a, b);
m->read_total = (double)delta * cmcb->data_unit_size / seconds;
data_read = 100.0 * delta / cmcb->max_read_data_units / seconds;
}
/* read_part = data_units_read * unit_size / seconds */
if (cue_valid2(a, b, data_units_read)) {
@@ -273,12 +280,20 @@ static void calc_metrics(struct cmg_data_t *data, double seconds)
if (cue_valid2(a, b, data_units_written_cpc)) {
delta = field_delta(data_units_written_cpc, a, b);
m->write_total = (double)delta * cmcb->data_unit_size / seconds;
data_write = 100.0 * delta / cmcb->max_write_data_units /
seconds;
}
/* write_part = data_units_written * unit_size / seconds */
if (cue_valid2(a, b, data_units_written)) {
delta = field_delta(data_units_written, a, b);
m->write_part = (double)delta * cmcb->data_unit_size / seconds;
}
/*
* util_data = max (
* 100.0 * data_units_read_cpc / max_read_data_units / seconds),
* 100.0 * data_units_written_cpc / max_write_data_units / seconds)
*/
m->util_data = MAX(data_read, data_write);
}
/* Calculate metrics base on CMG 5 extended CUEs. */

View File

@@ -134,6 +134,16 @@ static struct column_t columns[] = {
HDR1_UTIL_GROUP,
0,
},
{
COL_UTIL_DATA,
"util_data",
COL_PERCENT,
"Data bandwidth utilization in %",
"DATA",
HDR1_UTIL_SINGLE,
HDR1_UTIL_GROUP,
0,
},
{
COL_READ_PART,
"read_part",

View File

@@ -24,6 +24,7 @@ enum column_id_t {
COL_UTIL_PART,
COL_UTIL_TOTAL,
COL_UTIL_BUS,
COL_UTIL_DATA,
COL_READ_PART,
COL_READ_TOTAL,
COL_WRITE_PART,