Skip to content

Commit

Permalink
Merge branch 'linuxkerneltravel:develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
syxl-time authored May 23, 2024
2 parents 0a88c4f + 9ae9062 commit 1d77eac
Show file tree
Hide file tree
Showing 378 changed files with 372,886 additions and 147 deletions.
14 changes: 14 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,20 @@ $(TARGETS): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
$(call msg,BINARY,$@)
$(Q)$(CC) $(CFLAGS) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@

SUCCESS_MESSAGE:
@echo "\e[38;2;255;0;0m __ __ \e[0m"
@echo "\e[38;2;255;128;0m _________ __ __ _ ______ _/ /______/ /_ ___ _____\e[0m"
@echo "\e[38;2;255;255;0m / ___/ __ \/ / / / | | /| / / __ / __/ ___/ __ \/ _ \/ ___/\e[0m"
@echo "\e[38;2;128;255;0m/ /__/ /_/ / /_/ / | |/ |/ / /_/ / /_/ /__/ / / / __/ / \e[0m"
@echo "\e[38;2;0;255;0m\___/ .___/\__,_/ |__/|__/\__,_/\__/\___/_/ /_/\___/_/ \e[0m"
@echo "\e[38;2;0;255;128m /_/ \e[0m"
@echo "\e[38;2;0;255;255mSuccessful to compile cpu_watcher tools: \e[0m"
@echo "\e[38;2;0;255;255mPlease start your use ~ \e[0m"


all: $(TARGETS) SUCCESS_MESSAGE


# delete failed targets
.DELETE_ON_ERROR:

Expand Down
123 changes: 100 additions & 23 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/cpu_watcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
#include <time.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include <sys/sysinfo.h>
#include <sys/select.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#include "cpu_watcher.h"
Expand All @@ -35,6 +38,7 @@

typedef long long unsigned int u64;
typedef unsigned int u32;
#define MAX_BUF 512

struct list_head {
struct list_head *next;
Expand All @@ -50,6 +54,8 @@ struct msg_msg {

static struct env {
int time;
int period;
bool percent;
bool enable_proc;
bool SAR;
bool CS_DELAY;
Expand All @@ -60,6 +66,8 @@ static struct env {
int freq;
} env = {
.time = 0,
.period = 1,
.percent = false,
.enable_proc = false,
.SAR = false,
.CS_DELAY = false,
Expand Down Expand Up @@ -87,6 +95,7 @@ unsigned long ktTime = 0;
unsigned long utTime = 0;
u64 tick_user = 0;


int sc_sum_time = 0 ;
int sc_max_time = 0 ;
int sc_min_time = SYSCALL_MIN_TIME ;
Expand All @@ -102,12 +111,14 @@ int preempt_start_print = 0 ;
const char argp_program_doc[] ="cpu wacher is in use ....\n";
static const struct argp_option opts[] = {
{ "time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)" },
{ "period", 'i', "INTERVAL", 0, "Period interval in seconds" },
{"percent",'P',0,0,"format data as percentages"},
{"libbpf_sar", 's', 0,0,"print sar_info (the data of cpu)"},
{"cs_delay", 'c', 0,0,"print cs_delay (the data of cpu)"},
{"syscall_delay", 'S', 0,0,"print syscall_delay (the data of syscall)"},
{"preempt_time", 'p', 0,0,"print preempt_time (the data of preempt_schedule)"},
{"schedule_delay", 'd', 0,0,"print schedule_delay (the data of cpu)"},
{"mq_delay", 'm', 0,0,"print mq_delay"},
{"mq_delay", 'm', 0,0,"print mq_delay(the data of proc)"},
{ NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" },
{0},
};
Expand All @@ -118,6 +129,12 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
env.time = strtol(arg, NULL, 10);
if(env.time) alarm(env.time);
break;
case 'i':
env.period = strtol(arg, NULL, 10);
break;
case 'P':
env.percent = true;
break;
case 's':
env.SAR = true;
break;
Expand Down Expand Up @@ -219,6 +236,7 @@ u64 find_ksym(const char* target_symbol) {

static int print_all()
{
int nprocs = get_nprocs();
/*proc:*/
int key_proc = 1;
int err_proc, fd_proc = bpf_map__fd(sar_skel->maps.countMap);
Expand Down Expand Up @@ -334,10 +352,30 @@ static int print_all()
if(env.enable_proc){
time_t now = time(NULL);
struct tm *localTime = localtime(&now);
printf("%02d:%02d:%02d %8llu %8llu %6d %8llu %10llu %8llu %10lu %8llu %8llu %8llu\n",
if (env.percent == true){
printf("%02d:%02d:%02d %8llu %8llu %6d ",localTime->tm_hour, localTime->tm_min, localTime->tm_sec,__proc, __sched, runqlen);
// 大于百分之60的标红输出
double values[7] = {
(double)dtairqtime / 10000000 / nprocs / env.period,
(double)dtasoftirq / 10000000 / nprocs / env.period,
(double)dtaidle / 10000000 / nprocs / env.period,
(double)dtaKT / 10000000 / nprocs / env.period,
(double)dtaSysc / 10000000 / nprocs / env.period,
(double)dtaUTRaw / 10000000 / nprocs / env.period,
(double)dtaSys / 10000000 / nprocs / env.period
};
for (int i = 0; i < 7; i++) {
if (values[i] > 60.0) {
printf("\033[1;31m"); // 设置为红色
}
printf("%10.2f ", values[i]);
printf("\033[0m"); // 重置为默认颜色
}
printf("\n");
}else{printf("%02d:%02d:%02d %8llu %8llu %6d %8llu %10llu %8llu %10lu %8llu %8llu %8llu\n",
localTime->tm_hour, localTime->tm_min, localTime->tm_sec,
__proc,__sched,runqlen,dtairqtime/1000,dtasoftirq/1000,dtaidle/1000000,
dtaKT/1000,dtaSysc / 1000000,dtaUTRaw/1000000,dtaSys / 1000000);
dtaKT/1000,dtaSysc / 1000000,dtaUTRaw/1000000,dtaSys / 1000000);}
}
else{
env.enable_proc = true;
Expand Down Expand Up @@ -440,6 +478,32 @@ static int preempt_print(void *ctx, void *data, unsigned long data_sz)
return 0;
}

char* get_process_name_by_pid(int pid) {
static char buf[MAX_BUF];
char command[MAX_BUF];
snprintf(command, sizeof(command), "cat /proc/%d/status | grep Name", pid);
FILE* fp = popen(command, "r");
if (fp == NULL) {
perror("popen");
return NULL;
}
char* name = NULL;
while (fgets(buf, sizeof(buf), fp)) {
if (strncmp(buf, "Name:", 5) == 0) {
name = strdup(buf + 6);
break;
}
}
pclose(fp);
if (name != NULL) {
size_t len = strlen(name);
if (len > 0 && name[len - 1] == '\n') {
name[len - 1] = '\0';
}
}
return name;
}

static int schedule_print(struct bpf_map *sys_fd)
{
int key = 0;
Expand All @@ -460,8 +524,16 @@ static int schedule_print(struct bpf_map *sys_fd)
if(!ifprint){
ifprint=1;
}else{
printf("%02d:%02d:%02d %-15lf %-15lf %5d %15lf %10d\n",
hour, min, sec, avg_delay / 1000.0, info.max_delay / 1000.0,info.pid_max, info.min_delay / 1000.0,info.pid_min);
char* proc_name_max = get_process_name_by_pid(info.pid_max);
char* proc_name_min = get_process_name_by_pid(info.pid_min);
printf("%02d:%02d:%02d %-15lf %-15lf %10s %15lf %15s\n",
hour, min, sec, avg_delay / 1000.0, info.max_delay / 1000.0,proc_name_max,info.min_delay / 1000.0,proc_name_min);
if (proc_name_max != NULL) {
free(proc_name_max);
}
if (proc_name_min != NULL) {
free(proc_name_min);
}
}
return 0;
}
Expand All @@ -470,22 +542,24 @@ static int mq_event(void *ctx, void *data,unsigned long data_sz)
{
time_t now = time(NULL);// 获取当前时间
struct tm *localTime = localtime(&now);// 将时间转换为本地时间结构
printf("\n\nTime: %02d:%02d:%02d\n",localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
printf("-----------------------------------------------------------------------------------------------------------------------\n");
const struct mq_events *e = data;

printf("Mqdes: %-8d msg_len: %-8lu msg_prio: %-8u\n",e->mqdes,e->msg_len,e->msg_prio);
printf("SND_PID: %-8d SND_enter_time: %-16llu SND_exit_time: %-16llu\n",
e->send_pid,e->send_enter_time,e->send_exit_time);
printf("RCV_PID: %-8d RCV_enter_time: %-16llu RCV_exit_time: %-16llu\n",
e->rcv_pid,e->rcv_enter_time,e->rcv_exit_time);
printf("-------------------------------------------------------------------------------\n");

printf("SND_Delay/ms: %-8.2f RCV_Delay/ms: %-8.2f Delay/ms: %-8.5f\n",
(e->send_exit_time - e->send_enter_time)/1000000.0,
(e->rcv_exit_time - e->rcv_enter_time)/1000000.0,
(e->rcv_exit_time - e->send_enter_time)/1000000.0);
printf("-----------------------------------------------------------------------------------------------------------------------\n\n");
float send_delay,rcv_delay,delay;
if(!e->send_enter_time || !e->send_exit_time || !e->rcv_enter_time || !e->rcv_exit_time) {
printf("erro!\n");
return 0;
}
send_delay = (e->send_exit_time - e->send_enter_time)/1000000.0;
rcv_delay = (e->rcv_exit_time - e->rcv_enter_time)/1000000.0;
if(e->send_enter_time < e->rcv_enter_time){
delay = (e->rcv_exit_time - e->send_enter_time)/1000000.0;
}else{
delay = (e->rcv_exit_time - e->send_enter_time)/1000000.0 + send_delay + rcv_delay;
}
printf("%02d:%02d:%02d %-8llu %-8lu %-8lu \t%-16ld %-16ld %-16ld %-16ld\t%-15.5f %-15.5f %-15.5f\n",
localTime->tm_hour, localTime->tm_min, localTime->tm_sec,
e->mqdes,e->send_pid,e->rcv_pid,
e->send_enter_time,e->send_exit_time,e->rcv_enter_time,e->rcv_exit_time,
send_delay,rcv_delay,delay);

return 0;
}
Expand Down Expand Up @@ -617,7 +691,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto schedule_cleanup;
}
printf("%-8s %s\n", " TIME ", "avg_delay/μs max_delay/μs max_pid min_delay/μs min_pid");
printf("%-8s %s\n", " TIME ", "avg_delay/μs max_delay/μs max_proc_name min_delay/μs min_proc_name");
}else if (env.SAR){
/* Load and verify BPF application */
sar_skel = sar_bpf__open();
Expand Down Expand Up @@ -646,7 +720,9 @@ int main(int argc, char **argv)
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 \n");
if (env.percent){
printf(" time proc/s cswch/s runqlen irqTime/%% softirq/%% idle/%% kthread/%% sysc/%% utime/%% sys/%% \n");
}else{printf(" time proc/s cswch/s runqlen irqTime/us softirq/us idle/ms kthread/us sysc/ms utime/ms sys/ms \n");}
}else if(env.MQ_DELAY){
/* Load and verify BPF application */
mq_skel = mq_delay_bpf__open();
Expand All @@ -669,6 +745,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto mq_delay_cleanup;
}
printf("%-8s %-8s %-8s %-8s \t%-16s %-16s %-16s %-16s\t%-15s %-15s %-15s\n","Time","Mqdes","SND_PID","RCV_PID","SND_Enter","SND_EXit","RCV_Enter","RCV_EXit","SND_Delay/ms","RCV_Delay/ms","Delay/ms");
rb = ring_buffer__new(bpf_map__fd(mq_skel->maps.rb), mq_event, NULL, NULL); //ring_buffer__new() API,允许在不使用额外选项数据结构下指定回调
if (!rb) {
err = -1;
Expand All @@ -678,7 +755,7 @@ int main(int argc, char **argv)
}
while (!exiting) {
if(env.SAR){
sleep(1);
sleep(env.period);
err = print_all();
if (err == -EINTR) {
err = 0;
Expand Down
18 changes: 18 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CC = gcc
CFLAGS = -Wall -Wextra
LDFLAGS = -lrt

.PHONY: all clean

all: test_cpuwatcher sender receiver

sender: mq_test_sender.c
$(CC) $(CFLAGS) -o sender mq_test_sender.c $(LDFLAGS)

receiver: mq_test_receiver.c
$(CC) $(CFLAGS) -o receiver mq_test_receiver.c $(LDFLAGS)

test_cpuwatcher: test_cpuwatcher.c
$(CC) $(CFLAGS) -o test_cpuwatcher test_cpuwatcher.c
clean:
rm -f test_cpuwatcher sender receiver
37 changes: 37 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_receiver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

#define QUEUE_NAME "/test_queue"
#define MSG_SIZE 50

int main() {
mqd_t mq;
char msg_buffer[MSG_SIZE];
unsigned int priority;

// 打开消息队列
mq = mq_open(QUEUE_NAME, O_RDONLY);
if (mq == (mqd_t)-1) {
perror("mq_open");
exit(1);
}

// 接收消息
while (1) {
if (mq_receive(mq, msg_buffer, MSG_SIZE, &priority) == -1) {
perror("mq_receive");
break;
}
printf("Received: %s\n", msg_buffer);
}

// 关闭消息队列
mq_close(mq);

return 0;
}
49 changes: 49 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/test/mq_test_sender.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>

#define QUEUE_NAME "/test_queue"
#define MSG_SIZE 50
#define MAX_MSGS 10

int main() {
mqd_t mq;
struct mq_attr attr;
char msg_buffer[MSG_SIZE];
unsigned int priority = 1;
int i;

// 设置消息队列属性
attr.mq_flags = 0;
attr.mq_maxmsg = MAX_MSGS;
attr.mq_msgsize = MSG_SIZE;
attr.mq_curmsgs = 0;

// 创建或打开消息队列
mq = mq_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0644, &attr);
if (mq == (mqd_t)-1) {
perror("mq_open");
exit(1);
}

// 发送消息
for (i = 0;i<60 ; i++) {
sprintf(msg_buffer, "Message %d", i);
if (mq_send(mq, msg_buffer, strlen(msg_buffer) + 1, priority) == -1) {
perror("mq_send");
break;
}
printf("Sent: %s\n", msg_buffer);
sleep(1);
}

// 关闭消息队列
mq_close(mq);
mq_unlink(QUEUE_NAME);

return 0;
}
Loading

0 comments on commit 1d77eac

Please sign in to comment.