Commit c32b845d authored by Brendan Gregg's avatar Brendan Gregg Committed by Sasha Goldshtein

hardirqs: add --count for event counts (#1460)

parent 58b63ffe
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.SH NAME .SH NAME
hardirqs \- Measure hard IRQ (hard interrupt) event time. Uses Linux eBPF/bcc. hardirqs \- Measure hard IRQ (hard interrupt) event time. Uses Linux eBPF/bcc.
.SH SYNOPSIS .SH SYNOPSIS
.B hardirqs [\-h] [\-T] [\-N] [\-d] [interval] [count] .B hardirqs [\-h] [\-T] [\-N] [\-C] [\-d] [interval] [outputs]
.SH DESCRIPTION .SH DESCRIPTION
This summarizes the time spent servicing hard IRQs (hard interrupts), and can This summarizes the time spent servicing hard IRQs (hard interrupts), and can
show this time as either totals or histogram distributions. A system-wide show this time as either totals or histogram distributions. A system-wide
...@@ -25,10 +25,13 @@ Print usage message. ...@@ -25,10 +25,13 @@ Print usage message.
Include timestamps on output. Include timestamps on output.
.TP .TP
\-N \-N
Output in nanoseconds Output in nanoseconds.
.TP
\-C
Count events only.
.TP .TP
\-d \-d
Show IRQ time distribution as histograms Show IRQ time distribution as histograms.
.SH EXAMPLES .SH EXAMPLES
.TP .TP
Sum hard IRQ event time until Ctrl-C: Sum hard IRQ event time until Ctrl-C:
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# hardirqs Summarize hard IRQ (interrupt) event time. # hardirqs Summarize hard IRQ (interrupt) event time.
# For Linux, uses BCC, eBPF. # For Linux, uses BCC, eBPF.
# #
# USAGE: hardirqs [-h] [-T] [-Q] [-m] [-D] [interval] [count] # USAGE: hardirqs [-h] [-T] [-N] [-C] [-d] [interval] [outputs]
# #
# Thanks Amer Ather for help understanding irq behavior. # Thanks Amer Ather for help understanding irq behavior.
# #
...@@ -33,15 +33,23 @@ parser.add_argument("-T", "--timestamp", action="store_true", ...@@ -33,15 +33,23 @@ parser.add_argument("-T", "--timestamp", action="store_true",
help="include timestamp on output") help="include timestamp on output")
parser.add_argument("-N", "--nanoseconds", action="store_true", parser.add_argument("-N", "--nanoseconds", action="store_true",
help="output in nanoseconds") help="output in nanoseconds")
parser.add_argument("-C", "--count", action="store_true",
help="show event counts instead of timing")
parser.add_argument("-d", "--dist", action="store_true", parser.add_argument("-d", "--dist", action="store_true",
help="show distributions as histograms") help="show distributions as histograms")
parser.add_argument("interval", nargs="?", default=99999999, parser.add_argument("interval", nargs="?", default=99999999,
help="output interval, in seconds") help="output interval, in seconds")
parser.add_argument("count", nargs="?", default=99999999, parser.add_argument("outputs", nargs="?", default=99999999,
help="number of outputs") help="number of outputs")
args = parser.parse_args() args = parser.parse_args()
countdown = int(args.count) countdown = int(args.outputs)
if args.nanoseconds: if args.count and (args.dist or args.nanoseconds):
print("The --count option can't be used with time-based options")
exit()
if args.count:
factor = 1
label = "count"
elif args.nanoseconds:
factor = 1 factor = 1
label = "nsecs" label = "nsecs"
else: else:
...@@ -64,6 +72,22 @@ BPF_HASH(start, u32); ...@@ -64,6 +72,22 @@ BPF_HASH(start, u32);
BPF_HASH(irqdesc, u32, struct irq_desc *); BPF_HASH(irqdesc, u32, struct irq_desc *);
BPF_HISTOGRAM(dist, irq_key_t); BPF_HISTOGRAM(dist, irq_key_t);
// count IRQ
int count_only(struct pt_regs *ctx, struct irq_desc *desc)
{
u32 pid = bpf_get_current_pid_tgid();
struct irqaction *action = desc->action;
char *name = (char *)action->name;
irq_key_t key = {.slot = 0 /* ignore */};
bpf_probe_read(&key.name, sizeof(key.name), name);
u64 zero = 0, *vp = dist.lookup_or_init(&key, &zero);
(*vp)++;
return 0;
}
// time IRQ // time IRQ
int trace_start(struct pt_regs *ctx, struct irq_desc *desc) int trace_start(struct pt_regs *ctx, struct irq_desc *desc)
{ {
...@@ -119,10 +143,14 @@ if debug: ...@@ -119,10 +143,14 @@ if debug:
b = BPF(text=bpf_text) b = BPF(text=bpf_text)
# these should really use irq:irq_handler_entry/exit tracepoints: # these should really use irq:irq_handler_entry/exit tracepoints:
b.attach_kprobe(event="handle_irq_event_percpu", fn_name="trace_start") if args.count:
b.attach_kretprobe(event="handle_irq_event_percpu", fn_name="trace_completion") b.attach_kprobe(event="handle_irq_event_percpu", fn_name="count_only")
print("Tracing hard irq events... Hit Ctrl-C to end.")
print("Tracing hard irq event time... Hit Ctrl-C to end.") else:
b.attach_kprobe(event="handle_irq_event_percpu", fn_name="trace_start")
b.attach_kretprobe(event="handle_irq_event_percpu",
fn_name="trace_completion")
print("Tracing hard irq event time... Hit Ctrl-C to end.")
# output # output
exiting = 0 if args.interval else 1 exiting = 0 if args.interval else 1
......
...@@ -614,21 +614,55 @@ hardirq = 'resched3' ...@@ -614,21 +614,55 @@ hardirq = 'resched3'
2048 -> 4095 : 39 |* | 2048 -> 4095 : 39 |* |
Sometimes you just want counts of events, and don't need the distribution
of times. You can use the -C or --count option:
# ./hardirqs.py -C
Tracing hard irq events... Hit Ctrl-C to end.
^C
HARDIRQ TOTAL_count
blkif 2
callfuncsingle3 8
callfuncsingle2 10
callfuncsingle1 18
resched7 25
callfuncsingle6 25
callfuncsingle5 27
callfuncsingle0 27
eth0 34
resched2 40
resched1 66
timer7 70
resched6 71
resched0 73
resched5 79
resched4 90
timer6 95
timer4 100
timer1 109
timer2 115
timer0 117
timer3 123
resched3 140
timer5 288
USAGE message: USAGE message:
# ./hardirqs -h # ./hardirqs -h
usage: hardirqs [-h] [-T] [-N] [-d] [interval] [count] usage: hardirqs [-h] [-T] [-N] [-C] [-d] [interval] [outputs]
Summarize hard irq event time as histograms Summarize hard irq event time as histograms
positional arguments: positional arguments:
interval output interval, in seconds interval output interval, in seconds
count number of outputs outputs number of outputs
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-T, --timestamp include timestamp on output -T, --timestamp include timestamp on output
-N, --nanoseconds output in nanoseconds -N, --nanoseconds output in nanoseconds
-C, --count show event counts instead of timing
-d, --dist show distributions as histograms -d, --dist show distributions as histograms
examples: examples:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment