Skip to content

Commit

Permalink
添加新功能sys,数据处理部分修整完毕
Browse files Browse the repository at this point in the history
  • Loading branch information
albertxu216 committed Feb 2, 2024
1 parent 0651ba4 commit a4d98ad
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 757 deletions.
89 changes: 85 additions & 4 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <bpf/libbpf.h>
#include <sys/select.h>
#include <unistd.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#include "cpu_watcher.h"
#include "sar.skel.h"
#include "cs_delay.skel.h"
Expand All @@ -34,12 +36,14 @@ static struct env {
bool enable_proc;
bool SAR;
bool CS_DELAY;
int freq;

} env = {
.time = 0,
.enable_proc = false,
.SAR = false,
.CS_DELAY = false,
.freq = 99,
};

struct cs_delay_bpf *cs_skel;
Expand All @@ -51,6 +55,7 @@ u64 sched = 0;
u64 proc = 0;
unsigned long ktTime = 0;
unsigned long utTime = 0;
u64 tick_user = 0;//初始化sys;

/*设置传参*/
const char argp_program_doc[] ="cpu wacher is in use ....\n";
Expand Down Expand Up @@ -102,6 +107,43 @@ static void sig_handler(int sig)
exiting = true;
}

/*perf_event*/
static int nr_cpus;
static int open_and_attach_perf_event(int freq, struct bpf_program *prog,
struct bpf_link *links[])
{
struct perf_event_attr attr = {
.type = PERF_TYPE_SOFTWARE,
.freq = 99,
.sample_period = freq,
.config = PERF_COUNT_SW_CPU_CLOCK,
};
int i, fd;

for (i = 0; i < nr_cpus; i++) {
fd = syscall(__NR_perf_event_open, &attr, -1, i, -1, 0);
if (fd < 0) {
/* Ignore CPU that is offline */
if (errno == ENODEV)
continue;
fprintf(stderr, "failed to init perf sampling: %s\n",
strerror(errno));
return -1;
}
links[i] = bpf_program__attach_perf_event(prog, fd);
if (libbpf_get_error(links[i])) {
fprintf(stderr, "failed to attach perf event on cpu: "
"%d\n", i);
links[i] = NULL;
close(fd);
return -1;
}
}

return 0;
}


u64 find_ksym(const char* target_symbol) {
FILE *file = fopen("/proc/kallsyms", "r");
if (file == NULL) {
Expand Down Expand Up @@ -220,11 +262,29 @@ static int print_all()
}
unsigned long dtaUT = utTime -_utTime;

/*sys*/
int key_sys = 0,next_key;
int err_sys, fd_sys = bpf_map__fd(sar_skel->maps.tick_user);
u64 __tick_user =0 ;// 用于存储从映射中查找到的值
__tick_user = tick_user;
//tick_user = 0;
err_sys = bpf_map_lookup_elem(fd_sys, &key_sys, &tick_user);
if (err_sys < 0) {
fprintf(stderr, "failed to lookup infos of sys: %d\n", err_sys);
return -1;
}
u64 dtaTickUser = tick_user - __tick_user;
u64 dtaUTRaw = dtaTickUser/(99.0000) * 1000000000;
u64 dtaSysc = abs(dtaUT - dtaUTRaw);
u64 dtaSys = dtaKT + dtaSysc ;

if(env.enable_proc){
time_t now = time(NULL);
struct tm *localTime = localtime(&now);
printf("%02d:%02d:%02d %8llu %8llu %8llu %8llu %8llu %10lu %13lu\n",
localTime->tm_hour, localTime->tm_min, localTime->tm_sec,__proc,__sched,dtairqtime/1000,dtasoftirq/1000,dtaidle/1000000,dtaKT/1000,dtaUT/1000);
printf("%02d:%02d:%02d %8llu %8llu %8llu %10llu %8llu %8llu %8llu %8lu %8lu\n",
localTime->tm_hour, localTime->tm_min, localTime->tm_sec,
__proc,__sched,dtairqtime/1000,dtasoftirq/1000,dtaidle/1000000,
dtaKT/1000,dtaSysc / 1000000,dtaUTRaw/1000000,dtaSys / 1000000);
}
else{
env.enable_proc = true;
Expand Down Expand Up @@ -318,11 +378,26 @@ int main(int argc, char **argv)
if (err)
return err;
const char* symbol_name = "total_forks";
struct bpf_link *links[MAX_CPU_NR] = {};
libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
libbpf_set_print(libbpf_print_fn);
/* Cleaner handling of Ctrl-C */
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);

nr_cpus = libbpf_num_possible_cpus();
if (nr_cpus < 0) {
fprintf(stderr, "failed to get # of possible cpus: '%s'!\n",
strerror(-nr_cpus));
return 1;
}
if (nr_cpus > MAX_CPU_NR) {
fprintf(stderr, "the number of cpu cores is too big, please "
"increase MAX_CPU_NR's value and recompile");
return 1;
}


if (env.CS_DELAY)
{
/* Load and verify BPF application */
Expand Down Expand Up @@ -368,15 +443,21 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto sar_cleanup;
}

/*perf_event加载*/
err = open_and_attach_perf_event(env.freq, sar_skel->progs.tick_update, links);
if (err)
goto sar_cleanup;

err = sar_bpf__attach(sar_skel);
if (err)
{
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto sar_cleanup;
}
//printf(" time proc/s cswch/s runqlen irqTime/us softirq/us idle/ms kthread/us sysc/ms utime/ms sys/ms BpfCnt\n");
printf(" time proc/s cswch/s irqTime/us softirq/us idle/ms kthread/us uthread/ms\n");
}
printf(" time proc/s cswch/s irqTime/us softirq/us idle/ms kthread/us sysc/ms utime/ms sys/ms\n");
}
while (!exiting) {
sleep(1);
if(env.SAR){
Expand Down
2 changes: 1 addition & 1 deletion eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

typedef long long unsigned int u64;
typedef unsigned int u32;

#define MAX_CPU_NR 128
/*----------------------------------------------*/
/* cs_delay结构体 */
/*----------------------------------------------*/
Expand Down
58 changes: 55 additions & 3 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/sar.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ BPF_ARRAY(idleLastTime,u32,u64,1);
BPF_ARRAY(kt_LastTime,u32,u64,1);
// 储存cpu运行用户线程的时间
BPF_ARRAY(ut_LastTime,u32,u64,1);
BPF_ARRAY(tick_user,u32,u64,1);
BPF_ARRAY(symAddr,u32,u64,1);
// 统计fork数
SEC("kprobe/finish_task_switch.isra.0")
//SEC("kprobe/finish_task_switch.isra.0")
SEC("kprobe/finish_task_switch")
int kprobe__finish_task_switch(struct pt_regs *ctx)
{
u32 key = 0;
Expand Down Expand Up @@ -74,7 +77,8 @@ int trace_sched_switch2(struct cswch_args *info) {
return 0;
}

SEC("kprobe/finish_task_switch.isra.0")
SEC("kprobe/finish_task_switch")
//SEC("kprobe/finish_task_switch.isra.0")
int BPF_KPROBE(finish_task_switch,struct task_struct *prev){
pid_t pid=BPF_CORE_READ(prev,pid);
u64 *val, time = bpf_ktime_get_ns();
Expand All @@ -93,7 +97,7 @@ int BPF_KPROBE(finish_task_switch,struct task_struct *prev){
val = bpf_map_lookup_elem(&procStartTime, &pid);
if (val) {
u32 key = 0;
delta = (time - *val)/1000;
delta = (time - *val);
val = bpf_map_lookup_elem(&ut_LastTime, &key);
if (val) *val += delta;
else bpf_map_update_elem(&ut_LastTime, &key, &delta, BPF_ANY);
Expand Down Expand Up @@ -193,3 +197,51 @@ int trace_cpu_idle(struct idleStruct *pIDLE) {
}
return 0;
}

static __always_inline int user_mode(struct pt_regs *regs)
{
#ifdef CONFIG_X86_32
return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >= USER_RPL;
#else
return !!(regs->cs & 3);
#endif
}
// 两个CPU各自会产生一个调用,这正好方便我们使用
SEC("perf_event")
int tick_update(struct pt_regs *ctx) {

// bpf_trace_printk("cs_rpl = %x\n", ctx->cs & 3);
u32 key = 0;
u64 val, *valp;

// 记录用户态时间,直接从头文件arch/x86/include/asm/ptrace.h中引用
if (user_mode(ctx)) {
u64 initval = 1;
valp = bpf_map_lookup_elem(&tick_user, &key);
if (valp) *valp += 1;
else bpf_map_update_elem(&tick_user, &key, &initval, BPF_ANY);
}

unsigned long total_forks;

// if(forks_addr !=0){
// valp = (u64 *)forks_addr;
// bpf_probe_read_kernel(&total_forks, sizeof(unsigned long), valp);
// key = 1;
// val = total_forks;
// bpf_map_update_elem(&countMap,&key,&val,BPF_ANY);
// }

valp = bpf_map_lookup_elem(&symAddr, &key);
if (valp) {
void *addr = (void *)(*valp);
if (addr > 0) {
bpf_probe_read_kernel(&total_forks, sizeof(unsigned long), addr);
key = 1;
val = total_forks;
bpf_map_update_elem(&countMap, &key, &val, BPF_ANY);
}
}

return 0;
}
Loading

0 comments on commit a4d98ad

Please sign in to comment.