cpumf/lshwc: Add support for delta counter value display

Add a flag to display the counter value in form of a delta
value. This format shows the increase of that counter value
in comparison to the previous readout.
The first line is the base for the delta calculation and always
shows 'Total'. The remaining lines show 'Delta' in the third
column.

 # ./lshwc -d -i 3 -l 5 -x -s :p
 Date,Time,CPU,P32,P33
 2024-11-27,15:45:55,Total,d7b,172
 2024-11-27,15:45:58,Delta,2be403,2d58bb
 2024-11-27,15:46:01,Delta,43e3b,22c41
 2024-11-27,15:46:04,Delta,58e3a,35319
 2024-11-27,15:46:07,Delta,5080e,2b81c
 #

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Thomas Richter
2025-03-26 10:57:16 +01:00
committed by Jan Höppner
parent c39722aff2
commit 2278f112ba
2 changed files with 56 additions and 4 deletions

View File

@@ -57,6 +57,7 @@ static bool allcpu;
static char *ctrformat = "%ld";
static bool shortname;
static bool hideundef;
static bool delta, firstread;
static unsigned int max_possible_cpus; /* No of possible CPUs */
static struct ctrname { /* List of defined counters */
@@ -64,6 +65,7 @@ static struct ctrname { /* List of defined counters */
bool hitcnt; /* Counter number read from ioctl() */
unsigned long total; /* Total counter value */
unsigned long *ccv; /* Per CPU counter value */
unsigned long *ccvprv; /* Per CPU counter value (previous read) */
} ctrname[MAXCTRS];
static char *mk_name(int ctr, char *name)
@@ -129,6 +131,7 @@ static void free_counternames(void)
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
free(ctrname[i].name);
free(ctrname[i].ccv);
free(ctrname[i].ccvprv);
}
}
@@ -391,7 +394,7 @@ static void line(char *header)
}
/* Print total count of all CPUs */
printf("%sTotal,", header);
printf("%s%s,", header, delta && !firstread ? "Delta" : "Total");
comma = false;
for (size_t i = 0; i < ARRAY_SIZE(ctrname); ++i) {
if (!ctrname[i].hitcnt)
@@ -490,7 +493,18 @@ static bool add_countervalue(size_t idx, unsigned int cpu, unsigned long value)
warnx("Invalid CPU number %d", cpu);
return false;
}
ctrname[idx].ccv[cpu] = value;
if (delta) {
if (firstread) {
ctrname[idx].ccvprv[cpu] = value;
ctrname[idx].ccv[cpu] = value;
} else {
ctrname[idx].ccv[cpu] = value - ctrname[idx].ccvprv[cpu];
ctrname[idx].ccvprv[cpu] = value;
value = ctrname[idx].ccv[cpu];
}
} else {
ctrname[idx].ccv[cpu] = value;
}
ctrname[idx].total += value;
ctrname[idx].hitcnt = true;
return true;
@@ -538,6 +552,7 @@ static int test_read(struct s390_hwctr_read *read)
}
}
show();
firstread = false;
return 0;
}
@@ -665,6 +680,10 @@ static struct util_opt opt_vec[] = {
.option = { "hide", no_argument, NULL, 'H' },
.desc = "Do not display undefined counters of a counter set"
},
{
.option = { "delta", no_argument, NULL, 'd' },
.desc = "Display delta counter values"
},
UTIL_OPT_HELP,
UTIL_OPT_VERSION,
UTIL_OPT_END
@@ -740,6 +759,10 @@ int main(int argc, char **argv)
case 'a':
allcpu = true;
break;
case 'd':
delta = true;
firstread = true;
break;
}
}
@@ -753,8 +776,10 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
for (unsigned int i = 0; i < ARRAY_SIZE(ctrname); ++i)
for (unsigned int i = 0; i < ARRAY_SIZE(ctrname); ++i) {
ctrname[i].ccv = util_zalloc(max_possible_cpus * sizeof(unsigned long));
ctrname[i].ccvprv = util_zalloc(max_possible_cpus * sizeof(unsigned long));
}
if (optind >= argc) {
ch = do_it(NULL);

View File

@@ -14,7 +14,7 @@ lshwc \- extract CPU Measurement Facilities counter sets
.
.SH SYNOPSIS
\*c
.RB [ \-a ][ \-H][ \-s ][ \-x ][ \-X]
.RB [ \-a ][ \-d][ \-H][ \-s ][ \-x ][ \-X]
.RB [ \-l
.IR count ]
.RB [ \-i
@@ -51,6 +51,13 @@ Displays counter values from each CPU.
The default is a total summary line of all counters from all CPUs.
.
.TP
.BR \-d ", " \-\-delta
Displays counter values in form of deltas.
Each counter value shows the increment to the previous output line.
Without this flag the total value of each counter is displayed.
See Examples.
.
.TP
.BR \-i ", " \-\-interval \fI\ seconds\fP
Specifies a time interval, in seconds,
that the command waits between read operations.
@@ -162,6 +169,26 @@ Date,Time,CPU,PROBLEM_STATE_CPU_CYCLES(32),PROBLEM_STATE_INSTRUCTIONS(33)
2021-04-01,11:56:47,Total,6432163447,2978400903
.ft
.fi
.sp 1
This example shows the counter values of the basic counter set
using delta output format.
.nf
.ft CW
.sp 1
# lshwc -d -l 10 -i 5 -s :b
Date,Time,CPU,B0,B1,B2,B3,B4,B5
2025-03-26,10:34:19,Total,208075,117287,1950,50548,1082,49609
2025-03-26,10:34:24,Delta,85800055,70353492,590286,13228290,364034,12945804
2025-03-26,10:34:29,Delta,70654751,60656797,483047,10838672,305703,10570868
2025-03-26,10:34:34,Delta,81043162,69476160,587141,13228161,376662,12868298
2025-03-26,10:34:39,Delta,73434017,62675417,524857,11787256,333966,11543649
2025-03-26,10:34:44,Delta,68367967,58452919,506712,11370740,310785,10589883
2025-03-26,10:34:49,Delta,70351947,57607764,507675,11433377,312433,10676243
2025-03-26,10:34:54,Delta,77154817,65371168,562153,12671030,349750,12311061
2025-03-26,10:34:59,Delta,88871882,75441201,655310,14875963,392530,13773130
2025-03-26,10:35:04,Delta,83763472,71730813,609260,13643680,366992,12672405
.ft
.fi
.SH "SEE ALSO"
.BR lscpumf (8)
.BR chcpumf (8)