Commit 43cfc13b authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 0f3e7237
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# pinglat - estimate upper bound for local and remote ICMP ECHO software processing latency # pinglat - estimate upper bound for local ICMP ECHO software processing latency
from bcc import BPF from bcc import BPF
from time import sleep from time import sleep
# name of interface we are tracing on # name of interface we are tracing on
ifname="eth0" ifname="eth0"
#icmp_echo_ip = BPF.ksymname("icmp_echo")
#assert icmp_echo_ip != -1
prog = r""" prog = r"""
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/icmp.h> #include <linux/icmp.h>
...@@ -22,22 +19,17 @@ struct event { ...@@ -22,22 +19,17 @@ struct event {
// we take conservative approach and start counting time from the first ) // we take conservative approach and start counting time from the first )
u64 techo; // t when it got to icmp_echo u64 techo; // t when it got to icmp_echo
// u64 techo_reply; // t when icmp_echo finished (it calls icmp_reply inside) //u64 techo_reply; // t when icmp_echo finished (it calls icmp_reply inside)
// we do not need to store it as this is the last point of the event
}; };
BPF_ARRAY(event, struct event, 1); // current in-flight event BPF_ARRAY(event, struct event, 1); // current in-flight event
// BPF_ARRAY(tlastint, u64, 1); // t of last interrupt on iface
// BPF_ARRAY(tlastecho, u64, 1); // t of last icmp_echo
BPF_HISTOGRAM(dist_dt_int_echo); // dt int - icmp_echo BPF_HISTOGRAM(dist_dt_int_echo); // dt int - icmp_echo
BPF_HISTOGRAM(dist_dt_echo_tx); // dt icmp_echo - tx BPF_HISTOGRAM(dist_dt_echo_tx); // dt icmp_echo - tx
BPF_HISTOGRAM(dist_dt_int_tx); // dt int - tx BPF_HISTOGRAM(dist_dt_int_tx); // dt int - tx
BPF_HISTOGRAM(dist_nint); BPF_HISTOGRAM(dist_nint);
// // for determining call stack in net_dev_xmit; 1024 - not 1 - because calls can be done concurrently
// BPF_STACK_TRACE(traceback, 1024);
// # out-of-sync events // # out-of-sync events
// 1 - missed interrupt // 1 - missed interrupt
// 2 - second icmp_echo without processing for first completed // 2 - second icmp_echo without processing for first completed
...@@ -60,11 +52,6 @@ prog += r""" ...@@ -60,11 +52,6 @@ prog += r"""
int z=0; struct event zev = {}; int z=0; struct event zev = {};
struct event *ev = event.lookup_or_init(&z, &zev); struct event *ev = event.lookup_or_init(&z, &zev);
//if (ev->tint != 0) {
// // interrupt came but icmp_echo not yet handled
// ev->nint++;
// return 0;
//}
ev->tint = ts; // t of _last_ interrupt ev->tint = ts; // t of _last_ interrupt
ev->nint++; // verifying it is sane (e.g. =2 means TXintr RXintr icmp_echo icmp_reply TXintr RXintr ... ev->nint++; // verifying it is sane (e.g. =2 means TXintr RXintr icmp_echo icmp_reply TXintr RXintr ...
...@@ -94,15 +81,6 @@ int kprobe__icmp_echo(struct pt_regs *ctx, struct sk_buff *skb) { ...@@ -94,15 +81,6 @@ int kprobe__icmp_echo(struct pt_regs *ctx, struct sk_buff *skb) {
ev->techo = ts; ev->techo = ts;
// update t(int) - t(icmp_echo) along the way
//struct icmphdr h;
//bpf_probe_read(&h, sizeof(h), skb->head + skb->transport_header); // = icmp_hdr(skb)
//u64 tint = *tlastint.lookup_or_init(&z, &z64);
//u64 dt = ts - tint;
//dist_dt_int_echo.increment(bpf_log2l(dt / (u64)(1E3)));
//bpf_trace_printk("ping id: %d seq: %d dint: %dns\n", h.un.echo.id, h.un.echo.sequence, ts - tint); //bpf_trace_printk("ping id: %d seq: %d dint: %dns\n", h.un.echo.id, h.un.echo.sequence, ts - tint);
return 0; return 0;
} }
...@@ -144,60 +122,7 @@ int kretprobe__icmp_echo(struct pt_regs *ctx) { ...@@ -144,60 +122,7 @@ int kretprobe__icmp_echo(struct pt_regs *ctx) {
} }
""" """
# # devname != ifname -> return
# prog += " char c;\n"
# for i, c in enumerate(ifname):
# prog += " bpf_probe_read(&c, 1, &devname[%d]); if (c != '%s') return 0;\n" % (i, c)
#
#
# prog += r"""
# // make sure tx is called from under icmp_echo - if not - ignore
# // 0 0 swapper/1 net_dev_xmit
# // dev_hard_start_xmit+0x123 [kernel]
# // dev_hard_start_xmit+0x123 [kernel]
# // sch_direct_xmit+0xf1 [kernel]
# // __dev_queue_xmit+0x45a [kernel]
# // ip_finish_output2+0x2a8 [kernel]
# // ip_output+0x72 [kernel]
# // ip_output+0x72 [kernel]
# // ip_send_skb+0x15 [kernel]
# // icmp_reply.constprop.25+0x24f [kernel]
# // icmp_echo.part.23+0x5e [kernel]
# // skb_checksum+0x32 [kernel]
# // csum_partial_ext+0x0 [kernel]
# // csum_block_add_ext+0x0 [kernel]
# // __skb_checksum_complete+0x1c [kernel]
# // icmp_echo+0x27 [kernel] <--
# // icmp_rcv+0x26f [kernel]
# int stkid = traceback.get_stackid(args, 14 | BPF_F_REUSE_STACKID); // XXX recheck 14 skip, fragile
# if (stkid < 0) {
# return 0; // error
# }
#
# struct bpf_stacktrace *tb;
# tb = traceback.lookup(&stkid);
# if (!(ICMP_ECHO_IP <= tb->ip[0] && tb->ip[0] < ICMP_ECHO_IP + 0x40)) { // XXX fragile
# return 0; // called not from under icmp_echo
# }
#
# bpf_trace_printk("net tx from under icmp_echo\n");
# return 0;
#
#
# int z=0; u64 z64=0;
# u64 ts = bpf_ktime_get_ns();
#
# u64 dtint = ts - *tlastint.lookup_or_init(&z, &z64);
# u64 dtecho = ts - *tlastecho.lookup_or_init(&z, &z64);
#
# dist_dt_echo_tx.increment(bpf_log2l(dtecho / (u64)(1E3)));
# dist_dt_int_tx .increment(bpf_log2l(dtint / (u64)(1E3)));
#
# return 0;
# }
# """
prog = prog.replace("IFNAME", ifname) prog = prog.replace("IFNAME", ifname)
#prog = prog.replace("ICMP_ECHO_IP", "0x%x" % icmp_echo_ip)
#print prog #print prog
......
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