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
9 const volatile bool filter_dev = false;
10 const volatile __u32 targ_dev = 0;
11
12 struct {
13 __uint(type, BPF_MAP_TYPE_HASH);
14 __uint(max_entries, 64);
15 __type(key, u32);
16 __type(value, struct counter);
17 __uint(map_flags, BPF_F_NO_PREALLOC);
18 } counters SEC(".maps");
19
20 SEC("tracepoint/block/block_rq_complete")
handle__block_rq_complete(struct trace_event_raw_block_rq_complete * ctx)21 int handle__block_rq_complete(struct trace_event_raw_block_rq_complete *ctx)
22 {
23 sector_t sector = ctx->sector;
24 struct counter *counterp, zero = {};
25 u32 nr_sector = ctx->nr_sector;
26 u32 dev = ctx->dev;
27
28 if (filter_dev && targ_dev != dev)
29 return 0;
30
31 counterp = bpf_map_lookup_or_try_init(&counters, &dev, &zero);
32 if (!counterp)
33 return 0;
34 if (counterp->last_sector) {
35 if (counterp->last_sector == sector)
36 __sync_fetch_and_add(&counterp->sequential, 1);
37 else
38 __sync_fetch_and_add(&counterp->random, 1);
39 __sync_fetch_and_add(&counterp->bytes, nr_sector * 512);
40 }
41 counterp->last_sector = sector + nr_sector;
42 return 0;
43 }
44
45 char LICENSE[] SEC("license") = "GPL";
46