xref: /aosp_15_r20/external/bcc/libbpf-tools/biopattern.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
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