Skip to content

Commit 1cb0df5

Browse files
ethercflowyonghong-song
authored andcommitted
libbpf-tools: add offcputime
Signed-off-by: Wenbo Zhang <[email protected]>
1 parent d089013 commit 1cb0df5

File tree

9 files changed

+1125
-7
lines changed

9 files changed

+1125
-7
lines changed

libbpf-tools/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
/hardirqs
1616
/llcstat
1717
/numamove
18+
/offcputime
1819
/opensnoop
1920
/readahead
2021
/runqlat

libbpf-tools/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ APPS = \
3232
hardirqs \
3333
llcstat \
3434
numamove \
35+
offcputime \
3536
opensnoop \
3637
readahead \
3738
runqlat \

libbpf-tools/offcputime.bpf.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Copyright (c) 2021 Wenbo Zhang
3+
#include <vmlinux.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <bpf/bpf_core_read.h>
6+
#include <bpf/bpf_tracing.h>
7+
#include "offcputime.h"
8+
9+
#define PF_KTHREAD 0x00200000 /* I am a kernel thread */
10+
#define MAX_ENTRIES 10240
11+
12+
const volatile bool kernel_threads_only = false;
13+
const volatile bool user_threads_only = false;
14+
const volatile __u64 max_block_ns = -1;
15+
const volatile __u64 min_block_ns = 1;
16+
const volatile pid_t targ_tgid = -1;
17+
const volatile pid_t targ_pid = -1;
18+
const volatile long state = -1;
19+
20+
struct internal_key {
21+
u64 start_ts;
22+
struct key_t key;
23+
};
24+
25+
struct {
26+
__uint(type, BPF_MAP_TYPE_HASH);
27+
__type(key, u32);
28+
__type(value, struct internal_key);
29+
__uint(max_entries, MAX_ENTRIES);
30+
} start SEC(".maps");
31+
32+
struct {
33+
__uint(type, BPF_MAP_TYPE_STACK_TRACE);
34+
__uint(key_size, sizeof(u32));
35+
} stackmap SEC(".maps");
36+
37+
struct {
38+
__uint(type, BPF_MAP_TYPE_HASH);
39+
__type(key, struct key_t);
40+
__type(value, struct val_t);
41+
__uint(max_entries, MAX_ENTRIES);
42+
} info SEC(".maps");
43+
44+
static bool allow_record(struct task_struct *t)
45+
{
46+
if (targ_tgid != -1 && targ_tgid != t->tgid)
47+
return false;
48+
if (targ_pid != -1 && targ_pid != t->pid)
49+
return false;
50+
if (user_threads_only && t->flags & PF_KTHREAD)
51+
return false;
52+
else if (kernel_threads_only && !(t->flags & PF_KTHREAD))
53+
return false;
54+
if (state != -1 && t->state != state)
55+
return false;
56+
return true;
57+
}
58+
59+
SEC("tp_btf/sched_switch")
60+
int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev,
61+
struct task_struct *next)
62+
{
63+
struct internal_key *i_keyp, i_key;
64+
struct val_t *valp, val;
65+
s64 delta;
66+
u32 pid;
67+
68+
if (allow_record(prev)) {
69+
pid = prev->pid;
70+
/* To distinguish idle threads of different cores */
71+
if (!pid)
72+
pid = bpf_get_smp_processor_id();
73+
i_key.key.pid = pid;
74+
i_key.key.tgid = prev->tgid;
75+
i_key.start_ts = bpf_ktime_get_ns();
76+
77+
if (prev->flags & PF_KTHREAD)
78+
i_key.key.user_stack_id = -1;
79+
else
80+
i_key.key.user_stack_id =
81+
bpf_get_stackid(ctx, &stackmap,
82+
BPF_F_USER_STACK);
83+
i_key.key.kern_stack_id = bpf_get_stackid(ctx, &stackmap, 0);
84+
bpf_map_update_elem(&start, &pid, &i_key, 0);
85+
bpf_probe_read_str(&val.comm, sizeof(prev->comm), prev->comm);
86+
val.delta = 0;
87+
bpf_map_update_elem(&info, &i_key.key, &val, BPF_NOEXIST);
88+
}
89+
90+
pid = next->pid;
91+
i_keyp = bpf_map_lookup_elem(&start, &pid);
92+
if (!i_keyp)
93+
return 0;
94+
delta = (s64)(bpf_ktime_get_ns() - i_keyp->start_ts);
95+
if (delta < 0)
96+
goto cleanup;
97+
delta /= 1000U;
98+
if (delta < min_block_ns || delta > max_block_ns)
99+
goto cleanup;
100+
valp = bpf_map_lookup_elem(&info, &i_keyp->key);
101+
if (!valp)
102+
goto cleanup;
103+
__sync_fetch_and_add(&valp->delta, delta);
104+
105+
cleanup:
106+
bpf_map_delete_elem(&start, &pid);
107+
return 0;
108+
}
109+
110+
char LICENSE[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)