diff --git a/cpumf/lshwc.c b/cpumf/lshwc.c index aba27d36..d5868273 100644 --- a/cpumf/lshwc.c +++ b/cpumf/lshwc.c @@ -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); diff --git a/cpumf/man/lshwc.8 b/cpumf/man/lshwc.8 index 0d9ac7fc..c0dc2624 100644 --- a/cpumf/man/lshwc.8 +++ b/cpumf/man/lshwc.8 @@ -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)