Skip to content

Commit dd08f0f

Browse files
authored
hardirqs: Optimize output information and increase CPU display (#5228)
Combine the previous count and time into one, and increase CPU independent statistics and maximum interrupt time Before: ./hardirqs Tracing hard irq event time... Hit Ctrl-C to end. ^C HARDIRQ TOTAL_usecs enp0s3 254 snd_intel8x0 368 ./hardirqs -C Tracing hard irq events... Hit Ctrl-C to end. ^C HARDIRQ TOTAL_count enp0s3 14 ata_piix 2 After: ./hardirqs Tracing hard irq event time... Hit Ctrl-C to end. ^C HARDIRQ TOTAL_count TOTAL_usecs MAX_usecs ata_piix 2 32 21 enp0s3 19 318 42 ./hardirqs -C Tracing hard irq event time... Hit Ctrl-C to end. ^C HARDIRQ TOTAL_count TOTAL_usecs MAX_usecs CPU enp0s3 111375 1420732 303 2 enp0s3 1546 21826 39 9 ata_piix 8 162 33 8 Signed-off-by: Feng Yang <[email protected]>
1 parent d124144 commit dd08f0f

File tree

3 files changed

+41
-53
lines changed

3 files changed

+41
-53
lines changed

libbpf-tools/hardirqs.bpf.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
const volatile bool filter_cg = false;
1414
const volatile bool targ_dist = false;
1515
const volatile bool targ_ns = false;
16-
const volatile bool do_count = false;
16+
const volatile bool cpu = false;
1717
const volatile int targ_cpu = -1;
1818

1919
struct {
@@ -53,26 +53,12 @@ static int handle_entry(int irq, struct irqaction *action)
5353
if (!is_target_cpu())
5454
return 0;
5555

56-
if (do_count) {
57-
struct irq_key key = {};
58-
struct info *info;
59-
60-
bpf_probe_read_kernel_str(&key.name, sizeof(key.name), BPF_CORE_READ(action, name));
61-
info = bpf_map_lookup_or_try_init(&infos, &key, &zero);
62-
if (!info)
63-
return 0;
64-
info->count += 1;
65-
return 0;
66-
} else {
67-
u64 ts = bpf_ktime_get_ns();
68-
u32 key = 0;
56+
u64 ts = bpf_ktime_get_ns();
57+
u32 key = 0;
6958

70-
if (filter_cg && !bpf_current_task_under_cgroup(&cgroup_map, 0))
71-
return 0;
59+
bpf_map_update_elem(&start, &key, &ts, BPF_ANY);
7260

73-
bpf_map_update_elem(&start, &key, &ts, BPF_ANY);
74-
return 0;
75-
}
61+
return 0;
7662
}
7763

7864
static int handle_exit(int irq, struct irqaction *action)
@@ -98,12 +84,18 @@ static int handle_exit(int irq, struct irqaction *action)
9884
delta /= 1000U;
9985

10086
bpf_probe_read_kernel_str(&ikey.name, sizeof(ikey.name), BPF_CORE_READ(action, name));
87+
if (cpu)
88+
ikey.cpu = bpf_get_smp_processor_id();
10189
info = bpf_map_lookup_or_try_init(&infos, &ikey, &zero);
10290
if (!info)
10391
return 0;
10492

93+
info->count += 1;
94+
10595
if (!targ_dist) {
106-
info->count += delta;
96+
info->total_time += delta;
97+
if (delta > info->max_time)
98+
info->max_time = delta;
10799
} else {
108100
u64 slot;
109101

libbpf-tools/hardirqs.c

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "trace_helpers.h"
1919

2020
struct env {
21-
bool count;
21+
bool cpu;
2222
bool distributed;
2323
bool nanoseconds;
2424
time_t interval;
@@ -42,18 +42,19 @@ const char *argp_program_bug_address =
4242
const char argp_program_doc[] =
4343
"Summarize hard irq event time as histograms.\n"
4444
"\n"
45-
"USAGE: hardirqs [--help] [-T] [-N] [-d] [interval] [count] [-c CG]\n"
45+
"USAGE: hardirqs [--help] [-T] [-N] [-d] [-C] [interval] [count] [-c CG]\n"
4646
"\n"
4747
"EXAMPLES:\n"
4848
" hardirqs # sum hard irq event time\n"
4949
" hardirqs -d # show hard irq event time as histograms\n"
5050
" hardirqs 1 10 # print 1 second summaries, 10 times\n"
5151
" hardirqs -c CG # Trace process under cgroupsPath CG\n"
5252
" hardirqs --cpu 1 # only stat irq on cpu 1\n"
53+
" hardirqs -C # display separately by CPU\n"
5354
" hardirqs -NT 1 # 1s summaries, nanoseconds, and timestamps\n";
5455

5556
static const struct argp_option opts[] = {
56-
{ "count", 'C', NULL, 0, "Show event counts instead of timing", 0 },
57+
{ "CPU", 'C', NULL, 0, "Display separately by CPU", 0 },
5758
{ "distributed", 'd', NULL, 0, "Show distributions as histograms", 0 },
5859
{ "cgroup", 'c', "/sys/fs/cgroup/unified", 0, "Trace process in cgroup path", 0 },
5960
{ "cpu", 's', "CPU", 0, "Only stat irq on selected cpu", 0 },
@@ -79,7 +80,7 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
7980
env.distributed = true;
8081
break;
8182
case 'C':
82-
env.count = true;
83+
env.cpu = true;
8384
break;
8485
case 's':
8586
errno = 0;
@@ -142,14 +143,16 @@ static int print_map(struct bpf_map *map)
142143
{
143144
struct irq_key lookup_key = {}, next_key;
144145
struct info info;
146+
const char *units = env.nanoseconds ? "nsecs" : "usecs";
145147
int fd, err;
146148

147-
if (env.count) {
148-
printf("%-26s %11s\n", "HARDIRQ", "TOTAL_count");
149-
} else if (!env.distributed) {
150-
const char *units = env.nanoseconds ? "nsecs" : "usecs";
151-
152-
printf("%-26s %6s%5s\n", "HARDIRQ", "TOTAL_", units);
149+
if (!env.distributed) {
150+
printf("%-33s %11s %6s%5s %4s%5s", "HARDIRQ", "TOTAL_count",
151+
"TOTAL_", units, "MAX_", units);
152+
if (env.cpu)
153+
printf(" %3s\n", "CPU");
154+
else
155+
printf("\n");
153156
}
154157

155158
fd = bpf_map__fd(map);
@@ -160,10 +163,15 @@ static int print_map(struct bpf_map *map)
160163
return -1;
161164
}
162165
if (!env.distributed)
163-
printf("%-26s %11llu\n", next_key.name, info.count);
166+
if (env.cpu)
167+
printf("%-33s %11llu %11llu %9llu %3u\n", next_key.name,
168+
info.count, info.total_time, info.max_time, next_key.cpu);
169+
else
170+
printf("%-33s %11llu %11llu %9llu\n", next_key.name,
171+
info.count, info.total_time, info.max_time);
164172
else {
165-
const char *units = env.nanoseconds ? "nsecs" : "usecs";
166-
173+
if (env.cpu)
174+
printf("cpu = %u ", next_key.cpu);
167175
printf("hardirq = %s\n", next_key.name);
168176
print_log2_hist(info.slots, MAX_SLOTS, units);
169177
}
@@ -203,11 +211,6 @@ int main(int argc, char **argv)
203211
if (err)
204212
return err;
205213

206-
if (env.count && env.distributed) {
207-
fprintf(stderr, "count, distributed cann't be used together.\n");
208-
return 1;
209-
}
210-
211214
libbpf_set_print(libbpf_print_fn);
212215

213216
obj = hardirqs_bpf__open();
@@ -219,24 +222,17 @@ int main(int argc, char **argv)
219222
if (probe_tp_btf("irq_handler_entry")) {
220223
bpf_program__set_autoload(obj->progs.irq_handler_entry, false);
221224
bpf_program__set_autoload(obj->progs.irq_handler_exit, false);
222-
if (env.count)
223-
bpf_program__set_autoload(obj->progs.irq_handler_exit_btf, false);
224225
} else {
225226
bpf_program__set_autoload(obj->progs.irq_handler_entry_btf, false);
226227
bpf_program__set_autoload(obj->progs.irq_handler_exit_btf, false);
227-
if (env.count)
228-
bpf_program__set_autoload(obj->progs.irq_handler_exit, false);
229228
}
230229

230+
/* initialize global data (filtering options) */
231231
obj->rodata->filter_cg = env.cg;
232-
obj->rodata->do_count = env.count;
232+
obj->rodata->cpu = env.cpu;
233233
obj->rodata->targ_cpu = env.targ_cpu;
234-
235-
/* initialize global data (filtering options) */
236-
if (!env.count) {
237-
obj->rodata->targ_dist = env.distributed;
238-
obj->rodata->targ_ns = env.nanoseconds;
239-
}
234+
obj->rodata->targ_dist = env.distributed;
235+
obj->rodata->targ_ns = env.nanoseconds;
240236

241237
err = hardirqs_bpf__load(obj);
242238
if (err) {
@@ -267,10 +263,7 @@ int main(int argc, char **argv)
267263

268264
signal(SIGINT, sig_handler);
269265

270-
if (env.count)
271-
printf("Tracing hard irq events... Hit Ctrl-C to end.\n");
272-
else
273-
printf("Tracing hard irq event time... Hit Ctrl-C to end.\n");
266+
printf("Tracing hard irq event time... Hit Ctrl-C to end.\n");
274267

275268
/* main: poll */
276269
while (1) {

libbpf-tools/hardirqs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66

77
struct irq_key {
88
char name[32];
9+
__u32 cpu;
910
};
1011

1112
struct info {
1213
__u64 count;
14+
__u64 total_time;
15+
__u64 max_time;
1316
__u32 slots[MAX_SLOTS];
1417
};
1518

0 commit comments

Comments
 (0)