1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020 Wenbo Zhang
3 #include <vmlinux.h>
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_tracing.h>
6 #include "biopattern.h"
7 #include "maps.bpf.h"
8 #include "core_fixes.bpf.h"
9
10 const volatile bool filter_dev = false;
11 const volatile __u32 targ_dev = 0;
12
13 struct {
14 __uint(type, BPF_MAP_TYPE_HASH);
15 __uint(max_entries, 64);
16 __type(key, u32);
17 __type(value, struct counter);
18 } counters SEC(".maps");
19
20 SEC("tracepoint/block/block_rq_complete")
handle__block_rq_complete(void * args)21 int handle__block_rq_complete(void *args)
22 {
23 struct counter *counterp, zero = {};
24 sector_t sector;
25 u32 nr_sector;
26 u32 dev;
27
28 if (has_block_rq_completion()) {
29 struct trace_event_raw_block_rq_completion___x *ctx = args;
30 sector = BPF_CORE_READ(ctx, sector);
31 nr_sector = BPF_CORE_READ(ctx, nr_sector);
32 dev = BPF_CORE_READ(ctx, dev);
33 } else {
34 struct trace_event_raw_block_rq_complete___x *ctx = args;
35 sector = BPF_CORE_READ(ctx, sector);
36 nr_sector = BPF_CORE_READ(ctx, nr_sector);
37 dev = BPF_CORE_READ(ctx, dev);
38 }
39
40 if (filter_dev && targ_dev != dev)
41 return 0;
42
43 counterp = bpf_map_lookup_or_try_init(&counters, &dev, &zero);
44 if (!counterp)
45 return 0;
46 if (counterp->last_sector) {
47 if (counterp->last_sector == sector)
48 __sync_fetch_and_add(&counterp->sequential, 1);
49 else
50 __sync_fetch_and_add(&counterp->random, 1);
51 __sync_fetch_and_add(&counterp->bytes, nr_sector * 512);
52 }
53 counterp->last_sector = sector + nr_sector;
54 return 0;
55 }
56
57 char LICENSE[] SEC("license") = "GPL";
58