Skip to content

Commit

Permalink
cpu_watcher:schedule_delay功能扩充&sar功能适配controller (#830)
Browse files Browse the repository at this point in the history
* cpu_watcher:schedule_delay增加阈值选项&&workflow增加测试流程

* .

* cpu_watcher:增加controller功能

* cpu_watcher:schedule_delay增加dump出调度延迟过大task的前两个task

* sar功能适配controller

* .
  • Loading branch information
vvzxy authored Jun 21, 2024
1 parent d7c342b commit 6ac98b6
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 76 deletions.
11 changes: 11 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/cs_delay.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,19 @@ struct {
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");

static inline struct cs_ctrl *get_cs_ctrl(void) {
struct cs_ctrl *cs_ctrl;
cs_ctrl = bpf_map_lookup_elem(&cs_ctrl_map, &ctrl_key);
if (!cs_ctrl || !cs_ctrl->cs_func) {
return NULL;
}
return cs_ctrl;
}

SEC("kprobe/schedule")
int BPF_KPROBE(schedule)
{
struct cs_ctrl *cs_ctrl = get_cs_ctrl();
u64 t1;
t1 = bpf_ktime_get_ns()/1000;
int key =0;
Expand All @@ -43,6 +53,7 @@ int BPF_KPROBE(schedule)
SEC("kretprobe/schedule")
int BPF_KRETPROBE(schedule_exit)
{
struct cs_ctrl *cs_ctrl = get_cs_ctrl();
u64 t2 = bpf_ktime_get_ns()/1000;
u64 t1,delay;
int key = 0;
Expand Down
17 changes: 17 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mq_delay.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ struct {
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");

static inline struct mq_ctrl *get_mq_ctrl(void) {
struct mq_ctrl *mq_ctrl;
mq_ctrl = bpf_map_lookup_elem(&mq_ctrl_map, &ctrl_key);
if (!mq_ctrl || !mq_ctrl->mq_func) {
return NULL;
}
return mq_ctrl;
}


// int print_send_info(struct send_events * mq_send_info,int flag){
// bpf_printk("---------------------test----------------------------test--------------------------test--------------------------------------------test---------------------test---------------------test\n");
// bpf_printk("send_msg_prio: %-8lu\n",mq_send_info->msg_prio);
Expand Down Expand Up @@ -64,6 +74,7 @@ int BPF_KPROBE(mq_timedsend,mqd_t mqdes, const char *u_msg_ptr,
size_t msg_len, unsigned int msg_prio,
struct timespec64 *ts)
{
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
u64 send_enter_time = bpf_ktime_get_ns();//开始发送信息时间;
int pid = bpf_get_current_pid_tgid();//发送端pid

Expand All @@ -83,6 +94,7 @@ int BPF_KPROBE(mq_timedsend,mqd_t mqdes, const char *u_msg_ptr,
/*仅获取mq_send_info -> src*/
SEC("kprobe/load_msg")
int BPF_KPROBE(load_msg_enter,const void *src, size_t len){
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
int pid = bpf_get_current_pid_tgid();//发送端pid
/*记录load入参src*/
struct send_events *mq_send_info = bpf_map_lookup_elem(&send_msg1, &pid);
Expand All @@ -97,6 +109,7 @@ int BPF_KPROBE(load_msg_enter,const void *src, size_t len){
/*获取消息块作为key,并建立 message -> mq_send_info 的哈希表*/
SEC("kretprobe/load_msg")
int BPF_KRETPROBE(load_msg_exit,void *ret){
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
int pid = bpf_get_current_pid_tgid();//发送端pid
/*构建消息块结构体,作为key*/
struct send_events *mq_send_info = bpf_map_lookup_elem(&send_msg1, &pid);
Expand All @@ -122,6 +135,7 @@ int BPF_KRETPROBE(load_msg_exit,void *ret){
SEC("kretprobe/do_mq_timedsend")
int BPF_KRETPROBE(do_mq_timedsend_exit,void *ret)
{
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
bpf_printk("do_mq_timedsend_exit----------------------------------------------------------------\n");
u64 send_exit_time = bpf_ktime_get_ns();//开始发送信息时间;
int pid = bpf_get_current_pid_tgid();//发送端pid
Expand Down Expand Up @@ -149,6 +163,7 @@ int BPF_KPROBE(mq_timedreceive_entry,mqd_t mqdes, const char __user *u_msg_ptr,
size_t msg_len, unsigned int msg_prio,
struct timespec64 *ts)
{
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
u64 rcv_enter_time = bpf_ktime_get_ns();
int pid = bpf_get_current_pid_tgid();

Expand All @@ -166,6 +181,7 @@ int BPF_KPROBE(mq_timedreceive_entry,mqd_t mqdes, const char __user *u_msg_ptr,
SEC("kprobe/store_msg")
int BPF_KPROBE(store_msg,void __user *dest, struct msg_msg *msg, size_t len)
{
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
int pid = bpf_get_current_pid_tgid();

/*make key*/
Expand Down Expand Up @@ -193,6 +209,7 @@ int BPF_KPROBE(store_msg,void __user *dest, struct msg_msg *msg, size_t len)

SEC("kretprobe/do_mq_timedreceive")
int BPF_KRETPROBE(do_mq_timedreceive_exit,void *ret){
struct mq_ctrl *mq_ctrl = get_mq_ctrl();
u64 rcv_exit_time = bpf_ktime_get_ns();
int pid = bpf_get_current_pid_tgid();
u64 send_enter_time,delay;
Expand Down
15 changes: 13 additions & 2 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/preempt.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,27 @@
char LICENSE[] SEC("license") = "Dual BSD/GPL";

#define TIF_NEED_RESCHED 3

const int ctrl_key = 0;
// 记录时间戳
BPF_HASH(preemptTime, pid_t, u64, 4096);

BPF_ARRAY(preempt_ctrl_map,int,struct preempt_ctrl,1);
struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");

static inline struct preempt_ctrl *get_preempt_ctrl(void) {
struct preempt_ctrl *preempt_ctrl;
preempt_ctrl = bpf_map_lookup_elem(&preempt_ctrl_map, &ctrl_key);
if (!preempt_ctrl || !preempt_ctrl->preempt_func) {
return NULL;
}
return preempt_ctrl;
}

SEC("tp_btf/sched_switch")
int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_struct *next) {
struct preempt_ctrl *preempt_ctrl = get_preempt_ctrl();
u64 start_time = bpf_ktime_get_ns();
pid_t prev_pid = BPF_CORE_READ(prev, pid);

Expand All @@ -52,6 +62,7 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s
// SEC("kprobe/finish_task_switch")
SEC("kprobe/finish_task_switch.isra.0")
int BPF_KPROBE(finish_task_switch, struct task_struct *prev) {
struct preempt_ctrl *preempt_ctrl = get_preempt_ctrl();
u64 end_time = bpf_ktime_get_ns();
pid_t pid = BPF_CORE_READ(prev, pid);
u64 *val;
Expand Down
23 changes: 22 additions & 1 deletion eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sar.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
char LICENSE[] SEC("license") = "Dual BSD/GPL";

const volatile long long unsigned int forks_addr = 0;

const int ctrl_key = 0;
#define PF_IDLE 0x00000002 /* I am an IDLE thread */
#define PF_KTHREAD 0x00200000 /* I am a kernel thread */

Expand Down Expand Up @@ -51,11 +51,23 @@ BPF_ARRAY(kt_LastTime,u32,u64,1);
BPF_ARRAY(ut_LastTime,u32,u64,1);
BPF_ARRAY(tick_user,u32,u64,1);
BPF_ARRAY(symAddr,u32,u64,1);
BPF_ARRAY(sar_ctrl_map,int,struct sar_ctrl,1);

static inline struct sar_ctrl *get_sar_ctrl(void) {
struct sar_ctrl *sar_ctrl;
sar_ctrl = bpf_map_lookup_elem(&sar_ctrl_map, &ctrl_key);
if (!sar_ctrl || !sar_ctrl->sar_func) {
return NULL;
}
return sar_ctrl;
}

// 统计fork数
SEC("kprobe/finish_task_switch.isra.0")
// SEC("kprobe/finish_task_switch")
int kprobe__finish_task_switch(struct pt_regs *ctx)
{
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u32 key = 0;
u64 val, *valp = NULL;
unsigned long total_forks;
Expand All @@ -73,6 +85,7 @@ int kprobe__finish_task_switch(struct pt_regs *ctx)
//获取进程切换数;
SEC("tracepoint/sched/sched_switch")
int trace_sched_switch2(struct cswch_args *info) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
pid_t prev = info->prev_pid, next = info->next_pid;
if (prev != next) {
u32 key = 0;
Expand All @@ -94,6 +107,7 @@ int trace_sched_switch2(struct cswch_args *info) {
// SEC("kprobe/finish_task_switch")
SEC("kprobe/finish_task_switch.isra.0")
int BPF_KPROBE(finish_task_switch,struct task_struct *prev){
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
pid_t pid=BPF_CORE_READ(prev,pid);
u64 *val, time = bpf_ktime_get_ns();
u64 delta;
Expand Down Expand Up @@ -124,6 +138,7 @@ int BPF_KPROBE(finish_task_switch,struct task_struct *prev){
//统计运行队列长度
SEC("kprobe/update_rq_clock")
int BPF_KPROBE(update_rq_clock,struct rq *rq){
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u32 key = 0;
u64 val = BPF_CORE_READ(rq,nr_running);
bpf_map_update_elem(&runqlen,&key,&val,BPF_ANY);
Expand All @@ -133,6 +148,7 @@ int BPF_KPROBE(update_rq_clock,struct rq *rq){
//软中断
SEC("tracepoint/irq/softirq_entry")
int trace_softirq_entry(struct __softirq_info *info) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u32 key = info->vec;
u64 val = bpf_ktime_get_ns();
bpf_map_update_elem(&softirqCpuEnterTime, &key, &val, BPF_ANY);
Expand All @@ -141,6 +157,7 @@ int trace_softirq_entry(struct __softirq_info *info) {

SEC("tracepoint/irq/softirq_exit")
int trace_softirq_exit(struct __softirq_info *info) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u32 key = info->vec;
u64 now = bpf_ktime_get_ns(), *valp = 0;
valp =bpf_map_lookup_elem(&softirqCpuEnterTime, &key);
Expand All @@ -159,6 +176,7 @@ int trace_softirq_exit(struct __softirq_info *info) {
注意这是所有CPU时间的叠加,平均到每个CPU应该除以CPU个数。*/
SEC("tracepoint/irq/irq_handler_entry")
int trace_irq_handler_entry(struct __irq_info *info) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u32 key = info->irq;
u64 ts = bpf_ktime_get_ns();
bpf_map_update_elem(&irq_cpu_enter_start, &key, &ts, BPF_ANY);
Expand All @@ -167,6 +185,7 @@ int trace_irq_handler_entry(struct __irq_info *info) {

SEC("tracepoint/irq/irq_handler_exit")
int trace_irq_handler_exit(struct __irq_info *info) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u32 key = info->irq;
u64 now = bpf_ktime_get_ns(), *ts = 0;
ts = bpf_map_lookup_elem(&irq_cpu_enter_start, &key);
Expand All @@ -186,6 +205,7 @@ int trace_irq_handler_exit(struct __irq_info *info) {
//tracepoint:power_cpu_idle 表征了CPU进入IDLE的状态,比较准确
SEC("tracepoint/power/cpu_idle")
int trace_cpu_idle(struct idleStruct *pIDLE) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();
u64 delta, time = bpf_ktime_get_ns();
u32 key = pIDLE->cpu_id;
if (pIDLE->state == -1) {
Expand Down Expand Up @@ -215,6 +235,7 @@ static __always_inline int user_mode(struct pt_regs *regs)
// 两个CPU各自会产生一个调用,这正好方便我们使用
SEC("perf_event")
int tick_update(struct pt_regs *ctx) {
struct sar_ctrl *sar_ctrl = get_sar_ctrl();

// bpf_trace_printk("cs_rpl = %x\n", ctx->cs & 3);
u32 key = 0;
Expand Down
40 changes: 22 additions & 18 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sc_delay.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,38 @@
// author: [email protected] [email protected] [email protected]

#include "vmlinux.h"
#include <bpf/bpf_helpers.h> //包含了BPF 辅助函数
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "cpu_watcher.h"

char LICENSE[] SEC("license") = "Dual BSD/GPL";

// 定义数组映射
//BPF_PERCPU_HASH(SyscallEnterTime,pid_t,struct syscall_flags,512);//记录时间戳
BPF_PERCPU_HASH(SyscallEnterTime,pid_t,u64,512);//记录时间戳

const int ctrl_key = 0;
BPF_PERCPU_HASH(SyscallEnterTime,pid_t,u64,512);
BPF_PERCPU_HASH(Events,pid_t,u64,10);
BPF_ARRAY(sc_ctrl_map,int,struct sc_ctrl,1);

struct {
__uint(type, BPF_MAP_TYPE_RINGBUF);
__uint(max_entries, 256 * 1024);
} rb SEC(".maps");//环形缓冲区;

static inline struct sc_ctrl *get_sc_ctrl(void) {
struct sc_ctrl *sc_ctrl;
sc_ctrl = bpf_map_lookup_elem(&sc_ctrl_map, &ctrl_key);
if (!sc_ctrl || !sc_ctrl->sc_func) {
return NULL;
}
return sc_ctrl;
}


SEC("tracepoint/raw_syscalls/sys_enter")//进入系统调用
SEC("tracepoint/raw_syscalls/sys_enter")
int tracepoint__syscalls__sys_enter(struct trace_event_raw_sys_enter *args){
u64 start_time = bpf_ktime_get_ns()/1000;//ms
pid_t pid = bpf_get_current_pid_tgid();//获取到当前进程的pid
struct sc_ctrl *sc_ctrl = get_sc_ctrl();
u64 start_time = bpf_ktime_get_ns()/1000;
pid_t pid = bpf_get_current_pid_tgid();
u64 syscall_id = (u64)args->id;

//bpf_printk("ID:%ld\n",syscall_id);
Expand All @@ -44,13 +55,13 @@ int tracepoint__syscalls__sys_enter(struct trace_event_raw_sys_enter *args){
return 0;
}

SEC("tracepoint/raw_syscalls/sys_exit")//退出系统调用
SEC("tracepoint/raw_syscalls/sys_exit")
int tracepoint__syscalls__sys_exit(struct trace_event_raw_sys_exit *args){
u64 exit_time = bpf_ktime_get_ns()/1000;//ms
pid_t pid = bpf_get_current_pid_tgid() ;//获取到当前进程的pid
struct sc_ctrl *sc_ctrl = get_sc_ctrl();
u64 exit_time = bpf_ktime_get_ns()/1000;
pid_t pid = bpf_get_current_pid_tgid() ;
u64 syscall_id;
u64 start_time, delay;

u64 *val = bpf_map_lookup_elem(&SyscallEnterTime, &pid);
if(val !=0){
start_time = *val;
Expand All @@ -59,27 +70,20 @@ int tracepoint__syscalls__sys_exit(struct trace_event_raw_sys_exit *args){
}else{
return 0;
}

u64 *val2 = bpf_map_lookup_elem(&Events, &pid);
if(val2 !=0){
syscall_id = *val2;
bpf_map_delete_elem(&SyscallEnterTime, &pid);
}else{
return 0;
}


struct syscall_events *e;
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
if (!e) return 0;

e->pid = pid;
e->delay = delay;
bpf_get_current_comm(&e->comm, sizeof(e->comm));
e->syscall_id = syscall_id;

bpf_ringbuf_submit(e, 0);


return 0;
}
Loading

0 comments on commit 6ac98b6

Please sign in to comment.