-
Notifications
You must be signed in to change notification settings - Fork 1
/
bio.c
83 lines (69 loc) · 1.81 KB
/
bio.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
* biostat.c count I/O
* For Linux, uses BCC, eBPF. See the Python front-end.
*
* USAGE: biostat.py
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*
*/
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>
enum stat_types {
S_MAXSTAT
};
struct key_t {
u64 ip;
u64 tp;
char disk_name[DISK_NAME_LEN];
u64 rblk;
u64 wblk;
u64 wsvc;
u64 rsvc;
};
//BPF_TABLE("hash", struct key_t, u64, counts, 256);
BPF_HASH(counts,struct key_t);
BPF_HASH(start, struct request *);
// time block I/O
int trace_req_start(struct pt_regs *ctx, struct request *req)
{
u64 ts;
ts = bpf_ktime_get_ns();
start.update(&req, &ts);
return 0;
}
int do_count(struct pt_regs *ctx , struct request *req) {
struct key_t key = {};
u64 zero = 0, *val, *val2;
u64 reads = 0;
unsigned int a;
u64 delta;
u64 *tsp;
int *b;
key.ip = ctx->ip;
tsp = start.lookup(&req);
if (tsp == 0) {
// missed tracing issue
return 0;
}
delta = (bpf_ktime_get_ns() - *tsp) /1000000;
if (req->cmd_flags & REQ_WRITE) {
key.tp=1;
a=req->__data_len;
key.wblk=a;
key.wsvc = delta;
bpf_probe_read(&key.disk_name,sizeof(key.disk_name),req->rq_disk->disk_name);
} else {
key.tp=2;
a=req->__data_len;
key.rblk=a;
key.rsvc=delta;
bpf_probe_read(&key.disk_name,sizeof(key.disk_name),req->rq_disk->disk_name);
}
start.delete(&req);
val = counts.lookup_or_init(&key, &reads);
(*val)++;
return 0;
}