Skip to content

Commit

Permalink
hardirqs: add --count for event counts (iovisor#1460)
Browse files Browse the repository at this point in the history
  • Loading branch information
brendangregg authored and goldshtn committed Nov 27, 2017
1 parent 58b63ff commit c32b845
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 13 deletions.
9 changes: 6 additions & 3 deletions man/man8/hardirqs.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.SH NAME
hardirqs \- Measure hard IRQ (hard interrupt) event time. Uses Linux eBPF/bcc.
.SH SYNOPSIS
.B hardirqs [\-h] [\-T] [\-N] [\-d] [interval] [count]
.B hardirqs [\-h] [\-T] [\-N] [\-C] [\-d] [interval] [outputs]
.SH DESCRIPTION
This summarizes the time spent servicing hard IRQs (hard interrupts), and can
show this time as either totals or histogram distributions. A system-wide
Expand All @@ -25,10 +25,13 @@ Print usage message.
Include timestamps on output.
.TP
\-N
Output in nanoseconds
Output in nanoseconds.
.TP
\-C
Count events only.
.TP
\-d
Show IRQ time distribution as histograms
Show IRQ time distribution as histograms.
.SH EXAMPLES
.TP
Sum hard IRQ event time until Ctrl-C:
Expand Down
44 changes: 36 additions & 8 deletions tools/hardirqs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# hardirqs Summarize hard IRQ (interrupt) event time.
# 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.
#
Expand Down Expand Up @@ -33,15 +33,23 @@
help="include timestamp on output")
parser.add_argument("-N", "--nanoseconds", action="store_true",
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",
help="show distributions as histograms")
parser.add_argument("interval", nargs="?", default=99999999,
help="output interval, in seconds")
parser.add_argument("count", nargs="?", default=99999999,
parser.add_argument("outputs", nargs="?", default=99999999,
help="number of outputs")
args = parser.parse_args()
countdown = int(args.count)
if args.nanoseconds:
countdown = int(args.outputs)
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
label = "nsecs"
else:
Expand All @@ -64,6 +72,22 @@
BPF_HASH(irqdesc, u32, struct irq_desc *);
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
int trace_start(struct pt_regs *ctx, struct irq_desc *desc)
{
Expand Down Expand Up @@ -119,10 +143,14 @@
b = BPF(text=bpf_text)

# these should really use irq:irq_handler_entry/exit tracepoints:
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.")
if args.count:
b.attach_kprobe(event="handle_irq_event_percpu", fn_name="count_only")
print("Tracing hard irq events... 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
exiting = 0 if args.interval else 1
Expand Down
38 changes: 36 additions & 2 deletions tools/hardirqs_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -614,21 +614,55 @@ hardirq = 'resched3'
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:

# ./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

positional arguments:
interval output interval, in seconds
count number of outputs
outputs number of outputs

optional arguments:
-h, --help show this help message and exit
-T, --timestamp include timestamp on output
-N, --nanoseconds output in nanoseconds
-C, --count show event counts instead of timing
-d, --dist show distributions as histograms

examples:
Expand Down

0 comments on commit c32b845

Please sign in to comment.