Skip to content

Commit 69013f3

Browse files
authored
Merge pull request #9 from beepfd/ghostbaby
feat: update Go version and enhance scheduling metrics
2 parents 2270ebb + c5f22d0 commit 69013f3

File tree

8 files changed

+84
-14
lines changed

8 files changed

+84
-14
lines changed

.github/workflows/push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- name: Install dependencies
1616
run: |
1717
sudo apt-get update && sudo apt-get install -y \
18-
golang-1.22 \
18+
golang-1.23 \
1919
git \
2020
make \
2121
gcc \

bpf/trace.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ extern int LINUX_KERNEL_VERSION __kconfig;
1515
// 定义数据结构来存储调度延迟信息
1616
struct sched_latency_t
1717
{
18-
__u32 pid; // 进程ID
19-
__u32 tid; // 线程ID
20-
__u64 delay_ns; // 调度延迟(纳秒)
21-
__u64 ts; // 时间戳
22-
__u32 preempted_pid; // 被抢占的进程ID
23-
char preempted_comm[16]; // 被抢占的进程名
24-
__u64 is_preempt; // 是否抢占(0: 否, 1: 是)
25-
char comm[16]; // 进程名
18+
__u32 pid; // 进程ID
19+
__u32 tid; // 线程ID
20+
__u64 delay_ns; // 调度延迟(纳秒)
21+
__u64 ts; // 时间戳
22+
__u32 preempted_pid; // 被抢占的进程ID
23+
char preempted_comm[16]; // 被抢占的进程名
24+
__u64 is_preempt; // 是否抢占(0: 否, 1: 是)
25+
char comm[16]; // 进程名
26+
__u32 preempted_pid_state; // 被抢占的进程状态
2627
} __attribute__((packed));
2728

2829
struct sched_latency_t *unused_sched_latency_t __attribute__((unused));
@@ -201,6 +202,7 @@ static __always_inline void handle_sched_switch(u32 prev_pid, u32 prev_tgid,
201202
.tid = next_pid,
202203
.delay_ns = delay,
203204
.ts = now,
205+
.preempted_pid_state = prev_state,
204206
};
205207

206208
bpf_probe_read_kernel_str(&latency.comm, sizeof(latency.comm), next_comm);

cmd/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ btf:
55
kernel: "/sys/kernel/btf/vmlinux"
66

77
output:
8-
type: file
8+
type: clickhouse
99
clickhouse:
1010
host: "192.168.200.201"
1111
port: "9000"

deploy/sql/clickhouse/sched.ck

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ CREATE TABLE shepherd.sched_latency
2020

2121
`date` Date DEFAULT today(),
2222

23+
`preempted_pid_state` UInt32,
24+
2325
`datetime` DateTime64(9) DEFAULT now64(9)
2426
)
2527
ENGINE = MergeTree

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module github.com/cen-ngc5139/shepherd
22

3-
go 1.22.4
4-
toolchain go1.24.1
3+
go 1.23.4
54

65
require (
76
github.com/ClickHouse/clickhouse-go/v2 v2.30.0

internal/output/output.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ func (o *Output) InitSinkCli(cfg config.OutputConfig) (err error) {
5858
INSERT INTO sched_latency (
5959
pid, tid, delay_ns, ts,
6060
preempted_pid, preempted_comm,
61-
is_preempt, comm
61+
is_preempt, comm,
62+
preempted_pid_state
6263
)
6364
`)
6465
if err != nil {

internal/output/sched_delay.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ func insertSchedMetrics(ctx context.Context, conn clickhouse.Conn, batch driver.
113113
sanitizeString(convertInt8ToString(event.PreemptedComm[:])),
114114
event.IsPreempt,
115115
sanitizeString(convertInt8ToString(event.Comm[:])),
116+
event.PreemptedPidState,
116117
)
117118
if err != nil {
118119
log.Errorf("failed to append to batch: %v", err)
@@ -132,7 +133,8 @@ func insertSchedMetrics(ctx context.Context, conn clickhouse.Conn, batch driver.
132133
INSERT INTO sched_latency (
133134
pid, tid, delay_ns, ts,
134135
preempted_pid, preempted_comm,
135-
is_preempt, comm
136+
is_preempt, comm,
137+
preempted_pid_state
136138
)
137139
`)
138140
if err != nil {

internal/output/utils.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,67 @@ func filterNonASCII(data []byte) string {
6767
func sanitizeString(s string) string {
6868
return strings.TrimSpace(s)
6969
}
70+
71+
72+
// 线程状态常量
73+
const (
74+
TASK_RUNNING = 0x00000000
75+
TASK_INTERRUPTIBLE = 0x00000001
76+
TASK_UNINTERRUPTIBLE = 0x00000002
77+
TASK_STOPPED = 0x00000004
78+
TASK_TRACED = 0x00000008
79+
EXIT_DEAD = 0x00000010
80+
EXIT_ZOMBIE = 0x00000020
81+
EXIT_TRACE = EXIT_ZOMBIE | EXIT_DEAD
82+
TASK_PARKED = 0x00000040
83+
TASK_DEAD = 0x00000080
84+
TASK_WAKEKILL = 0x00000100
85+
TASK_WAKING = 0x00000200
86+
TASK_NOLOAD = 0x00000400
87+
TASK_NEW = 0x00000800
88+
TASK_RTLOCK_WAIT = 0x00001000
89+
TASK_FREEZABLE = 0x00002000
90+
TASK_FREEZABLE_UNSAFE = 0x00004000 // 取决于: IS_ENABLED(CONFIG_LOCKDEP)
91+
TASK_FROZEN = 0x00008000
92+
TASK_STATE_MAX = 0x00010000 // 截至 Linux 内核 6.9
93+
)
94+
95+
// 任务状态映射表
96+
var taskStates = map[uint32]string{
97+
0x00000000: "R", // "RUNNING"
98+
0x00000001: "S", // "INTERRUPTIBLE"
99+
0x00000002: "D", // "UNINTERRUPTIBLE"
100+
0x00000004: "T", // "STOPPED"
101+
0x00000008: "t", // "TRACED"
102+
0x00000010: "X", // "EXIT_DEAD"
103+
0x00000020: "Z", // "EXIT_ZOMBIE"
104+
0x00000040: "P", // "PARKED"
105+
0x00000080: "dd", // "DEAD"
106+
0x00000100: "wk", // "WAKEKILL"
107+
0x00000200: "wg", // "WAKING"
108+
0x00000400: "I", // "NOLOAD"
109+
0x00000800: "N", // "NEW"
110+
0x00001000: "rt", // "RTLOCK_WAIT"
111+
0x00002000: "fe", // "FREEZABLE"
112+
0x00004000: "fu", // "__TASK_FREEZABLE_UNSAFE = (0x00004000 * IS_ENABLED(CONFIG_LOCKDEP))"
113+
0x00008000: "fo", // "FROZEN"
114+
}
115+
116+
// GetTaskStateName 将内核任务状态位掩码转换为可读字符串
117+
func GetTaskStateName(taskState uint32) string {
118+
if taskState == 0 {
119+
return "R"
120+
}
121+
if taskState&TASK_NOLOAD != 0 { // 空闲内核线程等待工作
122+
return "I"
123+
}
124+
125+
var names []string
126+
for state, name := range taskStates {
127+
if taskState&state != 0 {
128+
names = append(names, name)
129+
}
130+
}
131+
132+
return strings.Join(names, "+")
133+
}

0 commit comments

Comments
 (0)