Skip to content

Commit

Permalink
rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long
Browse files Browse the repository at this point in the history
Most fields of struct timerlat_top_cpu are unsigned long long, but the
fields {irq,thread,user}_count are int (32-bit signed).

This leads to overflow when tracing on a large number of CPUs for a long
enough time:
$ rtla timerlat top -a20 -c 1-127 -d 12h
...
  0 12:00:00   |          IRQ Timer Latency (us)        |         Thread Timer Latency (us)
CPU COUNT      |      cur       min       avg       max |      cur       min       avg       max
 1 #43200096  |        0         0         1         2 |        3         2         6        12
...
127 #43200096  |        0         0         1         2 |        3         2         5        11
ALL #119144 e4 |                  0         5         4 |                  2        28        16

The average latency should be 0-1 for IRQ and 5-6 for thread, but is
reported as 5 and 28, about 4 to 5 times more, due to the count
overflowing when summed over all CPUs: 43200096 * 127 = 5486412192,
however, 1191444898 (= 5486412192 mod MAX_INT) is reported instead, as
seen on the last line of the output, and the averages are thus ~4.6
times higher than they should be (5486412192 / 1191444898 = ~4.6).

Fix the issue by changing {irq,thread,user}_count fields to unsigned
long long, similarly to other fields in struct timerlat_top_cpu and to
the count variable in timerlat_top_print_sum.

Link: https://lore.kernel.org/[email protected]
Reported-by: Attila Fazekas <[email protected]>
Signed-off-by: Tomas Glozar <[email protected]>
Signed-off-by: Steven Rostedt (Google) <[email protected]>
  • Loading branch information
lenticularis39 authored and rostedt committed Oct 11, 2024
1 parent 0eecee3 commit 4eba472
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions tools/tracing/rtla/src/timerlat_top.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ struct timerlat_top_params {
};

struct timerlat_top_cpu {
int irq_count;
int thread_count;
int user_count;
unsigned long long irq_count;
unsigned long long thread_count;
unsigned long long user_count;

unsigned long long cur_irq;
unsigned long long min_irq;
Expand Down Expand Up @@ -280,7 +280,7 @@ static void timerlat_top_print(struct osnoise_tool *top, int cpu)
/*
* Unless trace is being lost, IRQ counter is always the max.
*/
trace_seq_printf(s, "%3d #%-9d |", cpu, cpu_data->irq_count);
trace_seq_printf(s, "%3d #%-9llu |", cpu, cpu_data->irq_count);

if (!cpu_data->irq_count) {
trace_seq_printf(s, "%s %s %s %s |", no_value, no_value, no_value, no_value);
Expand Down

0 comments on commit 4eba472

Please sign in to comment.