tools/softirqs: Add event counting support
diff --git a/man/man8/softirqs.8 b/man/man8/softirqs.8
index 408c5a0..fa475f7 100644
--- a/man/man8/softirqs.8
+++ b/man/man8/softirqs.8
@@ -2,7 +2,7 @@
.SH NAME
softirqs \- Measure soft IRQ (soft interrupt) event time. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B softirqs [\-h] [\-T] [\-N] [\-d] [interval] [count]
+.B softirqs [\-h] [\-T] [\-N] [\-C] [\-d] [\-c CPU] [interval] [count]
.SH DESCRIPTION
This summarizes the time spent servicing soft IRQs (soft interrupts), and can
show this time as either totals or histogram distributions. A system-wide
@@ -26,10 +26,13 @@
Include timestamps on output.
.TP
\-N
-Output in nanoseconds
+Output in nanoseconds.
+.TP
+\-C
+Show the number of soft irq events.
.TP
\-d
-Show IRQ time distribution as histograms
+Show IRQ time distribution as histograms.
.TP
\-c CPU
Trace on this CPU only.
@@ -39,6 +42,10 @@
#
.B softirqs
.TP
+Show the number of soft irq events:
+#
+.B softirqs \-C
+.TP
Show soft IRQ event time as histograms:
#
.B softirqs \-d
diff --git a/tools/softirqs.py b/tools/softirqs.py
index 2186277..0ed18c4 100755
--- a/tools/softirqs.py
+++ b/tools/softirqs.py
@@ -4,7 +4,7 @@
# softirqs Summarize soft IRQ (interrupt) event time.
# For Linux, uses BCC, eBPF.
#
-# USAGE: softirqs [-h] [-T] [-N] [-d] [-c CPU] [interval] [count]
+# USAGE: softirqs [-h] [-T] [-N] [-C] [-d] [-c CPU] [interval] [count]
#
# Copyright (c) 2015 Brendan Gregg.
# Licensed under the Apache License, Version 2.0 (the "License")
@@ -12,6 +12,7 @@
# 20-Oct-2015 Brendan Gregg Created this.
# 03-Apr-2017 Sasha Goldshtein Migrated to kernel tracepoints.
# 07-Mar-2022 Rocky Xing Added CPU filter support.
+# 24-Mar-2022 Rocky Xing Added event counting support.
from __future__ import print_function
from bcc import BPF
@@ -22,6 +23,7 @@
# arguments
examples = """examples:
./softirqs # sum soft irq event time
+ ./softirqs -C # show the number of soft irq events
./softirqs -d # show soft irq event time as histograms
./softirqs 1 10 # print 1 second summaries, 10 times
./softirqs -NT 1 # 1s summaries, nanoseconds, and timestamps
@@ -35,6 +37,8 @@
help="include timestamp on output")
parser.add_argument("-N", "--nanoseconds", action="store_true",
help="output in nanoseconds")
+parser.add_argument("-C", "--events", action="store_true",
+ help="show the number of soft irq events")
parser.add_argument("-d", "--dist", action="store_true",
help="show distributions as histograms")
parser.add_argument("-c", "--cpu", type=int,
@@ -47,7 +51,13 @@
help=argparse.SUPPRESS)
args = parser.parse_args()
countdown = int(args.count)
-if args.nanoseconds:
+if args.events and (args.dist or args.nanoseconds):
+ print("The --events option can't be used with time-based options")
+ exit()
+if args.events:
+ factor = 1
+ label = "count"
+elif args.nanoseconds:
factor = 1
label = "nsecs"
else:
@@ -76,7 +86,25 @@
BPF_HASH(start, entry_key_t, account_val_t);
BPF_HISTOGRAM(dist, irq_key_t);
+"""
+bpf_text_count = """
+TRACEPOINT_PROBE(irq, softirq_entry)
+{
+ u32 cpu = bpf_get_smp_processor_id();
+
+ FILTER_CPU
+
+ irq_key_t key = { .slot = 0 /* ignore */ };
+ key.vec = args->vec;
+
+ dist.atomic_increment(key);
+
+ return 0;
+}
+"""
+
+bpf_text_time = """
TRACEPOINT_PROBE(irq, softirq_entry)
{
account_val_t val = {};
@@ -125,6 +153,11 @@
}
"""
+if args.events:
+ bpf_text += bpf_text_count
+else:
+ bpf_text += bpf_text_time
+
# code substitutions
if args.dist:
bpf_text = bpf_text.replace('STORE',
@@ -153,7 +186,10 @@
return ["hi", "timer", "net_tx", "net_rx", "block", "irq_poll",
"tasklet", "sched", "hrtimer", "rcu"][vec]
-print("Tracing soft irq event time... Hit Ctrl-C to end.")
+if args.events:
+ print("Tracing soft irq events... Hit Ctrl-C to end.")
+else:
+ print("Tracing soft irq event time... Hit Ctrl-C to end.")
# output
exiting = 0 if args.interval else 1
diff --git a/tools/softirqs_example.txt b/tools/softirqs_example.txt
index ef3174a..a914143 100644
--- a/tools/softirqs_example.txt
+++ b/tools/softirqs_example.txt
@@ -179,12 +179,27 @@
16384 -> 32767 : 24 |** |
+Sometimes you just want counts of events, and don't need the distribution
+of times. You can use the -C or --events option:
+
+# ./softirqs.py -C
+Tracing soft irq events... Hit Ctrl-C to end.
+^C
+SOFTIRQ TOTAL_count
+block 5
+tasklet 6
+net_rx 402
+sched 5251
+rcu 5748
+timer 9530
+
+
USAGE message:
# ./softirqs -h
-usage: softirqs [-h] [-T] [-N] [-d] [interval] [count]
+usage: softirqs [-h] [-T] [-N] [-C] [-d] [-c CPU] [interval] [count]
-Summarize soft irq event time as histograms
+Summarize soft irq event time as histograms.
positional arguments:
interval output interval, in seconds
@@ -194,10 +209,15 @@
-h, --help show this help message and exit
-T, --timestamp include timestamp on output
-N, --nanoseconds output in nanoseconds
+ -C, --events show the number of soft irq events
-d, --dist show distributions as histograms
+ -c CPU, --cpu CPU trace this CPU only
examples:
./softirqs # sum soft irq event time
+ ./softirqs -C # show the number of soft irq events
./softirqs -d # show soft irq event time as histograms
./softirqs 1 10 # print 1 second summaries, 10 times
./softirqs -NT 1 # 1s summaries, nanoseconds, and timestamps
+ ./softirqs -c 1 # sum soft irq event time on CPU 1 only
+