From d36874c451fb858e5968aa8f64b612ab2a51f2c4 Mon Sep 17 00:00:00 2001 From: Zhangxinyi <643470801@qq.com> Date: Fri, 16 Aug 2024 17:47:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=80=81=E4=BA=92?= =?UTF-8?q?=E6=96=A5=E9=94=81=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cpu_watcher/bpf/mutrace.bpf.c | 206 ++++++++---------- .../cpu_watcher/test/test_cpuwatcher.c | 67 +++++- 2 files changed, 145 insertions(+), 128 deletions(-) diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c index 79212119b..0ab634eeb 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c @@ -33,81 +33,81 @@ struct { } rb SEC(".maps"); static inline struct mu_ctrl *get_mu_ctrl(void) { - struct mu_ctrl *mu_ctrl; - mu_ctrl = bpf_map_lookup_elem(&mu_ctrl_map, &ctrl_key); - if (!mu_ctrl || !mu_ctrl->mu_func) { - return NULL; - } - return mu_ctrl; + struct mu_ctrl *mu_ctrl = bpf_map_lookup_elem(&mu_ctrl_map, &ctrl_key); + return (mu_ctrl && mu_ctrl->mu_func) ? mu_ctrl : NULL; } -/*----------------------------------------------*/ -/* 内核态互斥锁 */ -/*----------------------------------------------*/ +static inline void update_mutex_info(struct mutex_info *info, u64 ts, pid_t pid) { + info->acquire_time = ts; + info->last_owner = pid; + bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); +} + +static inline void init_mutex_info(struct mutex_info *info, u64 lock_addr, u64 ts, pid_t pid) { + info->locked_total = 0; + info->locked_max = 0; + info->contended_total = 0; + info->count = 0; + info->last_owner = pid; + info->acquire_time = ts; + info->ptr = lock_addr; + __builtin_memset(info->last_name, 0, sizeof(info->last_name)); + bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); +} SEC("kprobe/mutex_lock") int BPF_KPROBE(trace_mutex_lock, struct mutex *lock) { - u64 lock_addr = (u64)lock; // 获取锁地址 + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + u64 lock_addr = (u64)lock; u64 ts = bpf_ktime_get_ns(); struct mutex_info *info = bpf_map_lookup_elem(&kmutex_info_map, &lock_addr); + if (info) { - info->acquire_time = ts; // 保存锁获取时间 + info->acquire_time = ts; } else { - struct mutex_info new_info = { - .locked_total = 0, - .locked_max = 0, - .contended_total = 0, - .count = 0, - .last_owner = 0, - .acquire_time = ts, - .ptr = lock_addr - }; - __builtin_memset(new_info.last_name, 0, sizeof(new_info.last_name)); + struct mutex_info new_info; + init_mutex_info(&new_info, lock_addr, ts, 0); bpf_map_update_elem(&kmutex_info_map, &lock_addr, &new_info, BPF_ANY); } + return 0; } SEC("kprobe/mutex_trylock") int BPF_KPROBE(trace_mutex_trylock, struct mutex *lock) { + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); int ret = PT_REGS_RC(ctx); - if (ret != 0) { // 成功获取锁 - u64 lock_addr = (u64)lock; // 获取锁地址 + if (ret != 0) { + u64 lock_addr = (u64)lock; u64 ts = bpf_ktime_get_ns(); struct mutex_info *info = bpf_map_lookup_elem(&kmutex_info_map, &lock_addr); + if (info) { info->acquire_time = ts; } else { - struct mutex_info new_info = { - .locked_total = 0, - .locked_max = 0, - .contended_total = 0, - .count = 0, - .last_owner = 0, - .acquire_time = ts, - .ptr = lock_addr - }; - __builtin_memset(new_info.last_name, 0, sizeof(new_info.last_name)); + struct mutex_info new_info; + init_mutex_info(&new_info, lock_addr, ts, 0); bpf_map_update_elem(&kmutex_info_map, &lock_addr, &new_info, BPF_ANY); } } + return 0; } SEC("kprobe/__mutex_lock_slowpath") int BPF_KPROBE(trace_mutex_lock_slowpath, struct mutex *lock) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); - struct mutex_contention_event *e; - struct task_struct *owner_task; - struct task_struct *contender_task; - pid_t pid = bpf_get_current_pid_tgid(); - long owner; + if (!mu_ctrl) return 0; + u64 lock_addr = (u64)lock; u64 ts = bpf_ktime_get_ns(); - e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); - if (!e) { - return 0; - } + struct mutex_contention_event *e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); + if (!e) return 0; + + pid_t pid = bpf_get_current_pid_tgid(); + struct task_struct *owner_task, *contender_task; + long owner; + e->contender_pid = pid; e->ptr = lock_addr; bpf_get_current_comm(&e->contender_name, sizeof(e->contender_name)); @@ -115,6 +115,7 @@ int BPF_KPROBE(trace_mutex_lock_slowpath, struct mutex *lock) { owner_task = (struct task_struct *)(owner & ~0x1L); contender_task = (struct task_struct *)bpf_get_current_task(); bpf_probe_read_kernel(&e->contender_prio, sizeof(e->contender_prio), &contender_task->prio); + if (owner_task) { bpf_probe_read_kernel(&e->owner_pid, sizeof(e->owner_pid), &owner_task->pid); bpf_probe_read_kernel_str(&e->owner_name, sizeof(e->owner_name), owner_task->comm); @@ -123,89 +124,75 @@ int BPF_KPROBE(trace_mutex_lock_slowpath, struct mutex *lock) { e->owner_pid = 0; __builtin_memset(e->owner_name, 0, sizeof(e->owner_name)); } + struct mutex_info *info = bpf_map_lookup_elem(&kmutex_info_map, &lock_addr); if (info) { u64 contention_start = ts; - info->contended_total += (contention_start - info->acquire_time); // 更新争用时间 - info->count++; // 更新争用次数 + info->contended_total += (contention_start - info->acquire_time); + info->count++; } else { - struct mutex_info new_info = { - .locked_total = 0, - .locked_max = 0, - .contended_total = 0, - .count = 1, // 初始化争用次数 - .last_owner = 0, - .acquire_time = ts, // 初始化获取时间 - .ptr = lock_addr - }; - __builtin_memset(new_info.last_name, 0, sizeof(new_info.last_name)); + struct mutex_info new_info; + init_mutex_info(&new_info, lock_addr, ts, 0); + new_info.count = 1; bpf_map_update_elem(&kmutex_info_map, &lock_addr, &new_info, BPF_ANY); } + bpf_ringbuf_submit(e, 0); return 0; } SEC("kprobe/mutex_unlock") int BPF_KPROBE(trace_mutex_unlock, struct mutex *lock) { + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); u64 lock_addr = (u64)lock; u64 ts = bpf_ktime_get_ns(); pid_t pid = bpf_get_current_pid_tgid(); struct mutex_info *info = bpf_map_lookup_elem(&kmutex_info_map, &lock_addr); + if (info) { - u64 held_time = ts - info->acquire_time; // 计算锁被持有的时间 - info->locked_total += held_time; // 更新锁被持有的总时间 + u64 held_time = ts - info->acquire_time; + info->locked_total += held_time; if (held_time > info->locked_max) { - info->locked_max = held_time; // 更新锁被持有的最长时间 + info->locked_max = held_time; } - info->last_owner = pid; // 更新最后一次持有该锁的线程ID - bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); // 更新最后一次持有该锁的线程名称 + info->last_owner = pid; + bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); } + return 0; } - - /*----------------------------------------------*/ /* 用户态互斥锁 */ /*----------------------------------------------*/ - - -SEC("uprobe/pthread_mutex_lock") -int BPF_KPROBE(pthread_mutex_lock, void *__mutex) { - u64 pid_tgid = bpf_get_current_pid_tgid(); - pid_t pid = pid_tgid >> 32; - u64 now = bpf_ktime_get_ns(); - +static inline void handle_user_mutex_lock(void *__mutex, u64 now, pid_t pid) { struct mutex_info *info = bpf_map_lookup_elem(&umutex_info_map, &__mutex); if (info) { if (info->acquire_time > 0) { - // 如果 acquire_time 已经被设置,说明锁被争用 info->contended_total += (now - info->acquire_time); - info->count += 1; + info->count++; } - info->acquire_time = now; - info->last_owner = pid; - bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); + update_mutex_info(info, now, pid); } else { - // 初始化 mutex_info - struct mutex_info new_info = { - .locked_total = 0, - .locked_max = 0, - .contended_total = 0, - .count = 0, - .last_owner = pid, - .acquire_time = now, - .ptr = (u64)__mutex, - }; - bpf_get_current_comm(&new_info.last_name, sizeof(new_info.last_name)); + struct mutex_info new_info; + init_mutex_info(&new_info, (u64)__mutex, now, pid); bpf_map_update_elem(&umutex_info_map, &__mutex, &new_info, BPF_ANY); } +} + +SEC("uprobe/pthread_mutex_lock") +int BPF_KPROBE(pthread_mutex_lock, void *__mutex) { + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + u64 now = bpf_ktime_get_ns(); + pid_t pid = bpf_get_current_pid_tgid() >> 32; + handle_user_mutex_lock(__mutex, now, pid); return 0; } SEC("uprobe/__pthread_mutex_trylock") int BPF_KPROBE(__pthread_mutex_trylock, void *__mutex) { + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); u64 pid_tgid = bpf_get_current_pid_tgid(); u64 now = bpf_ktime_get_ns(); struct trylock_info info = { @@ -218,55 +205,32 @@ int BPF_KPROBE(__pthread_mutex_trylock, void *__mutex) { SEC("uretprobe/__pthread_mutex_trylock") int BPF_KRETPROBE(ret_pthread_mutex_trylock, int ret) { + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); u64 pid_tgid = bpf_get_current_pid_tgid(); struct trylock_info *try_info = bpf_map_lookup_elem(&trylock_map, &pid_tgid); - if (!try_info) { - return 0; - } - void *__mutex = try_info->__mutex; - u64 now = bpf_ktime_get_ns(); + if (!try_info) return 0; + if (ret == 0) { - struct mutex_info *info = bpf_map_lookup_elem(&umutex_info_map, &__mutex); - if (info) { - if (info->acquire_time > 0) { - // 如果 acquire_time 已经被设置,说明锁被争用 - info->contended_total += (now - info->acquire_time); - info->count += 1; - } - info->acquire_time = now; - info->last_owner = pid_tgid >> 32; - bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); - } else { - // 初始化 mutex_info - struct mutex_info new_info = { - .locked_total = 0, - .locked_max = 0, - .contended_total = 0, - .count = 0, - .last_owner = pid_tgid >> 32, - .acquire_time = now, - .ptr = (u64)__mutex, - }; - bpf_get_current_comm(&new_info.last_name, sizeof(new_info.last_name)); - bpf_map_update_elem(&umutex_info_map, &__mutex, &new_info, BPF_ANY); - } + handle_user_mutex_lock(try_info->__mutex, try_info->start_time, pid_tgid >> 32); } bpf_map_delete_elem(&trylock_map, &pid_tgid); return 0; } SEC("uprobe/pthread_mutex_unlock") -int BPF_KPROBE(pthread_mutex_unlock, void *__mutex){ +int BPF_KPROBE(pthread_mutex_unlock, void *__mutex) { + struct mu_ctrl *mu_ctrl = get_mu_ctrl(); u64 now = bpf_ktime_get_ns(); + pid_t pid = bpf_get_current_pid_tgid() >> 32; struct mutex_info *info = bpf_map_lookup_elem(&umutex_info_map, &__mutex); if (info) { - u64 locked_time = now - info->acquire_time; - info->locked_total += locked_time; - if (locked_time > info->locked_max) { - info->locked_max = locked_time; + u64 held_time = now - info->acquire_time; + info->locked_total += held_time; + if (held_time > info->locked_max) { + info->locked_max = held_time; } - info->acquire_time = 0; + info->last_owner = pid; + bpf_get_current_comm(&info->last_name, sizeof(info->last_name)); } return 0; } - diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c index 59bb2dcb6..806fb55e2 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/test_cpuwatcher.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -19,7 +20,8 @@ static struct env { bool mq_delay_test; bool preempt_test; bool schedule_test; - bool mutrace_test; + bool mutrace_test1; + bool mutrace_test2; } env = { .sar_test = false, .cs_delay_test = false, @@ -27,7 +29,8 @@ static struct env { .mq_delay_test = false, .preempt_test = false, .schedule_test = false, - .mutrace_test = false, + .mutrace_test1 = false, + .mutrace_test2 = false, }; const char argp_program_doc[] ="To test cpu_watcher.\n"; @@ -39,7 +42,8 @@ static const struct argp_option opts[] = { { "mq_delay", 'm', NULL, 0, "To test mq_delay", 0 }, { "preempt_delay", 'p', NULL, 0, "To test preempt_delay", 0 }, { "schedule_delay", 'd', NULL, 0, "To test schedule_delay", 0 }, - { "mu_trace", 'x', NULL, 0, "To test mutrace", 0 }, + { "mu_trace_kernel", 'x', NULL, 0, "To test kernel mutrace", 0 }, + { "mu_trace_user", 'u', NULL, 0, "To test user mutrace", 0 }, { "all", 'a', NULL, 0, "To test all", 0 }, { NULL, 'h', NULL, OPTION_HIDDEN, "show the full help", 0 }, {}, @@ -76,7 +80,10 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) env.schedule_test = true; break; case 'x': - env.mutrace_test = true; + env.mutrace_test1 = true; + break; + case 'u': + env.mutrace_test2 = true; break; case 'h': argp_state_help(state, stderr, ARGP_HELP_STD_HELP); @@ -128,6 +135,43 @@ void input_pid() { printf("\n"); } +void *mutex_test_thread(void *arg) { + pthread_mutex_t *mutex = (pthread_mutex_t *)arg; + uintptr_t mutex_addr = (uintptr_t)mutex; // 获取互斥锁的地址 + + for (int i = 0; i < 10; i++) { + pthread_mutex_lock(mutex); + printf("Thread %ld (mutex address: %lu) acquired the mutex\n", + pthread_self(), (unsigned long)mutex_addr); + usleep(rand() % 1000); + pthread_mutex_unlock(mutex); + printf("Thread %ld (mutex address: %lu) released the mutex\n", + pthread_self(), (unsigned long)mutex_addr); + usleep(rand() % 1000); + } + + return NULL; +} + +void start_mutex_test(int num_threads) { + pthread_mutex_t mutex; + pthread_t *threads = malloc(num_threads * sizeof(pthread_t)); + + pthread_mutex_init(&mutex, NULL); + + for (int i = 0; i < num_threads; i++) { + pthread_create(&threads[i], NULL, mutex_test_thread, &mutex); + } + + for (int i = 0; i < num_threads; i++) { + pthread_join(threads[i], NULL); + } + + pthread_mutex_destroy(&mutex); + free(threads); +} + + int main(int argc, char **argv){ int err; static const struct argp argp = { @@ -197,9 +241,9 @@ int main(int argc, char **argv){ printf("\n"); } - if(env.mutrace_test){ - printf("MUTRACE_TEST----------------------------------------------\n"); - //MUTRACE功能测试逻辑:系统上执行混合压力测试,包括4个顺序读写硬盘线程、4个IO操作线程,持续15秒,观察加压前后的变化。 + if(env.mutrace_test1){ + printf("MUTRACE_KERNEL_TEST----------------------------------------------\n"); + //内核态互斥锁功能测试逻辑:系统上执行混合压力测试,包括4个顺序读写硬盘线程、4个IO操作线程,持续15秒,观察加压前后的变化。 char *argvv[] = { "/usr/bin/stress-ng", "--hdd", "4", "--hdd-opts", "wr-seq,rd-seq", "--io", "4", "--timeout", "15s", "--metrics-brief", NULL }; char *envp[] = { "PATH=/bin", NULL }; printf("MUTRACE功能测试逻辑:系统上执行混合压力测试,包括4个顺序读写硬盘线程、4个IO操作线程和4个UDP网络操作线程,持续15秒,观察加压前后的变化\n"); @@ -209,5 +253,14 @@ int main(int argc, char **argv){ printf("\n"); } + + if(env.mutrace_test2){ + printf("MUTRACE_USER_TEST----------------------------------------------\n"); + printf("测试场景: 创建多个线程,每个线程反复加锁和解锁同一个互斥锁,观察互斥锁的争用情况\n"); + start_mutex_test(10); // 创建10个线程进行互斥锁测试 + printf("测试结束\n"); + printf("\n"); + + } return 0; } From 4e1d17296bb902d3dba9693e8d515feb7ba0a9ff Mon Sep 17 00:00:00 2001 From: Zhangxinyi <643470801@qq.com> Date: Sat, 7 Sep 2024 13:18:35 +0800 Subject: [PATCH 2/2] revision --- .../cpu_watcher/bpf/cs_delay.bpf.c | 6 ++++ .../cpu_watcher/bpf/mq_delay.bpf.c | 21 +++++++++++++ .../cpu_watcher/bpf/mutrace.bpf.c | 24 +++++++++++++++ .../cpu_watcher/bpf/preempt.bpf.c | 6 ++++ .../CPU_Subsystem/cpu_watcher/bpf/sar.bpf.c | 30 +++++++++++++++++++ .../cpu_watcher/bpf/sc_delay.bpf.c | 6 ++++ .../cpu_watcher/bpf/schedule_delay.bpf.c | 12 ++++++++ 7 files changed, 105 insertions(+) diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/cs_delay.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/cs_delay.bpf.c index caaf8c408..9cd31fc3d 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/cs_delay.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/cs_delay.bpf.c @@ -43,6 +43,9 @@ SEC("kprobe/schedule") int BPF_KPROBE(schedule) { struct cs_ctrl *cs_ctrl = get_cs_ctrl(); + if (!cs_ctrl) { + return 0; + } u64 t1; t1 = bpf_ktime_get_ns()/1000; int key =0; @@ -54,6 +57,9 @@ SEC("kretprobe/schedule") int BPF_KRETPROBE(schedule_exit) { struct cs_ctrl *cs_ctrl = get_cs_ctrl(); + if (!cs_ctrl) { + return 0; + } u64 t2 = bpf_ktime_get_ns()/1000; u64 t1,delay; int key = 0; diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mq_delay.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mq_delay.bpf.c index 3aa9dd92e..d9e94da36 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mq_delay.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mq_delay.bpf.c @@ -75,6 +75,9 @@ int BPF_KPROBE(mq_timedsend,mqd_t mqdes, const char *u_msg_ptr, struct timespec64 *ts) { struct mq_ctrl *mq_ctrl = get_mq_ctrl(); + if (!mq_ctrl) { + return 0; + } u64 send_enter_time = bpf_ktime_get_ns();//开始发送信息时间; int pid = bpf_get_current_pid_tgid();//发送端pid @@ -95,6 +98,9 @@ int BPF_KPROBE(mq_timedsend,mqd_t mqdes, const char *u_msg_ptr, SEC("kprobe/load_msg") int BPF_KPROBE(load_msg_enter,const void *src, size_t len){ struct mq_ctrl *mq_ctrl = get_mq_ctrl(); + if (!mq_ctrl) { + return 0; + } int pid = bpf_get_current_pid_tgid();//发送端pid /*记录load入参src*/ struct send_events *mq_send_info = bpf_map_lookup_elem(&send_msg1, &pid); @@ -110,6 +116,9 @@ int BPF_KPROBE(load_msg_enter,const void *src, size_t len){ SEC("kretprobe/load_msg") int BPF_KRETPROBE(load_msg_exit,void *ret){ struct mq_ctrl *mq_ctrl = get_mq_ctrl(); + if (!mq_ctrl) { + return 0; + } int pid = bpf_get_current_pid_tgid();//发送端pid /*构建消息块结构体,作为key*/ struct send_events *mq_send_info = bpf_map_lookup_elem(&send_msg1, &pid); @@ -136,6 +145,9 @@ SEC("kretprobe/do_mq_timedsend") int BPF_KRETPROBE(do_mq_timedsend_exit,void *ret) { struct mq_ctrl *mq_ctrl = get_mq_ctrl(); + if (!mq_ctrl) { + return 0; + } bpf_printk("do_mq_timedsend_exit----------------------------------------------------------------\n"); u64 send_exit_time = bpf_ktime_get_ns();//开始发送信息时间; int pid = bpf_get_current_pid_tgid();//发送端pid @@ -164,6 +176,9 @@ int BPF_KPROBE(mq_timedreceive_entry,mqd_t mqdes, const char __user *u_msg_ptr, struct timespec64 *ts) { struct mq_ctrl *mq_ctrl = get_mq_ctrl(); + if (!mq_ctrl) { + return 0; + } u64 rcv_enter_time = bpf_ktime_get_ns(); int pid = bpf_get_current_pid_tgid(); @@ -182,6 +197,9 @@ 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(); + if (!mq_ctrl) { + return 0; + } int pid = bpf_get_current_pid_tgid(); /*make key*/ @@ -210,6 +228,9 @@ 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(); + if (!mq_ctrl) { + return 0; + } u64 rcv_exit_time = bpf_ktime_get_ns(); int pid = bpf_get_current_pid_tgid(); u64 send_enter_time,delay; diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c index 0ab634eeb..7b10a6ff7 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/mutrace.bpf.c @@ -58,6 +58,9 @@ static inline void init_mutex_info(struct mutex_info *info, u64 lock_addr, u64 t SEC("kprobe/mutex_lock") int BPF_KPROBE(trace_mutex_lock, struct mutex *lock) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } u64 lock_addr = (u64)lock; u64 ts = bpf_ktime_get_ns(); struct mutex_info *info = bpf_map_lookup_elem(&kmutex_info_map, &lock_addr); @@ -76,6 +79,9 @@ int BPF_KPROBE(trace_mutex_lock, struct mutex *lock) { SEC("kprobe/mutex_trylock") int BPF_KPROBE(trace_mutex_trylock, struct mutex *lock) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } int ret = PT_REGS_RC(ctx); if (ret != 0) { u64 lock_addr = (u64)lock; @@ -97,6 +103,9 @@ int BPF_KPROBE(trace_mutex_trylock, struct mutex *lock) { SEC("kprobe/__mutex_lock_slowpath") int BPF_KPROBE(trace_mutex_lock_slowpath, struct mutex *lock) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } if (!mu_ctrl) return 0; u64 lock_addr = (u64)lock; @@ -144,6 +153,9 @@ int BPF_KPROBE(trace_mutex_lock_slowpath, struct mutex *lock) { SEC("kprobe/mutex_unlock") int BPF_KPROBE(trace_mutex_unlock, struct mutex *lock) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } u64 lock_addr = (u64)lock; u64 ts = bpf_ktime_get_ns(); pid_t pid = bpf_get_current_pid_tgid(); @@ -184,6 +196,9 @@ static inline void handle_user_mutex_lock(void *__mutex, u64 now, pid_t pid) { SEC("uprobe/pthread_mutex_lock") int BPF_KPROBE(pthread_mutex_lock, void *__mutex) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } u64 now = bpf_ktime_get_ns(); pid_t pid = bpf_get_current_pid_tgid() >> 32; handle_user_mutex_lock(__mutex, now, pid); @@ -193,6 +208,9 @@ int BPF_KPROBE(pthread_mutex_lock, void *__mutex) { SEC("uprobe/__pthread_mutex_trylock") int BPF_KPROBE(__pthread_mutex_trylock, void *__mutex) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } u64 pid_tgid = bpf_get_current_pid_tgid(); u64 now = bpf_ktime_get_ns(); struct trylock_info info = { @@ -206,6 +224,9 @@ int BPF_KPROBE(__pthread_mutex_trylock, void *__mutex) { SEC("uretprobe/__pthread_mutex_trylock") int BPF_KRETPROBE(ret_pthread_mutex_trylock, int ret) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } u64 pid_tgid = bpf_get_current_pid_tgid(); struct trylock_info *try_info = bpf_map_lookup_elem(&trylock_map, &pid_tgid); if (!try_info) return 0; @@ -220,6 +241,9 @@ int BPF_KRETPROBE(ret_pthread_mutex_trylock, int ret) { SEC("uprobe/pthread_mutex_unlock") int BPF_KPROBE(pthread_mutex_unlock, void *__mutex) { struct mu_ctrl *mu_ctrl = get_mu_ctrl(); + if (!mu_ctrl) { + return 0; + } u64 now = bpf_ktime_get_ns(); pid_t pid = bpf_get_current_pid_tgid() >> 32; struct mutex_info *info = bpf_map_lookup_elem(&umutex_info_map, &__mutex); diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/preempt.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/preempt.bpf.c index bf650a6e0..167f44f1a 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/preempt.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/preempt.bpf.c @@ -44,6 +44,9 @@ static inline struct preempt_ctrl *get_preempt_ctrl(void) { 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(); + if (!preempt_ctrl) { + return 0; + } u64 start_time = bpf_ktime_get_ns(); pid_t prev_pid = BPF_CORE_READ(prev, pid); @@ -63,6 +66,9 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s 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(); + if (!preempt_ctrl) { + return 0; + } u64 end_time = bpf_ktime_get_ns(); pid_t pid = BPF_CORE_READ(prev, pid); u64 *val; diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sar.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sar.bpf.c index eb4012def..b2f1a15a9 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sar.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sar.bpf.c @@ -68,6 +68,9 @@ SEC("kprobe/finish_task_switch.isra.0") int kprobe__finish_task_switch(struct pt_regs *ctx) { struct sar_ctrl *sar_ctrl = get_sar_ctrl(); + if (!sar_ctrl) { + return 0; + } u32 key = 0; u64 val, *valp = NULL; unsigned long total_forks; @@ -86,6 +89,9 @@ 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(); + if (!sar_ctrl) { + return 0; + } pid_t prev = info->prev_pid, next = info->next_pid; if (prev != next) { u32 key = 0; @@ -108,6 +114,9 @@ int trace_sched_switch2(struct cswch_args *info) { 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(); + if (!sar_ctrl) { + return 0; + } pid_t pid=BPF_CORE_READ(prev,pid); u64 *val, time = bpf_ktime_get_ns(); u64 delta; @@ -139,6 +148,9 @@ 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(); + if (!sar_ctrl) { + return 0; + } u32 key = 0; u64 val = BPF_CORE_READ(rq,nr_running); bpf_map_update_elem(&runqlen,&key,&val,BPF_ANY); @@ -149,6 +161,9 @@ 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(); + if (!sar_ctrl) { + return 0; + } u32 key = info->vec; u64 val = bpf_ktime_get_ns(); bpf_map_update_elem(&softirqCpuEnterTime, &key, &val, BPF_ANY); @@ -158,6 +173,9 @@ 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(); + if (!sar_ctrl) { + return 0; + } u32 key = info->vec; u64 now = bpf_ktime_get_ns(), *valp = 0; valp =bpf_map_lookup_elem(&softirqCpuEnterTime, &key); @@ -177,6 +195,9 @@ int trace_softirq_exit(struct __softirq_info *info) { SEC("tracepoint/irq/irq_handler_entry") int trace_irq_handler_entry(struct __irq_info *info) { struct sar_ctrl *sar_ctrl = get_sar_ctrl(); + if (!sar_ctrl) { + return 0; + } u32 key = info->irq; u64 ts = bpf_ktime_get_ns(); bpf_map_update_elem(&irq_cpu_enter_start, &key, &ts, BPF_ANY); @@ -186,6 +207,9 @@ 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(); + if (!sar_ctrl) { + return 0; + } u32 key = info->irq; u64 now = bpf_ktime_get_ns(), *ts = 0; ts = bpf_map_lookup_elem(&irq_cpu_enter_start, &key); @@ -206,6 +230,9 @@ int trace_irq_handler_exit(struct __irq_info *info) { SEC("tracepoint/power/cpu_idle") int trace_cpu_idle(struct idleStruct *pIDLE) { struct sar_ctrl *sar_ctrl = get_sar_ctrl(); + if (!sar_ctrl) { + return 0; + } u64 delta, time = bpf_ktime_get_ns(); u32 key = pIDLE->cpu_id; if (pIDLE->state == -1) { @@ -236,6 +263,9 @@ static __always_inline int user_mode(struct pt_regs *regs) SEC("perf_event") int tick_update(struct pt_regs *ctx) { struct sar_ctrl *sar_ctrl = get_sar_ctrl(); + if (!sar_ctrl) { + return 0; + } // bpf_trace_printk("cs_rpl = %x\n", ctx->cs & 3); u32 key = 0; diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sc_delay.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sc_delay.bpf.c index ee224283a..91c4537d8 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sc_delay.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/sc_delay.bpf.c @@ -45,6 +45,9 @@ static inline struct sc_ctrl *get_sc_ctrl(void) { SEC("tracepoint/raw_syscalls/sys_enter") int tracepoint__syscalls__sys_enter(struct trace_event_raw_sys_enter *args){ struct sc_ctrl *sc_ctrl = get_sc_ctrl(); + if (!sc_ctrl) { + return 0; + } u64 start_time = bpf_ktime_get_ns()/1000; pid_t pid = bpf_get_current_pid_tgid(); u64 syscall_id = (u64)args->id; @@ -58,6 +61,9 @@ int tracepoint__syscalls__sys_enter(struct trace_event_raw_sys_enter *args){ SEC("tracepoint/raw_syscalls/sys_exit") int tracepoint__syscalls__sys_exit(struct trace_event_raw_sys_exit *args){ struct sc_ctrl *sc_ctrl = get_sc_ctrl(); + if (!sc_ctrl) { + return 0; + } u64 exit_time = bpf_ktime_get_ns()/1000; pid_t pid = bpf_get_current_pid_tgid() ; u64 syscall_id; diff --git a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/schedule_delay.bpf.c b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/schedule_delay.bpf.c index db1b2a363..459eb042a 100644 --- a/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/schedule_delay.bpf.c +++ b/eBPF_Supermarket/CPU_Subsystem/cpu_watcher/bpf/schedule_delay.bpf.c @@ -43,6 +43,9 @@ static inline struct schedule_ctrl *get_schedule_ctrl(void) { SEC("tp_btf/sched_wakeup") int BPF_PROG(sched_wakeup, struct task_struct *p) { struct schedule_ctrl *sched_ctrl = get_schedule_ctrl(); + if (!sched_ctrl) { + return 0; + } pid_t pid = p->pid; int cpu = bpf_get_smp_processor_id(); struct schedule_event *schedule_event; @@ -70,6 +73,9 @@ int BPF_PROG(sched_wakeup, struct task_struct *p) { SEC("tp_btf/sched_wakeup_new") int BPF_PROG(sched_wakeup_new, struct task_struct *p) { struct schedule_ctrl *sched_ctrl = get_schedule_ctrl(); + if (!sched_ctrl) { + return 0; + } sched_ctrl = bpf_map_lookup_elem(&schedule_ctrl_map,&ctrl_key); if(!sched_ctrl || !sched_ctrl->schedule_func) return 0; @@ -94,6 +100,9 @@ int BPF_PROG(sched_wakeup_new, struct task_struct *p) { SEC("tp_btf/sched_switch") int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_struct *next) { struct schedule_ctrl *sched_ctrl = get_schedule_ctrl(); + if (!sched_ctrl) { + return 0; + } struct proc_history *history; struct proc_history new_history; u64 current_time = bpf_ktime_get_ns(); @@ -198,6 +207,9 @@ int BPF_PROG(sched_switch, bool preempt, struct task_struct *prev, struct task_s SEC("tracepoint/sched/sched_process_exit") int sched_process_exit(void *ctx) { struct schedule_ctrl *sched_ctrl = get_schedule_ctrl(); + if (!sched_ctrl) { + return 0; + } struct task_struct *p = (struct task_struct *)bpf_get_current_task(); pid_t pid = BPF_CORE_READ(p, pid); int cpu = bpf_get_smp_processor_id();