Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu_watcher:schedule_delay功能扩充&sar功能适配controller #830

Merged
merged 9 commits into from
Jun 21, 2024
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
Loading