blob: 6d741070ec735831b4728d8569e6525a9f52dddd [file] [log] [blame]
Brendan Gregg48fbc3e2015-08-18 14:56:14 -07001/*
2 * vfsreadlat.c VFS read latency distribution.
3 * For Linux, uses BCC, eBPF. See .py file.
4 *
5 * Based on eBPF sample tracex2 by Alexi Starovoitov.
6 * Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU General Public
9 * License as published by the Free Software Foundation.
10 *
11 * 15-Aug-2015 Brendan Gregg Created this.
12 */
13
14#include <uapi/linux/ptrace.h>
15
Brendan Greggf92e6682015-09-10 11:34:28 -070016BPF_HASH(start, u32);
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070017BPF_TABLE("array", int, u64, dist, 64);
18
19static unsigned int log2(unsigned int v)
20{
21 unsigned int r;
22 unsigned int shift;
23
24 r = (v > 0xFFFF) << 4; v >>= r;
25 shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
26 shift = (v > 0xF) << 2; v >>= shift; r |= shift;
27 shift = (v > 0x3) << 1; v >>= shift; r |= shift;
28 r |= (v >> 1);
29 return r;
30}
31
32static unsigned int log2l(unsigned long v)
33{
34 unsigned int hi = v >> 32;
35 if (hi)
36 return log2(hi) + 32 + 1;
37 else
38 return log2(v) + 1;
39}
40
41int do_entry(struct pt_regs *ctx)
42{
Brendan Greggf92e6682015-09-10 11:34:28 -070043 u32 pid;
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070044 u64 ts, *val, zero = 0;
45
Brendan Greggf92e6682015-09-10 11:34:28 -070046 pid = bpf_get_current_pid_tgid();
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070047 ts = bpf_ktime_get_ns();
Brendan Greggf92e6682015-09-10 11:34:28 -070048 start.update(&pid, &ts);
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070049 return 0;
50}
51
52int do_return(struct pt_regs *ctx)
53{
Brendan Greggf92e6682015-09-10 11:34:28 -070054 u32 pid;
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070055 u64 *tsp, delta;
56
Brendan Greggf92e6682015-09-10 11:34:28 -070057 pid = bpf_get_current_pid_tgid();
58 tsp = start.lookup(&pid);
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070059
60 if (tsp != 0) {
61 delta = bpf_ktime_get_ns() - *tsp;
62 int index = log2l(delta / 1000);
63 u64 *leaf = dist.lookup(&index);
64 if (leaf) (*leaf)++;
Brendan Greggf92e6682015-09-10 11:34:28 -070065 start.delete(&pid);
Brendan Gregg48fbc3e2015-08-18 14:56:14 -070066 }
67
68 return 0;
69}