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