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

Add the latest code comments #602

Merged
merged 1 commit into from
Nov 24, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add the latest code comments
gaoyixiang1 committed Nov 24, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 1706b4653dcf3350f72b3ffe668ba5251b422855
46 changes: 30 additions & 16 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/io_count.bpf.c
Original file line number Diff line number Diff line change
@@ -24,8 +24,10 @@
#include "stack_analyzer.h"
#include "task.h"


//定义的哈希表以及堆栈跟踪对象
BPF_HASH(psid_count, psid, u64);
BPF_STACK_TRACE(stack_trace);
BPF_STACK_TRACE(stack_trace); //记录了相应的函数内核栈以及用户栈的使用次数
BPF_HASH(pid_tgid, u32, u32);
BPF_HASH(pid_comm, u32, comm);

@@ -39,50 +41,52 @@ static int do_stack(struct trace_event_raw_sys_enter *ctx)
{
// u64 td = bpf_get_current_pid_tgid();
// u32 pid = td >> 32;
struct task_struct* curr = (struct task_struct*)bpf_get_current_task();
u32 pid = get_task_ns_pid(curr);

struct task_struct* curr = (struct task_struct*)bpf_get_current_task();//利用bpf_get_current_task()获得当前的进程tsk
u32 pid = get_task_ns_pid(curr); //利用帮助函数获得当前进程的pid

if ((apid >= 0 && pid != apid) || !pid)
return 0;

u64 len = (u64)BPF_CORE_READ(ctx, args[3]);
u64 len = (u64)BPF_CORE_READ(ctx, args[3]); //从当前ctx中读取64位的值,并保存在len中,
if (len <= min || len > max)
return 0;

// u32 tgid = td;
u32 tgid = get_task_ns_tgid(curr);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
if (!p)
u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获取进程的tgid
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //将pid_tgid表中的pid选项更新为tgid,若没有该表项,则创建
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm哈希表中的pid表项对应的value
if (!p) //如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid name项,则更新
{
comm name;
bpf_get_current_comm(&name, COMM_LEN);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
}
psid apsid = {
.pid = pid,
.usid = u ? USER_STACK : -1,
.ksid = k ? KERNEL_STACK : -1,
.usid = u ? USER_STACK : -1, //u存在,则USER_STACK
.ksid = k ? KERNEL_STACK : -1, //K存在,则KERNEL_STACK
};

// record time delta
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid);
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count表当中的apsid表项,即size
if (cot)
{
if (count)
if (count) //如果count不为NULL,则对count指向的值+1
(*count)++;
else
{
u64 one = 1;
u64 one = 1; //当psid_count中不存在apsid,就更新表项中的apsid=1
bpf_map_update_elem(&psid_count, &apsid, &one, BPF_NOEXIST);
}
}
else
else //cot=false
{
if (count)
if (count) //如果count不为NULL,则对count指向的值+len
(*count) += len;
else
bpf_map_update_elem(&psid_count, &apsid, &len, BPF_NOEXIST);

bpf_map_update_elem(&psid_count, &apsid, &len, BPF_NOEXIST); //当psid_count中不存在apsid,就更新表项中的apsid=len
}
return 0;
}
@@ -95,6 +99,16 @@ static int do_stack(struct trace_event_raw_sys_enter *ctx)
// tracepoint:syscalls:sys_enter_poll
// tracepoint:syscalls:sys_enter_epoll_wait


// 1. 设置挂载点
// tracepoint/syscalls/sys_enter_write 读操作
// tracepoint/syscalls/sys_enter_read 写操作
// tracepoint/syscalls/sys_enter_recvfrom 接收数据
// tracepoint/syscalls/sys_enter_sendto 发送数据

//2. 执行程序 int prog_t_##name(struct trace_event_raw_sys_enter *ctx) { return do_stack(ctx); }
//最终调用上面的do_stack函数

io_sec_tp(write);
io_sec_tp(read);
io_sec_tp(recvfrom);
117 changes: 68 additions & 49 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/mem_count.bpf.c
Original file line number Diff line number Diff line change
@@ -24,13 +24,14 @@
#include "stack_analyzer.h"
#include "task.h"

BPF_HASH(psid_count, psid, u64);
//定义的哈希表以及堆栈跟踪对象
BPF_HASH(psid_count, psid, u64); //记录对应进程申请的总内存空间大小
BPF_STACK_TRACE(stack_trace);
BPF_HASH(pid_tgid, u32, u32);
BPF_HASH(pid_comm, u32, comm);

BPF_HASH(pid_size, u32, u64);
BPF_HASH(piddr_meminfo, piddr, mem_info);
BPF_HASH(pid_size, u32, u64); //记录了对应进程使用malloc,calloc等函数申请内存的大小
BPF_HASH(piddr_meminfo, piddr, mem_info); //记录了每次申请的内存空间的起始地址等信息

const char LICENSE[] SEC("license") = "GPL";

@@ -47,53 +48,58 @@ int gen_alloc_enter(size_t size)
// u64 pt = bpf_get_current_pid_tgid();
// u32 pid = pt >> 32;
// u32 tgid = pt;
struct task_struct *curr = (struct task_struct *)bpf_get_current_task();
struct task_struct *curr = (struct task_struct *)bpf_get_current_task(); //利用bpf_get_current_task()获得当前的进程tsk
u32 pid = get_task_ns_pid(curr); // also kernel pid, but attached ns pid on kernel pid, invaild!
u32 tgid = get_task_ns_tgid(curr);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
if (!p)
u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获得当前进程的tgid
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid哈希表中的pid项目为tgid,如果该项不存在,则创建该表项
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm哈希表中的pid表项对应的value

if (!p) //如果p不为空,获取当前进程名保存至name中,如果pid_comm当中不存在pid => name项,则更新
{
comm name;
bpf_get_current_comm(&name, COMM_LEN);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
}

// record size
return bpf_map_update_elem(&pid_size, &pid, &size, BPF_ANY);
//size为挂载点传递的值
return bpf_map_update_elem(&pid_size, &pid, &size, BPF_ANY); //更新pid_size哈希表的pid项对应的值为size,如果不存在该项,则创建
}

SEC("uprobe/malloc")

SEC("uprobe/malloc") //用户空间探针uprobe,挂载点为malloc函数
int BPF_KPROBE(malloc_enter, size_t size)
{
return gen_alloc_enter(size);
return gen_alloc_enter(size); //当用户程序执行到malloc函数,则执行gen_alloc_enter(size)
}

SEC("uprobe/calloc")

SEC("uprobe/calloc") //用户空间探针uprobe,挂载点为calloc函数
int BPF_KPROBE(calloc_enter, size_t nmemb, size_t size)
{
return gen_alloc_enter(nmemb * size);
return gen_alloc_enter(nmemb * size); //当用户程序执行到calloc函数,则执行gen_alloc_enter(size)
}

SEC("uprobe/mmap")

SEC("uprobe/mmap") //用户空间探针uprobe,挂载点为mmap函数
int BPF_KPROBE(mmap_enter)
{
size_t size = PT_REGS_PARM2(ctx);
return gen_alloc_enter(size);
size_t size = PT_REGS_PARM2(ctx); //size为该函数的第二个参数的值
return gen_alloc_enter(size); //当用户程序执行到mmap函数,则执行gen_alloc_enter(size)
}

int gen_alloc_exit(struct pt_regs *ctx)
int gen_alloc_exit(struct pt_regs *ctx) //传入的参数ctx是个pt_regs(定义在vmlinux.h)的指针
{
void *addr = (void *)PT_REGS_RC(ctx);
void *addr = (void *)PT_REGS_RC(ctx); //从 struct pt_regs ctx 中提取函数的返回值
if (!addr)
return 0;
// bpf_printk("malloc_exit");
// get size
// u32 pid = bpf_get_current_pid_tgid() >> 32;
// struct task_struct* curr = ;
u32 pid = get_task_ns_pid((struct task_struct*)bpf_get_current_task());
u64 *size = bpf_map_lookup_elem(&pid_size, &pid);
if (!size)
u32 pid = get_task_ns_pid((struct task_struct*)bpf_get_current_task());//通过bpf_get_current_task函数得到当前进程的tsk。再通过get_task_ns_pid得到该进程的pid
u64 *size = bpf_map_lookup_elem(&pid_size, &pid); //size指向pid_size哈希表pid对应的值
if (!size) //size不存在
return -1;

// record stack count
@@ -102,57 +108,63 @@ int gen_alloc_exit(struct pt_regs *ctx)
.usid = u ? USER_STACK : -1,
.ksid = k ? KERNEL_STACK: -1,
};
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid);
if (!count)
u64 *count = bpf_map_lookup_elem(&psid_count, &apsid);//count指向psid_count表apsid对应的值

if (!count) //如果count为空,,若表的apsid表项不存在,则更新psid_count表的apsid为size
bpf_map_update_elem(&psid_count, &apsid, size, BPF_NOEXIST);
else
(*count) += *size;
(*count) += *size; //psid_count表apsid对应的值+=pid_size哈希表pid对应的值


// record pid_addr-info
piddr a = {
.addr = (u64)addr,
.addr = (u64)addr, //函数的返回值
.pid = pid,
.o = 0,
};
mem_info info = {
.size = *size,
.usid = apsid.usid,
.usid = apsid.usid, //表示是在用户空间,因此设为用户栈
.o = 0,
};
return bpf_map_update_elem(&piddr_meminfo, &a, &info, BPF_NOEXIST);

return bpf_map_update_elem(&piddr_meminfo, &a, &info, BPF_NOEXIST);//如果表中不存在a这个表项,则更新piddr_meminfo表的a对应的值为info
}

SEC("uretprobe/malloc")

SEC("uretprobe/malloc") //用户空间探针uretprobe,挂载点为malloc函数
int BPF_KRETPROBE(malloc_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出malloc函数,则执行gen_alloc_exit(ctx)
}

SEC("uretprobe/calloc")

SEC("uretprobe/calloc") //用户空间探针uretprobe,挂载点为calloc函数
int BPF_KRETPROBE(calloc_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出clloc函数,则执行gen_alloc_exit(ctx)
}

SEC("uretprobe/realloc")
SEC("uretprobe/realloc") //用户空间探针uretprobe,挂载点为realloc函数
int BPF_KRETPROBE(realloc_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出realloc函数,则执行gen_alloc_exit(ctx)
}

SEC("uretprobe/mmap")

SEC("uretprobe/mmap") //用户空间探针uretprobe,挂载点为mmap函数
int BPF_KRETPROBE(mmap_exit)
{
return gen_alloc_exit(ctx);
return gen_alloc_exit(ctx); //当用户程序退出mmap函数,则执行gen_alloc_exit(ctx)
}

int gen_free_enter(u64 addr, size_t unsize)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid
// struct task_struct* curr = (struct task_struct*)bpf_get_current_task();
// u32 pid = get_task_ns_pid(curr);
piddr a = {.addr = addr, .pid = pid, .o = 0};
mem_info *info = bpf_map_lookup_elem(&piddr_meminfo, &a);
mem_info *info = bpf_map_lookup_elem(&piddr_meminfo, &a); //info指向piddr_meminfo表中的a的值
if (!info)
return -1;

@@ -162,39 +174,46 @@ int gen_free_enter(u64 addr, size_t unsize)
.pid = pid,
.usid = info->usid,
};
u64 *size = bpf_map_lookup_elem(&psid_count, &apsid);

u64 *size = bpf_map_lookup_elem(&psid_count, &apsid); //size指向psid_count中apsid对应的值,即对应pid的总空间大小
if (!size)
return -1;

// sub the freeing size
//unsize为传入的值,是代表释放的空间大小
if(unsize) {
if (unsize >= *size)
*size = 0;

if (unsize >= *size) //unsize>=psid_count中apsid对应的值
*size = 0; //psid_count中apsid对应的值 = 0
else
(*size) -= unsize;
(*size) -= unsize; //否则,psid_count中apsid对应的值-=unsize
}
else
(*size) -= info->size;
(*size) -= info->size; //unsize=0,则psid_count中apsid对应的值-=piddr_meminfo表中的a的值的size成员的值

if(!*size) bpf_map_delete_elem(&psid_count, &apsid);

// del freeing addr info
return bpf_map_delete_elem(&piddr_meminfo, &a);
return bpf_map_delete_elem(&piddr_meminfo, &a); //删除piddr_meminfo表中的a的值,因为已经释放了
}

SEC("uprobe/free")

SEC("uprobe/free") //用户空间探针uprobe,挂载点为free函数
int BPF_KPROBE(free_enter, void *addr) {
return gen_free_enter((u64)addr, 0);
return gen_free_enter((u64)addr, 0); //当用户程序执行free函数,则执行gen_free_enter(addr, 0);
}

SEC("uprobe/realloc")

SEC("uprobe/realloc") //用户空间探针uprobe,挂载点为realloc函数
int BPF_KPROBE(realloc_enter, void *ptr, size_t size)
{
gen_free_enter((u64)ptr, 0);
gen_free_enter((u64)ptr, 0); //当用户程序执行realloc函数,则执行gen_free_enter(ptr, 0),并返回gen_alloc_enter(size)
return gen_alloc_enter(size);
}

SEC("uprobe/munmap")

SEC("uprobe/munmap") //用户空间探针uprobe,挂载点为munmap函数
int BPF_KPROBE(munmap_enter, void *addr, size_t unsize) {
return gen_free_enter((u64)addr, unsize);
return gen_free_enter((u64)addr, unsize); //当用户程序执行munmap函数,则执行gen_free_enter(addr, unsize);

}
38 changes: 19 additions & 19 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/off_cpu_count.bpf.c
Original file line number Diff line number Diff line change
@@ -24,8 +24,8 @@
#include "stack_analyzer.h"
#include "task.h"

BPF_HASH(psid_count, psid, u32);
BPF_HASH(start, u32, u64);
BPF_HASH(psid_count, psid, u32); //记录了进程的运行总时间
BPF_HASH(start, u32, u64); //记录进程运行的起始时间
BPF_STACK_TRACE(stack_trace);
BPF_HASH(pid_tgid, u32, u32);
BPF_HASH(pid_comm, u32, comm);
@@ -36,42 +36,42 @@ int apid = 0;
bool u = false, k = false;
__u64 min = 0, max = 0;

SEC("kprobe/finish_task_switch.isra.0")
SEC("kprobe/finish_task_switch.isra.0") //动态挂载点finish_task_switch.isra.0
int BPF_KPROBE(do_stack, struct task_struct *curr)
{
// u32 pid = BPF_CORE_READ(curr, pid);
u32 pid = get_task_ns_pid(curr);
u32 pid = get_task_ns_pid(curr); //利用帮助函数获取当前进程tsk的pid

if ((apid >= 0 && pid == apid) || (apid < 0 && pid))
{
// record next start time
u64 ts = bpf_ktime_get_ns();
bpf_map_update_elem(&start, &pid, &ts, BPF_NOEXIST);
u64 ts = bpf_ktime_get_ns(); //ts=当前的时间戳(ns)
bpf_map_update_elem(&start, &pid, &ts, BPF_NOEXIST); //如果start表中不存在pid对应的时间,则就创建pid-->ts
}

// calculate time delta
struct task_struct *next = (struct task_struct *)bpf_get_current_task();
struct task_struct *next = (struct task_struct *)bpf_get_current_task();//next指向当前的结构体
// pid = BPF_CORE_READ(next, pid);
pid = get_task_ns_pid(next);
u64 *tsp = bpf_map_lookup_elem(&start, &pid);
pid = get_task_ns_pid(next); //利用帮助函数获取next指向的tsk的pid
u64 *tsp = bpf_map_lookup_elem(&start, &pid); //tsp指向start表中的pid的值
if (!tsp)
return 0;
bpf_map_delete_elem(&start, &pid);
u32 delta = (bpf_ktime_get_ns() - *tsp) >> 20;
bpf_map_delete_elem(&start, &pid); //存在tsp,则删除pid对应的值
u32 delta = (bpf_ktime_get_ns() - *tsp) >> 20; //delta为当前时间戳 - 原先tsp指向start表中的pid的值.代表运行时间

if ((delta <= min) || (delta > max))
return 0;

// record data
// u32 tgid = BPF_CORE_READ(next, tgid);
u32 tgid = get_task_ns_tgid(curr);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
u32 tgid = get_task_ns_tgid(curr); //利用帮助函数获取当前进程的的tgid
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //利用帮助函数更新tgid对应的pid表项
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm中pid对应的表项
if (!p)
{
comm name;
bpf_probe_read_kernel_str(&name, COMM_LEN, next->comm);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
bpf_probe_read_kernel_str(&name, COMM_LEN, next->comm); //获取next指向的进程结构体的comm,赋值给comm
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); //如果pid_comm中不存在pid项,则创建
}
psid apsid = {
.pid = pid,
@@ -80,10 +80,10 @@ int BPF_KPROBE(do_stack, struct task_struct *curr)
};

// record time delta
u32 *count = bpf_map_lookup_elem(&psid_count, &apsid);
u32 *count = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count中的apsid对应的值
if (count)
(*count) += delta;
(*count) += delta; //如果count存在,则psid_count中的apsid对应的值+=时间戳
else
bpf_map_update_elem(&psid_count, &apsid, &delta, BPF_NOEXIST);
bpf_map_update_elem(&psid_count, &apsid, &delta, BPF_NOEXIST); //如果不存在,则将psid_count表中的apsid设置为delta
return 0;
}
31 changes: 16 additions & 15 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/on_cpu_count.bpf.c
Original file line number Diff line number Diff line change
@@ -27,36 +27,37 @@ const char LICENSE[] SEC("license") = "GPL";

BPF_STACK_TRACE(stack_trace);
BPF_HASH(pid_tgid, u32, u32);
BPF_HASH(psid_count, psid, u32);
BPF_HASH(psid_count, psid, u32); //记录了内核栈以及用户栈的使用次数
BPF_HASH(pid_comm, u32, comm);

bool u = false, k = false;
__u64 min = 0, max = 0;
unsigned long *load_a = NULL;

SEC("perf_event")

SEC("perf_event") //挂载点为perf_event
int do_stack(void *ctx)
{
unsigned long load;
bpf_core_read(&load, sizeof(unsigned long), load_a);
load >>= 11;
bpf_printk("%lu %lu", load, min);
bpf_core_read(&load, sizeof(unsigned long), load_a); //load为文件中读出的地址,则该地址开始读取unsigned long大小字节的数据保存到load
load >>= 11; //load右移11
bpf_printk("%lu %lu", load, min); //输出load 以及min
if (load < min || load > max)
return 0;

// record data
struct task_struct *curr = (void *)bpf_get_current_task();
u32 pid = BPF_CORE_READ(curr, pid);
struct task_struct *curr = (void *)bpf_get_current_task(); //curr指向当前进程的tsk
u32 pid = BPF_CORE_READ(curr, pid); //pid保存当前进程的pid
if (!pid)
return 0;
u32 tgid = BPF_CORE_READ(curr, tgid);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
u32 tgid = BPF_CORE_READ(curr, tgid); //tgid保存当前进程的tgid
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid表中的pid表项
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm中的Pid对应的值
if (!p)
{
comm name;
bpf_probe_read_kernel_str(&name, COMM_LEN, curr->comm);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
bpf_probe_read_kernel_str(&name, COMM_LEN, curr->comm); //name中保存的是当前进程tsk的进程名
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST); //更新pid_comm中的进程号对应的进程名
}
psid apsid = {
.pid = pid,
@@ -65,13 +66,13 @@ int do_stack(void *ctx)
};

// add cosunt
u32 *count = bpf_map_lookup_elem(&psid_count, &apsid);
u32 *count = bpf_map_lookup_elem(&psid_count, &apsid); //count指向psid_count对应的apsid的值
if (count)
(*count)++;
(*count)++; //count不为空,则psid_count对应的apsid的值+1
else
{
u32 orig = 1;
bpf_map_update_elem(&psid_count, &apsid, &orig, BPF_ANY);
bpf_map_update_elem(&psid_count, &apsid, &orig, BPF_ANY); //否则psid_count对应的apsid的值=1
}
return 0;
}
69 changes: 42 additions & 27 deletions eBPF_Supermarket/Stack_Analyser/libbpf/bpf/pre_count.bpf.c
Original file line number Diff line number Diff line change
@@ -38,95 +38,110 @@ BPF_HASH(page_psid, struct page *, psid);
int apid = 0;
bool u = false, k = false;
__u64 min = 0, max = 0;

SEC("fentry/page_cache_ra_unbounded") //fentry在内核函数page_cache_ra_unbounded进入时触发的挂载点

SEC("fentry/page_cache_ra_unbounded")
//定义了一个名为BPF_PROG(page_cache_ra_unbounded)的探针,该探针在page_cache_ra_unbounded的入口处被触发
int BPF_PROG(page_cache_ra_unbounded)
{
u64 td = bpf_get_current_pid_tgid();
u32 pid = td >> 32;
u32 pid = td >> 32; //获取当前进程tgid,用户空间的pid即是tgid

if ((apid >= 0 && pid != apid) || !pid)
return 0;

u32 tgid = td;
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY);
comm *p = bpf_map_lookup_elem(&pid_comm, &pid);
bpf_map_update_elem(&pid_tgid, &pid, &tgid, BPF_ANY); //更新pid_tgid表中的pid对应的值
comm *p = bpf_map_lookup_elem(&pid_comm, &pid); //p指向pid_comm表中pid对应的值
if (!p)
{
comm name;
bpf_get_current_comm(&name, COMM_LEN);
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);
bpf_get_current_comm(&name, COMM_LEN); //获取当前进程名
bpf_map_update_elem(&pid_comm, &pid, &name, BPF_NOEXIST);//在pid_comm表中更新pid对应的值
}
//栈计数的键,可以唯一标识一个用户内核栈
psid apsid = {
.pid = pid,
.usid = u ? USER_STACK : -1,
.ksid = k ? KERNEL_STACK : -1,
};

tuple *d = bpf_map_lookup_elem(&psid_util, &apsid);
// typedef struct
// {
// __u64 truth;
// __u64 expect;
// } tuple;

tuple *d = bpf_map_lookup_elem(&psid_util, &apsid); //d指向psid_util表中的apsid对应的类型为tuple的值
if (!d)
{
tuple a = {.expect = 0, .truth = 0};
bpf_map_update_elem(&psid_util, &apsid, &a, BPF_ANY);
tuple a = {.expect = 0, .truth = 0}; //初始化为0
bpf_map_update_elem(&psid_util, &apsid, &a, BPF_ANY); //更新psid_util表中的apsid的值为a
}
bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY);
bpf_map_update_elem(&in_ra, &pid, &apsid, BPF_ANY); //更新in_ra表中的pid对应的值为apsid
return 0;
}

SEC("fexit/alloc_pages")

SEC("fexit/alloc_pages") //fexit在内核函数alloc_pages退出时触发,挂载点为alloc_pages
//struct page *alloc_pages(gfp_t gfp_mask, unsigned int order); 参数分别是分配标志以及页的阶数
int BPF_PROG(filemap_alloc_folio_ret, gfp_t gfp, unsigned int order, u64 ret)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u32 pid = bpf_get_current_pid_tgid() >> 32; //pid为当前进程的pid

if ((apid >= 0 && pid != apid) || !pid)
return 0;

struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid);
struct psid *apsid = bpf_map_lookup_elem(&in_ra, &pid); //apsid指向了当前in_ra中pid的表项内容
if (!apsid)
return 0;

tuple *a = bpf_map_lookup_elem(&psid_util, apsid);
tuple *a = bpf_map_lookup_elem(&psid_util, apsid); //a是指向psid_util的apsid对应的内容
if (!a)
return 0;

const u32 lim = 1ul << order;
a->expect += lim;
const u32 lim = 1ul << order; //1 为长整型,左移order位,即2^order 即申请页的大小
a->expect += lim; //a->expect+=页大小(未访问)
u64 addr;
bpf_core_read(&addr, sizeof(u64), &ret);
bpf_core_read(&addr, sizeof(u64), &ret); //alloc_pages返回的值,即申请页的起始地址保存在addr中
for (int i = 0; i < lim && i < 1024; i++, addr += 0x1000)
bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY);
bpf_map_update_elem(&page_psid, &addr, apsid, BPF_ANY);//更新page_psid表中的addr(从页的起始地址开始到页的结束地址)所对应的值为apsid

return 0;
}

SEC("fexit/page_cache_ra_unbounded")
int BPF_PROG(page_cache_ra_unbounded_ret)
int BPF_PROG(page_cache_ra_unbounded_ret) //fexit在内核函数page_cache_ra_unbounded退出时触发的挂载点
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid

if ((apid >= 0 && pid != apid) || !pid)
return 0;

bpf_map_delete_elem(&in_ra, &pid);
bpf_map_delete_elem(&in_ra, &pid); //删除了in_ra对应的pid的表项,即删除对应的栈计数信息
return 0;
}

SEC("fentry/mark_page_accessed")

SEC("fentry/mark_page_accessed") //fentry在内核函数/mark_page_accessed进入时触发的挂载点

//void mark_page_accessed(struct page *page);用于标记页面(page)已经被访问

int BPF_PROG(mark_page_accessed, u64 page)
{
u32 pid = bpf_get_current_pid_tgid() >> 32;
u32 pid = bpf_get_current_pid_tgid() >> 32; //获取当前进程的pid

if ((apid >= 0 && pid != apid) || !pid)
return 0;
psid *apsid;
apsid = bpf_map_lookup_elem(&page_psid, &page);
apsid = bpf_map_lookup_elem(&page_psid, &page); //查看page_psid对应的 地址page 对应类型为psid的值,并保存在apsid
if (!apsid)
return 0;
tuple *a = bpf_map_lookup_elem(&psid_util, apsid);
tuple *a = bpf_map_lookup_elem(&psid_util, apsid); //a指向psid_util的apsid的内容
if (!a)
return 0;
a->truth++;
bpf_map_delete_elem(&page_psid, &page);
a->truth++; //已访问
bpf_map_delete_elem(&page_psid, &page); //删除page_psid的page对应的内容
return 0;
}