From 06a4f0a187031e1590b75a7f65ae7947b573536c Mon Sep 17 00:00:00 2001 From: zhuhuijun Date: Mon, 12 May 2025 14:58:00 +0800 Subject: [PATCH 1/2] feat: update Go version and enhance scheduling metrics - Updated Go version in `go.mod` from 1.22.4 to 1.23.4 for improved performance and compatibility. - Added `preempted_pid_state` field to the `sched_latency_t` structure in `trace.c` for better tracking of process states. - Modified SQL schema in `sched.ck` to include the new `preempted_pid_state` column. - Updated output handling in `output.go` and `sched_delay.go` to accommodate the new field in database inserts. - Introduced task state constants and a mapping function in `utils.go` for enhanced task state management. --- .github/workflows/push.yml | 2 +- bpf/trace.c | 18 +++++----- cmd/config.yaml | 2 +- deploy/sql/clickhouse/sched.ck | 2 ++ go.mod | 2 +- internal/output/output.go | 3 +- internal/output/sched_delay.go | 4 ++- internal/output/utils.go | 64 ++++++++++++++++++++++++++++++++++ 8 files changed, 84 insertions(+), 13 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index c022f02..c40a060 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -15,7 +15,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update && sudo apt-get install -y \ - golang-1.22 \ + golang-1.23 \ git \ make \ gcc \ diff --git a/bpf/trace.c b/bpf/trace.c index da8fbf8..b36183f 100644 --- a/bpf/trace.c +++ b/bpf/trace.c @@ -15,14 +15,15 @@ extern int LINUX_KERNEL_VERSION __kconfig; // 定义数据结构来存储调度延迟信息 struct sched_latency_t { - __u32 pid; // 进程ID - __u32 tid; // 线程ID - __u64 delay_ns; // 调度延迟(纳秒) - __u64 ts; // 时间戳 - __u32 preempted_pid; // 被抢占的进程ID - char preempted_comm[16]; // 被抢占的进程名 - __u64 is_preempt; // 是否抢占(0: 否, 1: 是) - char comm[16]; // 进程名 + __u32 pid; // 进程ID + __u32 tid; // 线程ID + __u64 delay_ns; // 调度延迟(纳秒) + __u64 ts; // 时间戳 + __u32 preempted_pid; // 被抢占的进程ID + char preempted_comm[16]; // 被抢占的进程名 + __u64 is_preempt; // 是否抢占(0: 否, 1: 是) + char comm[16]; // 进程名 + __u32 preempted_pid_state; // 被抢占的进程状态 } __attribute__((packed)); 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, .tid = next_pid, .delay_ns = delay, .ts = now, + .preempted_pid_state = prev_state, }; bpf_probe_read_kernel_str(&latency.comm, sizeof(latency.comm), next_comm); diff --git a/cmd/config.yaml b/cmd/config.yaml index e7c9fbe..6d04848 100644 --- a/cmd/config.yaml +++ b/cmd/config.yaml @@ -5,7 +5,7 @@ btf: kernel: "/sys/kernel/btf/vmlinux" output: - type: file + type: clickhouse clickhouse: host: "192.168.200.201" port: "9000" diff --git a/deploy/sql/clickhouse/sched.ck b/deploy/sql/clickhouse/sched.ck index ad56c3e..05dc0dd 100644 --- a/deploy/sql/clickhouse/sched.ck +++ b/deploy/sql/clickhouse/sched.ck @@ -20,6 +20,8 @@ CREATE TABLE shepherd.sched_latency `date` Date DEFAULT today(), + `preempted_pid_state` UInt32, + `datetime` DateTime64(9) DEFAULT now64(9) ) ENGINE = MergeTree diff --git a/go.mod b/go.mod index a85a30c..8a193fe 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cen-ngc5139/shepherd -go 1.22.4 +go 1.23.4 require ( github.com/ClickHouse/clickhouse-go/v2 v2.30.0 diff --git a/internal/output/output.go b/internal/output/output.go index 2f457f5..28bdc10 100644 --- a/internal/output/output.go +++ b/internal/output/output.go @@ -58,7 +58,8 @@ func (o *Output) InitSinkCli(cfg config.OutputConfig) (err error) { INSERT INTO sched_latency ( pid, tid, delay_ns, ts, preempted_pid, preempted_comm, - is_preempt, comm + is_preempt, comm, + preempted_pid_state ) `) if err != nil { diff --git a/internal/output/sched_delay.go b/internal/output/sched_delay.go index 8a849b4..a7529d2 100644 --- a/internal/output/sched_delay.go +++ b/internal/output/sched_delay.go @@ -113,6 +113,7 @@ func insertSchedMetrics(ctx context.Context, conn clickhouse.Conn, batch driver. sanitizeString(convertInt8ToString(event.PreemptedComm[:])), event.IsPreempt, sanitizeString(convertInt8ToString(event.Comm[:])), + event.PreemptedPidState, ) if err != nil { log.Errorf("failed to append to batch: %v", err) @@ -132,7 +133,8 @@ func insertSchedMetrics(ctx context.Context, conn clickhouse.Conn, batch driver. INSERT INTO sched_latency ( pid, tid, delay_ns, ts, preempted_pid, preempted_comm, - is_preempt, comm + is_preempt, comm, + preempted_pid_state ) `) if err != nil { diff --git a/internal/output/utils.go b/internal/output/utils.go index 87e4358..4c3a2db 100644 --- a/internal/output/utils.go +++ b/internal/output/utils.go @@ -67,3 +67,67 @@ func filterNonASCII(data []byte) string { func sanitizeString(s string) string { return strings.TrimSpace(s) } + + +// 线程状态常量 +const ( + TASK_RUNNING = 0x00000000 + TASK_INTERRUPTIBLE = 0x00000001 + TASK_UNINTERRUPTIBLE = 0x00000002 + TASK_STOPPED = 0x00000004 + TASK_TRACED = 0x00000008 + EXIT_DEAD = 0x00000010 + EXIT_ZOMBIE = 0x00000020 + EXIT_TRACE = EXIT_ZOMBIE | EXIT_DEAD + TASK_PARKED = 0x00000040 + TASK_DEAD = 0x00000080 + TASK_WAKEKILL = 0x00000100 + TASK_WAKING = 0x00000200 + TASK_NOLOAD = 0x00000400 + TASK_NEW = 0x00000800 + TASK_RTLOCK_WAIT = 0x00001000 + TASK_FREEZABLE = 0x00002000 + TASK_FREEZABLE_UNSAFE = 0x00004000 // 取决于: IS_ENABLED(CONFIG_LOCKDEP) + TASK_FROZEN = 0x00008000 + TASK_STATE_MAX = 0x00010000 // 截至 Linux 内核 6.9 +) + +// 任务状态映射表 +var taskStates = map[uint32]string{ + 0x00000000: "R", // "RUNNING" + 0x00000001: "S", // "INTERRUPTIBLE" + 0x00000002: "D", // "UNINTERRUPTIBLE" + 0x00000004: "T", // "STOPPED" + 0x00000008: "t", // "TRACED" + 0x00000010: "X", // "EXIT_DEAD" + 0x00000020: "Z", // "EXIT_ZOMBIE" + 0x00000040: "P", // "PARKED" + 0x00000080: "dd", // "DEAD" + 0x00000100: "wk", // "WAKEKILL" + 0x00000200: "wg", // "WAKING" + 0x00000400: "I", // "NOLOAD" + 0x00000800: "N", // "NEW" + 0x00001000: "rt", // "RTLOCK_WAIT" + 0x00002000: "fe", // "FREEZABLE" + 0x00004000: "fu", // "__TASK_FREEZABLE_UNSAFE = (0x00004000 * IS_ENABLED(CONFIG_LOCKDEP))" + 0x00008000: "fo", // "FROZEN" +} + +// GetTaskStateName 将内核任务状态位掩码转换为可读字符串 +func GetTaskStateName(taskState uint32) string { + if taskState == 0 { + return "R" + } + if taskState&TASK_NOLOAD != 0 { // 空闲内核线程等待工作 + return "I" + } + + var names []string + for state, name := range taskStates { + if taskState&state != 0 { + names = append(names, name) + } + } + + return strings.Join(names, "+") +} \ No newline at end of file From 8b6fc78ce74237975d17416b0c650dc39d3381d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Apr 2025 01:05:32 +0000 Subject: [PATCH 2/2] chore(deps): bump golang.org/x/crypto from 0.32.0 to 0.35.0 Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.32.0 to 0.35.0. - [Commits](https://github.com/golang/crypto/compare/v0.32.0...v0.35.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-version: 0.35.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 8a193fe..6346596 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/prometheus/client_golang v1.19.1 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - golang.org/x/sync v0.10.0 + golang.org/x/sync v0.11.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v2 v2.4.0 k8s.io/apimachinery v0.31.0 @@ -97,11 +97,11 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.12.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.35.0 // indirect golang.org/x/net v0.34.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/protobuf v1.36.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -118,5 +118,5 @@ require ( github.com/cilium/ebpf v0.16.1-0.20241204125435-9895aae6467e github.com/go-logr/logr v1.4.2 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - golang.org/x/sys v0.29.0 + golang.org/x/sys v0.30.0 ) diff --git a/go.sum b/go.sum index 9ca2597..6698076 100644 --- a/go.sum +++ b/go.sum @@ -265,8 +265,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -291,8 +291,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -304,20 +304,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=