mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
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>
484 lines
8.0 KiB
C
484 lines
8.0 KiB
C
/*
|
|
* Registry for supported table columns
|
|
*
|
|
* Copyright IBM Corp. 2024
|
|
*
|
|
* s390-tools is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "column.h"
|
|
|
|
#include "lib/util_base.h"
|
|
#include "lib/util_libc.h"
|
|
|
|
/*
|
|
* Use group header for adjacent columns of the same type to improve
|
|
* readability.
|
|
*
|
|
* Single header: UTIL Group header: UTILIZATION
|
|
* PART PART TOTAL
|
|
*/
|
|
#define HDR1_CHP_SINGLE ""
|
|
#define HDR1_CHP_GROUP "CHANNEL-PATH"
|
|
#define HDR1_UTIL_SINGLE "UTIL"
|
|
#define HDR1_UTIL_GROUP "UTILIZATION(%)"
|
|
#define HDR1_READ_SINGLE "READ"
|
|
#define HDR1_READ_GROUP "READ"
|
|
#define HDR1_WRITE_SINGLE "WRITE"
|
|
#define HDR1_WRITE_GROUP "WRITE"
|
|
#define HDR1_FICON_SINGLE "FICON"
|
|
#define HDR1_FICON_GROUP "FICON-OPS"
|
|
#define HDR1_HPF_SINGLE "HPF"
|
|
#define HDR1_HPF_GROUP "HPF-OPS"
|
|
#define HDR1_MSGR_SINGLE "RATE"
|
|
#define HDR1_MSGR_GROUP "MSG-RATE"
|
|
#define HDR1_MSGSZ_SINGLE "SIZE"
|
|
#define HDR1_MSGSZ_GROUP "MSG-SIZE"
|
|
#define HDR1_MSG_RCVF_SINGLE "RFAIL"
|
|
#define HDR1_MSG_RCVF_GROUP "RECEIVE-FAIL"
|
|
#define HDR1_DPU_UTIL_SINGLE "DPU"
|
|
#define HDR1_DPU_UTIL_GROUP "DPU UTILIZATION(%)"
|
|
|
|
static struct column_t columns[] = {
|
|
{
|
|
COL_CHPID,
|
|
"chpid",
|
|
COL_OTHER,
|
|
"Channel-path ID",
|
|
"ID",
|
|
HDR1_CHP_SINGLE,
|
|
HDR1_CHP_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_TYPE,
|
|
"type",
|
|
COL_OTHER,
|
|
"Channel-path type",
|
|
"TYP",
|
|
HDR1_CHP_SINGLE,
|
|
HDR1_CHP_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_CMG,
|
|
"cmg",
|
|
COL_OTHER,
|
|
"Channel-measurement group",
|
|
"CMG",
|
|
HDR1_CHP_SINGLE,
|
|
HDR1_CHP_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_SPEED,
|
|
"speed",
|
|
COL_OTHER,
|
|
"Operational speed",
|
|
"SPEED",
|
|
HDR1_CHP_SINGLE,
|
|
HDR1_CHP_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_SHARED,
|
|
"shared",
|
|
COL_OTHER,
|
|
"Shared channel-path indicator",
|
|
"SHR",
|
|
HDR1_CHP_SINGLE,
|
|
HDR1_CHP_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_INTERVAL,
|
|
"interval",
|
|
COL_OTHER,
|
|
"Cumulated statistics update interval",
|
|
"INT",
|
|
HDR1_CHP_SINGLE,
|
|
HDR1_CHP_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_UTIL_PART,
|
|
"util_part",
|
|
COL_PERCENT,
|
|
"Partition channel-path utilization in %",
|
|
"PART",
|
|
HDR1_UTIL_SINGLE,
|
|
HDR1_UTIL_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_UTIL_TOTAL,
|
|
"util_total",
|
|
COL_PERCENT,
|
|
"Total channel-path utilization in %",
|
|
"TOTAL",
|
|
HDR1_UTIL_SINGLE,
|
|
HDR1_UTIL_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_UTIL_BUS,
|
|
"util_bus",
|
|
COL_PERCENT,
|
|
"Bus utilization in %",
|
|
"BUS",
|
|
HDR1_UTIL_SINGLE,
|
|
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",
|
|
COL_BPS,
|
|
"Partition read throughput in B/s",
|
|
"PART",
|
|
HDR1_READ_SINGLE,
|
|
HDR1_READ_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_READ_TOTAL,
|
|
"read_total",
|
|
COL_BPS,
|
|
"Total read throughput in B/s",
|
|
"TOTAL",
|
|
HDR1_READ_SINGLE,
|
|
HDR1_READ_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_WRITE_PART,
|
|
"write_part",
|
|
COL_BPS,
|
|
"Partition write throughput in B/s",
|
|
"PART",
|
|
HDR1_WRITE_SINGLE,
|
|
HDR1_WRITE_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_WRITE_TOTAL,
|
|
"write_total",
|
|
COL_BPS,
|
|
"Total write throughput in B/s",
|
|
"TOTAL",
|
|
HDR1_WRITE_SINGLE,
|
|
HDR1_WRITE_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_FICON_RATE,
|
|
"ficon_rate",
|
|
COL_NUMBER,
|
|
"FICON operations per second",
|
|
"RATE",
|
|
HDR1_FICON_SINGLE,
|
|
HDR1_FICON_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_FICON_ACTIVE,
|
|
"ficon_active",
|
|
COL_NUMBER,
|
|
"Avg. concurrently active FICON operations",
|
|
"ACTV",
|
|
HDR1_FICON_SINGLE,
|
|
HDR1_FICON_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_FICON_DEFER,
|
|
"ficon_defer",
|
|
COL_NUMBER,
|
|
"Deferred FICON operations per second",
|
|
"DEFER",
|
|
HDR1_FICON_SINGLE,
|
|
HDR1_FICON_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_HPF_RATE,
|
|
"hpf_rate",
|
|
COL_NUMBER,
|
|
"HPF operations per second",
|
|
"RATE",
|
|
HDR1_HPF_SINGLE,
|
|
HDR1_HPF_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_HPF_ACTIVE,
|
|
"hpf_active",
|
|
COL_NUMBER,
|
|
"Avg. concurrently active HPF operations",
|
|
"ACTV",
|
|
HDR1_HPF_SINGLE,
|
|
HDR1_HPF_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_HPF_DEFER,
|
|
"hpf_defer",
|
|
COL_NUMBER,
|
|
"Deferred HPF operations per second",
|
|
"DEFER",
|
|
HDR1_HPF_SINGLE,
|
|
HDR1_HPF_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_MSG_RATE_PART,
|
|
"msg_rate_part",
|
|
COL_NUMBER,
|
|
"Partition message send rate per second",
|
|
"PART",
|
|
HDR1_MSGR_SINGLE,
|
|
HDR1_MSGR_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_MSG_RATE_TOTAL,
|
|
"msg_rate_total",
|
|
COL_NUMBER,
|
|
"Total message send rate per second",
|
|
"TOTAL",
|
|
HDR1_MSGR_SINGLE,
|
|
HDR1_MSGR_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_MSG_SIZE_PART,
|
|
"msg_size_part",
|
|
COL_NUMBER,
|
|
"Partition avg. send message size",
|
|
"PART",
|
|
HDR1_MSGSZ_SINGLE,
|
|
HDR1_MSGSZ_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_MSG_SIZE_TOTAL,
|
|
"msg_size_total",
|
|
COL_NUMBER,
|
|
"Total avg. send message size",
|
|
"TOTAL",
|
|
HDR1_MSGSZ_SINGLE,
|
|
HDR1_MSGSZ_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_SEND_FAIL_PART,
|
|
"send_fail_part",
|
|
COL_NUMBER,
|
|
"Partition message send fail rate per second",
|
|
"PART",
|
|
"SNDFAIL",
|
|
"SNDFAIL",
|
|
0,
|
|
},
|
|
{
|
|
COL_RCV_FAIL_PART,
|
|
"rcv_fail_part",
|
|
COL_NUMBER,
|
|
"Partition message receive fail rate per second",
|
|
"PART",
|
|
HDR1_MSG_RCVF_SINGLE,
|
|
HDR1_MSG_RCVF_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_RCV_FAIL_TOTAL,
|
|
"rcv_fail_total",
|
|
COL_NUMBER,
|
|
"Total message receive fail rate per second",
|
|
"TOTAL",
|
|
HDR1_MSG_RCVF_SINGLE,
|
|
HDR1_MSG_RCVF_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_DPU_ID,
|
|
"dpu_id",
|
|
COL_OTHER,
|
|
"DPU ID associated with channel-path",
|
|
"ID",
|
|
HDR1_DPU_UTIL_SINGLE,
|
|
HDR1_DPU_UTIL_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_DPU_UTIL,
|
|
"dpu_util",
|
|
COL_PERCENT,
|
|
"Full DPU utilization in %",
|
|
"FULL",
|
|
HDR1_DPU_UTIL_SINGLE,
|
|
HDR1_DPU_UTIL_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_DPU_UTIL_PART,
|
|
"dpu_util_part",
|
|
COL_PERCENT,
|
|
"Partition channel-path DPU utilization in %",
|
|
"PART",
|
|
HDR1_DPU_UTIL_SINGLE,
|
|
HDR1_DPU_UTIL_GROUP,
|
|
0,
|
|
},
|
|
{
|
|
COL_DPU_UTIL_TOTAL,
|
|
"dpu_util_total",
|
|
COL_PERCENT,
|
|
"Total channel-path DPU utilization in %",
|
|
"TOTAL",
|
|
HDR1_DPU_UTIL_SINGLE,
|
|
HDR1_DPU_UTIL_GROUP,
|
|
0,
|
|
},
|
|
};
|
|
|
|
/* Columns selected by default. */
|
|
static const int default_columns[] = {
|
|
COL_CHPID,
|
|
COL_TYPE,
|
|
COL_CMG,
|
|
COL_SHARED,
|
|
COL_SPEED,
|
|
COL_UTIL_PART,
|
|
COL_UTIL_TOTAL,
|
|
COL_UTIL_BUS,
|
|
COL_DPU_ID,
|
|
COL_READ_PART,
|
|
COL_READ_TOTAL,
|
|
COL_WRITE_PART,
|
|
COL_WRITE_TOTAL,
|
|
/* End of list. */
|
|
COL_END
|
|
};
|
|
|
|
static struct column_t **selected_cols;
|
|
static unsigned int num_selected_cols;
|
|
static bool hdr_updated;
|
|
|
|
struct column_t *column_get_by_index(unsigned int i, bool selected)
|
|
{
|
|
if (selected)
|
|
return i < num_selected_cols ? selected_cols[i] : NULL;
|
|
return i < ARRAY_SIZE(columns) ? &columns[i] : NULL;
|
|
}
|
|
|
|
/*
|
|
* Retrieve column object by @name or %NULL if column does not exist.
|
|
*/
|
|
struct column_t *column_get_by_name(const char *name)
|
|
{
|
|
struct column_t *col;
|
|
|
|
column_for_each(col) {
|
|
if (strcasecmp(col->name, name) == 0)
|
|
return col;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Add the specified column to the list of selected columns. Discard duplicate
|
|
* selections of the same column.
|
|
*/
|
|
void column_select(struct column_t *col)
|
|
{
|
|
struct column_t *c;
|
|
|
|
/* Silently filter out double selection of columns to prevent problems
|
|
* with non-unique util_rec name fields. */
|
|
column_for_each_selected(c) {
|
|
if (c == col)
|
|
return;
|
|
}
|
|
|
|
util_add_array(&selected_cols, &num_selected_cols, col);
|
|
}
|
|
|
|
void column_select_id_list(const int *ids)
|
|
{
|
|
struct column_t *col;
|
|
int i;
|
|
|
|
for (i = 0; ids[i] != COL_END; i++) {
|
|
column_for_each(col) {
|
|
if (col->id == ids[i]) {
|
|
column_select(col);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void column_select_default(void)
|
|
{
|
|
column_select_id_list(default_columns);
|
|
}
|
|
|
|
void column_select_all(void)
|
|
{
|
|
struct column_t *col;
|
|
|
|
column_for_each(col)
|
|
column_select(col);
|
|
}
|
|
|
|
void column_update_bps_suffix(bool auto_scale, char suffix_char)
|
|
{
|
|
struct column_t *col;
|
|
char *str;
|
|
|
|
if (auto_scale)
|
|
util_asprintf(&str, "(B/s)");
|
|
else if (suffix_char)
|
|
util_asprintf(&str, "(%ciB/s)", suffix_char);
|
|
else
|
|
str = util_strdup("(*)");
|
|
|
|
column_for_each(col) {
|
|
if (col->unit != COL_BPS) {
|
|
col->hdr1_group = util_strdup(col->hdr1_group);
|
|
continue;
|
|
}
|
|
util_asprintf(&col->hdr1_group, "%s%s", col->hdr1_group, str);
|
|
}
|
|
free(str);
|
|
|
|
hdr_updated = true;
|
|
}
|
|
|
|
void column_exit(void)
|
|
{
|
|
struct column_t *col;
|
|
|
|
if (hdr_updated) {
|
|
column_for_each(col)
|
|
free(col->hdr1_group);
|
|
}
|
|
free(selected_cols);
|
|
}
|