blob: 2d3141c4f551df4eae72690a89cc4d1ac5bf61af [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
16struct key_t {
17 u32 pid;
18};
19
20BPF_TABLE("hash", struct key_t, u64, start, 10240);
21BPF_TABLE("array", int, u64, dist, 64);
22
23static unsigned int log2(unsigned int v)
24{
25 unsigned int r;
26 unsigned int shift;
27
28 r = (v > 0xFFFF) << 4; v >>= r;
29 shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
30 shift = (v > 0xF) << 2; v >>= shift; r |= shift;
31 shift = (v > 0x3) << 1; v >>= shift; r |= shift;
32 r |= (v >> 1);
33 return r;
34}
35
36static unsigned int log2l(unsigned long v)
37{
38 unsigned int hi = v >> 32;
39 if (hi)
40 return log2(hi) + 32 + 1;
41 else
42 return log2(v) + 1;
43}
44
45int do_entry(struct pt_regs *ctx)
46{
47 struct key_t key = {};
48 u64 ts, *val, zero = 0;
49
50 key.pid = bpf_get_current_pid_tgid();
51 ts = bpf_ktime_get_ns();
52 start.update(&key, &ts);
53 return 0;
54}
55
56int do_return(struct pt_regs *ctx)
57{
58 struct key_t key = {};
59 u64 *tsp, delta;
60
61 key.pid = bpf_get_current_pid_tgid();
62 tsp = start.lookup(&key);
63
64 if (tsp != 0) {
65 delta = bpf_ktime_get_ns() - *tsp;
66 int index = log2l(delta / 1000);
67 u64 *leaf = dist.lookup(&index);
68 if (leaf) (*leaf)++;
69 start.delete(&key);
70 }
71
72 return 0;
73}