1*387f9dfdSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0 */
2*387f9dfdSAndroid Build Coastguard Worker /* Copyright (c) 2021 Hengqi Chen */
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_core_read.h>
6*387f9dfdSAndroid Build Coastguard Worker #include <bpf/bpf_tracing.h>
7*387f9dfdSAndroid Build Coastguard Worker #include "gethostlatency.h"
8*387f9dfdSAndroid Build Coastguard Worker
9*387f9dfdSAndroid Build Coastguard Worker #define MAX_ENTRIES 10240
10*387f9dfdSAndroid Build Coastguard Worker
11*387f9dfdSAndroid Build Coastguard Worker const volatile pid_t target_pid = 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, MAX_ENTRIES);
16*387f9dfdSAndroid Build Coastguard Worker __type(key, __u32);
17*387f9dfdSAndroid Build Coastguard Worker __type(value, struct event);
18*387f9dfdSAndroid Build Coastguard Worker } starts SEC(".maps");
19*387f9dfdSAndroid Build Coastguard Worker
20*387f9dfdSAndroid Build Coastguard Worker struct {
21*387f9dfdSAndroid Build Coastguard Worker __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
22*387f9dfdSAndroid Build Coastguard Worker __uint(key_size, sizeof(__u32));
23*387f9dfdSAndroid Build Coastguard Worker __uint(value_size, sizeof(__u32));
24*387f9dfdSAndroid Build Coastguard Worker } events SEC(".maps");
25*387f9dfdSAndroid Build Coastguard Worker
probe_entry(struct pt_regs * ctx)26*387f9dfdSAndroid Build Coastguard Worker static int probe_entry(struct pt_regs *ctx)
27*387f9dfdSAndroid Build Coastguard Worker {
28*387f9dfdSAndroid Build Coastguard Worker if (!PT_REGS_PARM1(ctx))
29*387f9dfdSAndroid Build Coastguard Worker return 0;
30*387f9dfdSAndroid Build Coastguard Worker
31*387f9dfdSAndroid Build Coastguard Worker __u64 pid_tgid = bpf_get_current_pid_tgid();
32*387f9dfdSAndroid Build Coastguard Worker __u32 pid = pid_tgid >> 32;
33*387f9dfdSAndroid Build Coastguard Worker __u32 tid = (__u32)pid_tgid;
34*387f9dfdSAndroid Build Coastguard Worker struct event event = {};
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Worker if (target_pid && target_pid != pid)
37*387f9dfdSAndroid Build Coastguard Worker return 0;
38*387f9dfdSAndroid Build Coastguard Worker
39*387f9dfdSAndroid Build Coastguard Worker event.time = bpf_ktime_get_ns();
40*387f9dfdSAndroid Build Coastguard Worker event.pid = pid;
41*387f9dfdSAndroid Build Coastguard Worker bpf_get_current_comm(&event.comm, sizeof(event.comm));
42*387f9dfdSAndroid Build Coastguard Worker bpf_probe_read_user(&event.host, sizeof(event.host), (void *)PT_REGS_PARM1(ctx));
43*387f9dfdSAndroid Build Coastguard Worker bpf_map_update_elem(&starts, &tid, &event, BPF_ANY);
44*387f9dfdSAndroid Build Coastguard Worker return 0;
45*387f9dfdSAndroid Build Coastguard Worker }
46*387f9dfdSAndroid Build Coastguard Worker
probe_return(struct pt_regs * ctx)47*387f9dfdSAndroid Build Coastguard Worker static int probe_return(struct pt_regs *ctx)
48*387f9dfdSAndroid Build Coastguard Worker {
49*387f9dfdSAndroid Build Coastguard Worker __u32 tid = (__u32)bpf_get_current_pid_tgid();
50*387f9dfdSAndroid Build Coastguard Worker struct event *eventp;
51*387f9dfdSAndroid Build Coastguard Worker
52*387f9dfdSAndroid Build Coastguard Worker eventp = bpf_map_lookup_elem(&starts, &tid);
53*387f9dfdSAndroid Build Coastguard Worker if (!eventp)
54*387f9dfdSAndroid Build Coastguard Worker return 0;
55*387f9dfdSAndroid Build Coastguard Worker
56*387f9dfdSAndroid Build Coastguard Worker /* update time from timestamp to delta */
57*387f9dfdSAndroid Build Coastguard Worker eventp->time = bpf_ktime_get_ns() - eventp->time;
58*387f9dfdSAndroid Build Coastguard Worker bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, eventp, sizeof(*eventp));
59*387f9dfdSAndroid Build Coastguard Worker bpf_map_delete_elem(&starts, &tid);
60*387f9dfdSAndroid Build Coastguard Worker return 0;
61*387f9dfdSAndroid Build Coastguard Worker }
62*387f9dfdSAndroid Build Coastguard Worker
63*387f9dfdSAndroid Build Coastguard Worker SEC("kprobe/handle_entry")
BPF_KPROBE(handle_entry)64*387f9dfdSAndroid Build Coastguard Worker int BPF_KPROBE(handle_entry)
65*387f9dfdSAndroid Build Coastguard Worker {
66*387f9dfdSAndroid Build Coastguard Worker return probe_entry(ctx);
67*387f9dfdSAndroid Build Coastguard Worker }
68*387f9dfdSAndroid Build Coastguard Worker
69*387f9dfdSAndroid Build Coastguard Worker SEC("kretprobe/handle_return")
BPF_KRETPROBE(handle_return)70*387f9dfdSAndroid Build Coastguard Worker int BPF_KRETPROBE(handle_return)
71*387f9dfdSAndroid Build Coastguard Worker {
72*387f9dfdSAndroid Build Coastguard Worker return probe_return(ctx);
73*387f9dfdSAndroid Build Coastguard Worker }
74*387f9dfdSAndroid Build Coastguard Worker
75*387f9dfdSAndroid Build Coastguard Worker char LICENSE[] SEC("license") = "GPL";
76