diff --git a/cpumf/lspai.c b/cpumf/lspai.c index e831f442..8c7c6448 100644 --- a/cpumf/lspai.c +++ b/cpumf/lspai.c @@ -43,6 +43,10 @@ static struct util_opt opt_vec[] = { UTIL_OPT_SECTION("OPTIONS"), + { + .option = { "delta", no_argument, NULL, 'd' }, + .desc = "Display delta counter values" + }, { .option = { "format", required_argument, NULL, OPT_FORMAT }, .argument = "FORMAT", @@ -100,6 +104,7 @@ static const struct util_prg prg = { static bool numsort; /* If true sort counter numerically */ static bool shortname; /* Use abbreviated counter names */ +static bool delta, firstread; /* Display delta values */ static int output_format = -1; /* Generate style if >= 0 */ static unsigned int max_cpus; /* # of CPUs to read counter values from */ static unsigned int max_fds; /* # of file descriptor to read counter values */ @@ -121,6 +126,8 @@ static int pai_types_show; struct pai_cpudata { /* Event data per CPU */ int fd; /* Event file descriptor */ int cpu; /* CPU number */ + unsigned long value; /* Event value */ + unsigned long prev_value; /* Previous value for deltas */ }; struct pai_ctrname { /* List of defined counters */ @@ -247,7 +254,6 @@ static void read_counternames(struct pai_node *node) if (util_file_read_va(ctrpath, "event=%x", &ctr) == 1) { node->ctrlist[node->ctridx].data = NULL; node->ctrlist[node->ctridx].name = util_strdup(namelist[i]->d_name); - node->ctrlist[node->ctridx].total = 0; node->ctrlist[node->ctridx++].nr = ctr; more++; max_fds++; @@ -426,7 +432,7 @@ static void line_out(char *header) line_header(); /* Print total count of all CPUs */ - printf("%s,%s,", header, "Total"); + printf("%s,%s,", header, delta && !firstread ? "Delta" : "Total"); comma = false; util_list_iterate(&pai_list, node) { for (int i = 0; i < node->ctridx; ++i) { @@ -434,7 +440,6 @@ static void line_out(char *header) putchar(','); printf(ctrformat, node->ctrlist[i].total); comma = true; - node->ctrlist[i].total = 0; } } putchar('\n'); @@ -456,7 +461,8 @@ static void format_line_out(time_t now, char *now_text) util_fmt_pair(FMT_PERSIST, "iteration", "%d", called++); util_fmt_pair(FMT_PERSIST, "time_epoch", "%d", now); util_fmt_pair(FMT_QUOTE | FMT_PERSIST, "time", "%s", now_text); - util_fmt_pair(FMT_QUOTE | FMT_PERSIST, "cpu", "total"); + util_fmt_pair(FMT_QUOTE | FMT_PERSIST, "cpu", + (delta && !firstread) ? "delta" : "total"); util_fmt_obj_start(FMT_LIST, "counters"); for (int i = 0; i < node->ctridx; ++i) { util_fmt_obj_start(FMT_ROW, "counter"); @@ -509,10 +515,17 @@ static void read_painode(void) util_list_iterate(&pai_list, node) { for (int i = 0; i < node->ctridx; ++i) { + node->ctrlist[i].total = 0; for (size_t j = 0; j < max_cpus; ++j) { data = &node->ctrlist[i].data[j]; value = event_read(data->fd); - node->ctrlist[i].total += value; + if (delta) { + data->value = value - data->prev_value; + data->prev_value = value; + } else { + data->value = value; + } + node->ctrlist[i].total += data->value; } } } @@ -525,6 +538,7 @@ static void wait_painode(void) show_values(); if (i + 1 < loops) sleep(read_interval); + firstread = false; } format_line_end(); } @@ -575,6 +589,8 @@ static void event_painode(void) if (CPU_ISSET(j, &cpu_online_mask)) { data->cpu = j; data->fd = event_add(j, i, node); + data->value = 0; + data->prev_value = 0; ++data; } } @@ -670,6 +686,11 @@ int main(int argc, char **argv) default: util_opt_print_parse_error(ch, argv); return EXIT_FAILURE; + case 'd': + delta = true; + firstread = true; + list_only = false; + break; case 'h': util_prg_print_help(); util_opt_print_help(); diff --git a/cpumf/man/lspai.8 b/cpumf/man/lspai.8 index c8c8d64a..d171c152 100644 --- a/cpumf/man/lspai.8 +++ b/cpumf/man/lspai.8 @@ -26,7 +26,7 @@ .RB [ \-n ] .RB [ \-t .IR "\ TYPE" ] -.RB [ \-i +.RB [ \-d ][ \-i .IR SECONDS ] .RB [ \-l .IR COUNT ] @@ -49,6 +49,7 @@ and numbers in various formats. If .I CPULIST is specified or any of the options +.BR \-d , .BR \-s , .BR \-x , .BR \-X , @@ -77,6 +78,12 @@ Displays help information, then exits. Displays version information, then exits. . .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. +. +.TP .BR \-s ", " \-\-short Displays counter names as short names in the heading. A short name consists of @@ -183,6 +190,32 @@ NNPA_2GFRAME(26),NNPA_ACCESSEXCEPT(27) 2025-05-13,08:18:45,Total,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 # .fi +.sp 1 +This \*c example displays the value of PAI crypto counter number 7. +It is field number 116 in the output. +This counter is incremented after \*c is started and +the table shows the delta values for PAI crypto counter 7. +.nf +# lspai -d -s -i 5 -l3 -t crypto | \ +awk -F , '{ print $1 "," $2 "," $3 "," $4 "," $116; }' +Date,Time,CPU,C0,C7 +2025-06-24,13:02:24,Total,0,0 +2025-06-24,13:02:29,Delta,77122286,77122284 +2025-06-24,13:02:34,Delta,92574403,92574403 +# +.fi +.sp 1 +The following table shows the total value for PAI crypto counter 7 +after \*c is started. +.nf +# lspai -s -i 5 -l3 -t crypto | \ +awk -F , '{ print $1 "," $2 "," $3 "," $4 "," $116; }' +Date,Time,CPU,C0,C7 +2025-06-24,13:03:01,Total,0,0 +2025-06-24,13:03:06,Total,72550754,72566121 +2025-06-24,13:03:11,Total,164633982,164650377 +# +.fi .SH "SEE ALSO" .BR pai (8) .BR lscpumf (8)