Created
October 19, 2015 20:44
-
-
Save brendangregg/a4a2c19b6206e205d540 to your computer and use it in GitHub Desktop.
irqdist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# | |
# irqdist Summarize irq event time as a histogram. | |
# For Linux, uses BCC, eBPF. | |
# | |
# USAGE: irqdist [-h] [-T] [-Q] [-m] [-D] [interval] [count] | |
# | |
# Copyright (c) 2015 Brendan Gregg. | |
# Licensed under the Apache License, Version 2.0 (the "License") | |
# | |
# 19-Oct-2015 Brendan Gregg Created this. | |
from __future__ import print_function | |
from bcc import BPF | |
from time import sleep, strftime | |
import argparse | |
### arguments | |
examples = """examples: | |
./irqdist # summarize irq event time as histograms | |
./irqdist 1 10 # print 1 second summaries, 10 times | |
./irqdist -mT 1 # 1s summaries, milliseconds, and timestamps | |
""" | |
parser = argparse.ArgumentParser( | |
description="Summarize irq event time as histograms", | |
formatter_class=argparse.RawDescriptionHelpFormatter, | |
epilog=examples) | |
parser.add_argument("-T", "--timestamp", action="store_true", | |
help="include timestamp on output") | |
parser.add_argument("-m", "--milliseconds", action="store_true", | |
help="millisecond histogram") | |
parser.add_argument("interval", nargs="?", default=99999999, | |
help="output interval, in seconds") | |
parser.add_argument("count", nargs="?", default=99999999, | |
help="number of outputs") | |
args = parser.parse_args() | |
countdown = int(args.count) | |
debug = 0 | |
### define BPF program | |
bpf_text = """ | |
#include <uapi/linux/ptrace.h> | |
#include <linux/irq.h> | |
#include <linux/irqdesc.h> | |
#include <linux/interrupt.h> | |
typedef struct irq_key { | |
char name[32]; | |
u64 slot; | |
} irq_key_t; | |
BPF_HASH(start, u32); | |
BPF_HASH(irqdesc, u32, struct irq_desc *); | |
BPF_HISTOGRAM(dist, irq_key_t); | |
// time IRQ | |
int trace_start(struct pt_regs *ctx, struct irq_desc *desc) | |
{ | |
u32 pid = bpf_get_current_pid_tgid(); | |
u64 ts = bpf_ktime_get_ns(); | |
start.update(&pid, &ts); | |
irqdesc.update(&pid, &desc); | |
return 0; | |
} | |
int trace_completion(struct pt_regs *ctx) | |
{ | |
u64 *tsp, delta; | |
struct irq_desc **descp; | |
u32 pid = bpf_get_current_pid_tgid(); | |
// fetch timestamp and calculate delta | |
tsp = start.lookup(&pid); | |
descp = irqdesc.lookup(&pid); | |
if (tsp == 0 || descp == 0) { | |
return 0; // missed start | |
} | |
delta = bpf_ktime_get_ns() - *tsp; | |
FACTOR | |
// store as histogram | |
irq_key_t key = {.slot = bpf_log2l(delta)}; | |
struct irq_desc *desc = *descp; | |
bpf_probe_read(&key.name, sizeof(key.name), (void *)desc->name); | |
dist.increment(key); | |
start.delete(&pid); | |
irqdesc.delete(&pid); | |
return 0; | |
} | |
""" | |
### code substitutions | |
if args.milliseconds: | |
bpf_text = bpf_text.replace('FACTOR', 'delta /= 1000000;') | |
label = "msecs" | |
else: | |
bpf_text = bpf_text.replace('FACTOR', 'delta /= 1000;') | |
label = "usecs" | |
if debug: | |
print(bpf_text) | |
### load BPF program | |
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 irq event time... Hit Ctrl-C to end.") | |
### output | |
exiting = 0 if args.interval else 1 | |
dist = b.get_table("dist") | |
while (1): | |
try: | |
sleep(int(args.interval)) | |
except KeyboardInterrupt: | |
exiting=1 | |
print() | |
if args.timestamp: | |
print("%-8s\n" % strftime("%H:%M:%S"), end="") | |
dist.print_log2_hist(label, "interrupt") | |
dist.clear() | |
countdown -= 1 | |
if exiting or countdown == 0: | |
exit() |
drzaeus77
commented
Oct 20, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment