Skip to content

Commit

Permalink
add futex to mfutex
Browse files Browse the repository at this point in the history
  • Loading branch information
albertxu216 committed Sep 19, 2024
1 parent 4804e40 commit 3f6096c
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 33 deletions.
41 changes: 37 additions & 4 deletions eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/bpf/mfutex.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ int BPF_KPROBE(trace_futex_wait,
*2.1 将执行futex_wake的线程pid与锁地址进行匹配,便于在后面futex_wake_mark找到锁地址
*/
SEC("kprobe/futex_wake")
int BPF_KPROBE(trace_futex_wake,
int BPF_KPROBE(trace_futex_wake_enter,
u32 *uaddr, unsigned int flags,
int nr_wake, u32 bitset)
{
Expand Down Expand Up @@ -401,15 +401,48 @@ int BPF_KPROBE(trace_futex_wake_mark, struct wake_q_head *wake_q, struct futex_q
}
/*4.将任务放到唤醒队列中*/
bpf_map_update_elem(&futex_wake_queue, &key, per_request, BPF_ANY);
return 0;
}

/*5.传入rb*/
/*2.将线程加入唤醒队列,从等待队列中删除
*2.1 将执行futex_wake的线程pid与锁地址进行匹配,便于在后面futex_wake_mark找到锁地址
*/
SEC("kretprobe/futex_wake")
int BPF_KRETPROBE(trace_futex_wake_exit)
{
struct mfutex_ctrl *mfutex_ctrl = get_mfutex_ctrl();
if(!mfutex_ctrl)
return 0;
pid_t pid = bpf_get_current_pid_tgid();
int tgid = bpf_get_current_pid_tgid() >> 32;

if(mfutex_ctrl->target_pid == -1 && mfutex_ctrl->target_tgid == -1)//未指定目标进程或线程
return 0;
if((mfutex_ctrl->target_pid != -1 && pid!=mfutex_ctrl->target_pid)||
(mfutex_ctrl->target_tgid != -1 && tgid != mfutex_ctrl->target_tgid))//当前进程或线程非目标进程或线程
return 0;

u64 *lock_ptr;
u64 temp_lock_ptr;
u64 ts = bpf_ktime_get_ns();

/*1.找到锁的地址*/
struct proc_flag proc_flag = {};
proc_flag.pid = pid;
proc_flag.flag = FUTEX_FLAG;
lock_ptr = bpf_map_lookup_elem(&proc_unlock, &proc_flag);
if(!lock_ptr) return 0;
temp_lock_ptr = *lock_ptr;
bpf_map_delete_elem(&proc_unlock, &proc_flag);

/*2.传入rb*/
struct per_lock_event *e;
e = bpf_ringbuf_reserve(&mfutex_rb, sizeof(*e), 0);
if(!e)
return 0;
e->lock_ptr = temp_lock_ptr;
e->start_hold_time = ts;
e->start_hold_time = bpf_ktime_get_ns();
e->type = FUTEX_FLAG;
bpf_ringbuf_submit(e, 0);
return 0;
return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
#define LAST_ARG (FULL_MAX_ARGS_ARR - ARGSIZE)

#define TASK_RUNNING 0x00000000
// #define MUTEX_FLAG 1
// #define RWLOCK_FLAG 2
// #define SPIN_FLAG 3
// #define RCU_FLAG 4
// #define FUTEX_FLAG 5
#define MUTEX_FLAG 1
#define RWLOCK_FLAG 2
#define SPIN_FLAG 3
#define RCU_FLAG 4
#define FUTEX_FLAG 5
typedef long long unsigned int u64;
typedef unsigned int u32;
#define MAX_STACK_DEPTH 128
Expand Down
103 changes: 79 additions & 24 deletions eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,32 +534,86 @@ static int print_mfutex(void *ctx, void *data,unsigned long data_sz)
time_t now = time(NULL);// 获取当前时间
struct tm *localTime = localtime(&now);// 将时间转换为本地时间结构
printf("%02d:%02d:%02d ",localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
printf("%-12s 0x%x %-10d %-16llu %-11llu %-11lu | ",mfutex_type[e->type],e->lock_ptr,e->owner,e->start_hold_time,e->last_owner,e->last_hold_delay);

int err,record_lock_fd =bpf_map__fd(mfutex_skel->maps.record_lock);

struct record_lock_key lookup_key = {-1,-1}, next_key;
while(!bpf_map_get_next_key(record_lock_fd, &lookup_key, &next_key)){
// printf("next_key:%x target_ptr:%x\n",next_key,e->lock_ptr);
if(next_key.lock_ptr != e->lock_ptr) {
lookup_key = next_key;
continue;//不是目标锁,跳过
}
struct per_request per_request = {};
err = bpf_map_lookup_elem(record_lock_fd,&next_key,&per_request);
if (err < 0) {
// printf(stderr, "failed to lookup info: %d\n", err);
lookup_key = next_key;
continue;//不是目标锁,跳过
int type = e->type;
if(type == MUTEX_FLAG){
printf("%-12s 0x%-8x %-11llu %-11lu %-16llu %-10d\n",mfutex_type[e->type],e->lock_ptr,e->last_owner,e->last_hold_delay,e->start_hold_time,e->owner);
printf("%-81s","");
int err,record_lock_fd =bpf_map__fd(mfutex_skel->maps.record_lock);
struct record_lock_key lookup_key1 = {-1,-1}, next_key;
while(!bpf_map_get_next_key(record_lock_fd, &lookup_key1, &next_key)){
// printf("next_key:%x target_ptr:%x\n",next_key,e->lock_ptr);
if(next_key.lock_ptr != e->lock_ptr) {
lookup_key1 = next_key;
continue;//不是目标锁,跳过
}
struct per_request per_request = {};
err = bpf_map_lookup_elem(record_lock_fd,&next_key,&per_request);
if (err < 0) {
// printf(stderr, "failed to lookup info: %d\n", err);
lookup_key1 = next_key;
continue;//不是目标锁,跳过
}
float wait_delay = (e->start_hold_time-per_request.start_request_time)/1000000000.0;
if(wait_delay<=0||wait_delay>=10000)
printf("%d(NULL)|",per_request.pid);
else printf("%d(%ds)|",per_request.pid,((e->start_hold_time-per_request.start_request_time)/1000000000));
lookup_key1 = next_key;
}
}else if(type == FUTEX_FLAG){
printf("%-12s 0x%-8x %-11s %-11s %-16llu ",mfutex_type[e->type],e->lock_ptr,"NULL","NULL",e->start_hold_time);
int err,futex_wake_queue_fd =bpf_map__fd(mfutex_skel->maps.futex_wake_queue);
struct lock_record_key lookup_key1 = {-1,-1}, next_key;
while(!bpf_map_get_next_key(futex_wake_queue_fd, &lookup_key1, &next_key)){
// printf("next_key:%x target_ptr:%x\n",next_key,e->lock_ptr);
if(next_key.lock_ptr != e->lock_ptr) {
lookup_key1 = next_key;
continue;//不是目标锁,跳过
}
struct per_request per_request = {};
err = bpf_map_lookup_elem(futex_wake_queue_fd,&next_key,&per_request);
if (err < 0) {
// printf(stderr, "failed to lookup info: %d\n", err);
lookup_key1 = next_key;
continue;//不是目标锁,跳过
}

float wait_delay = (e->start_hold_time-per_request.start_request_time)/1000000000.0;
if(wait_delay<=0||wait_delay>=10000)
printf("%d(NULL)| ",per_request.pid);
else printf("%d(%ds)| ",per_request.pid,((e->start_hold_time-per_request.start_request_time)/1000000000));
err = bpf_map_delete_elem(futex_wake_queue_fd, &next_key);
if (err < 0) {
fprintf(stderr, "failed to cleanup infos: %d\n", err);
return -1;
}
lookup_key1 = next_key;
}
printf("\n%-81s","");
int err2,futex_wait_queue_fd =bpf_map__fd(mfutex_skel->maps.futex_wait_queue);
struct lock_record_key lookup_key2 = {-1,-1};
while(!bpf_map_get_next_key(futex_wait_queue_fd, &lookup_key2, &next_key)){
// printf("next_key:%x target_ptr:%x\n",next_key,e->lock_ptr);
if(next_key.lock_ptr != e->lock_ptr) {
lookup_key2 = next_key;
continue;//不是目标锁,跳过
}
struct per_request per_request = {};
err2 = bpf_map_lookup_elem(futex_wait_queue_fd,&next_key,&per_request);
if (err2 < 0) {
// printf(stderr2, "failed to lookup info: %d\n", err2);
lookup_key2 = next_key;
continue;//不是目标锁,跳过
}

float wait_delay = (e->start_hold_time-per_request.start_request_time)/1000000000.0;
if(wait_delay<=0||wait_delay>=10000)
printf("%d(NULL)| ",per_request.pid);
else printf("%d(%ds)| ",per_request.pid,((e->start_hold_time-per_request.start_request_time)/1000000000));
lookup_key2 = next_key;
}
float wait_delay = (e->start_hold_time-per_request.start_request_time)/1000000000.0;
if(wait_delay<=0||wait_delay>=10000)
printf("%d(NULL) | ",per_request.pid);
else printf("%d(%ds) | ",per_request.pid,((e->start_hold_time-per_request.start_request_time)/1000000000));
lookup_key = next_key;
printf("\n");
}
printf("\n");

// struct record_lock_key key;
// key.lock_ptr = e->lock_ptr;
// key.cnt = 1;
Expand Down Expand Up @@ -1020,7 +1074,8 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to create mfutex ring buffer\n");
goto cleanup;
}
printf("%-8s %-12s %-10s %-10s %-16s %-11s %-11s | %10s\n","TIME","LOCK_TYPE","LOCK_Addr","Holder","HoldTime","Last_Holder","Last_Delay","Wait_Proc");
printf("============================================ MFutex ============================================\n");
printf("%-8s %-12s %-10s %-11s %-11s %-16s %-15s\n","TIME","LOCK_TYPE","LOCK_Addr","Last_Holder","Last_Delay","HoldTime","Waker/Waiter");
}

if(env.enable_keytime){
Expand Down

0 comments on commit 3f6096c

Please sign in to comment.