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
vvzxy authored Jun 21, 2024
2 parents 66725fc + 6ac98b6 commit 8646cfd
Show file tree
Hide file tree
Showing 21 changed files with 2,510 additions and 147 deletions.
1,177 changes: 1,177 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/cpu_watcher/grafana_cpu_watcher_dashboard.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ INCLUDES := -I$(OUTPUT) -I../../../libbpf/include/uapi -I$(dir $(VMLINUX)) -I$(L
CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)

APPS = lifecycle_image lock_image newlife_image keytime_image
APPS = lifecycle_image lock_image newlife_image keytime_image migrate_image

CARGO ?= $(shell which cargo)
ifeq ($(strip $(CARGO)),)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2023 The LMP Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// author: [email protected]

#include "vmlinux.h"
#include <bpf/bpf_helpers.h> //包含了BPF 辅助函数
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>
#include "migrate_image.h"

char LICENSE[] SEC("license") = "Dual BSD/GPL";
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(pid_t));
__uint(value_size, sizeof(struct migrate_event));
__uint(max_entries, 128);
} migrate SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
__uint(max_entries, 16);
} t SEC(".maps");

SEC("tracepoint/sched/sched_migrate_task")
int tracepoint_sched_migrate_task(struct trace_event_raw_sched_migrate_task *args){
u64 time = bpf_ktime_get_ns();//当前转移时间点;
pid_t pid = args->pid;
struct migrate_event *migrate_event;
migrate_event = bpf_map_lookup_elem(&migrate,&pid);
if(!migrate_event){
int key = 0,*count=bpf_map_lookup_elem(&t,&key);
if(!count){
int init = 1;
bpf_map_update_elem(&t,&key,&init,BPF_ANY);
}
else *count +=1;

struct migrate_event migrate_event = {};
migrate_event.pid = pid;
migrate_event.prio = args->prio;
migrate_event.migrate_info[0].time = time;
migrate_event.migrate_info[0].orig_cpu = args->orig_cpu;
migrate_event.migrate_info[0].dest_cpu = args->dest_cpu;
migrate_event.count = 1;
bpf_map_update_elem(&migrate, &pid, &migrate_event, BPF_ANY);
}
/*&& (migrate_event->migrate_info + migrate_event->count) < (migrate_event->migrate_info + MAX_MIGRATE)*/
else if(migrate_event->count>0 && migrate_event->count<MAX_MIGRATE
&& (migrate_event->migrate_info + migrate_event->count) < (migrate_event->migrate_info + MAX_MIGRATE) )
{
migrate_event->migrate_info[migrate_event->count].time = time;
migrate_event->migrate_info[migrate_event->count].orig_cpu = args->orig_cpu;
migrate_event->migrate_info[migrate_event->count++].dest_cpu = args->dest_cpu;
}
else if(migrate_event->count>=MAX_MIGRATE)
{
migrate_event->migrate_info[migrate_event->count % MAX_MIGRATE].time = time;
migrate_event->migrate_info[migrate_event->count % MAX_MIGRATE].orig_cpu = args->orig_cpu;
migrate_event->migrate_info[migrate_event->count % MAX_MIGRATE].dest_cpu = args->dest_cpu;
migrate_event->count++;
migrate_event->rear ++;
}

//bpf_printk("Time:%llu\tpid:%d\tcomm:%s\tprio:%d\torig_cpu:%d\tdest_cpu:%d\t\n",time,args->pid,args->comm,args->prio,args->orig_cpu,args->dest_cpu);
return 0;
}
248 changes: 248 additions & 0 deletions eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/tools/migrate_image.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
// Copyright 2023 The LMP Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://github.com/linuxkerneltravel/lmp/blob/develop/LICENSE
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// author: [email protected]

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#include <signal.h>
#include <argp.h>
#include <errno.h>
#include <time.h>
#include "migrate_image.skel.h"
#include "migrate_image.h"
#include "trace_helpers.h"

#define warn(...) fprintf(stderr, __VA_ARGS__)

static volatile bool exiting = false;
struct migrate_image_bpf *skel;
// static struct env {
// int pid;
// int time;
// int cpu_id;
// int stack_count;
// bool set_stack;
// bool enable_cs;
// } env = {
// .pid = 0,
// .time = 0,
// .cpu_id = 0,
// .stack_count = 0,
// .set_stack = false,
// .enable_cs = false,
// };

static struct ksyms *ksyms = NULL;

const char argp_program_doc[] ="Trace process to get process life cycle image.\n";

// static const struct argp_option opts[] = {
// { "pid", 'p', "PID", 0, "Process ID to trace" },
// { "cpuid", 'C', "CPUID", 0, "Set For Tracing Process 0(other processes don't need to set this parameter)" },
// { "time", 't', "TIME-SEC", 0, "Max Running Time(0 for infinite)" },
// { "cs-reason", 'r', NULL, 0, "Process context switch reasons annotation" },
// { "stack", 's', "STACK-COUNT", 0, "The number of kernel stacks printed when the process is under the CPU" },
// { NULL, 'h', NULL, OPTION_HIDDEN, "show the full help" },
// {},
// };

// static error_t parse_arg(int key, char *arg, struct argp_state *state)
// {
// long pid;
// long cpu_id;
// long stack;
// switch (key) {
// case 'p':
// errno = 0;
// pid = strtol(arg, NULL, 10);
// if (errno || pid < 0) {
// warn("Invalid PID: %s\n", arg);
// // 调用argp_usage函数,用于打印用法信息并退出程序
// argp_usage(state);
// }
// env.pid = pid;
// break;
// case 'C':
// cpu_id = strtol(arg, NULL, 10);
// if(cpu_id < 0){
// warn("Invalid CPUID: %s\n", arg);
// argp_usage(state);
// }
// env.cpu_id = cpu_id;
// break;
// case 't':
// env.time = strtol(arg, NULL, 10);
// if(env.time) alarm(env.time);
// break;
// case 'r':
// env.enable_cs = true;
// break;
// case 's':
// stack = strtol(arg, NULL, 10);
// if (stack < 0) {
// warn("Invalid STACK-COUNT: %s\n", arg);
// // 调用argp_usage函数,用于打印用法信息并退出程序
// argp_usage(state);
// }
// env.stack_count = stack;
// env.set_stack = true;
// break;
// case 'h':
// argp_state_help(state, stderr, ARGP_HELP_STD_HELP);
// break;
// default:
// return ARGP_ERR_UNKNOWN;
// }

// return 0;
// }

static void sig_handler(int sig)
{
exiting = true;
}


static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
}

static int migrate_print(){
time_t now = time(NULL);// 获取当前时间
struct tm *localTime = localtime(&now);// 将时间转换为本地时间结构
printf("Time: %02d:%02d:%02d\n",localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
printf("---------------------------------------------------------------------------------\n");
int err,migrate_fd =bpf_map__fd(skel->maps.migrate),t_fd =bpf_map__fd(skel->maps.t);
int key =0,count;
err = bpf_map_lookup_elem(t_fd,&key,&count);
if (err < 0) {
fprintf(stderr, "failed to lookup infos: %d\n", err);
return -1;
}
printf("total process %d\n",count);
count = 0;
bpf_map_update_elem(t_fd,&key,&count,BPF_ANY);

pid_t lookup_key = -1 ,next_key;
struct migrate_event migrate_event;
while(!bpf_map_get_next_key(migrate_fd, &lookup_key, &next_key)){//遍历打印hash map
err = bpf_map_lookup_elem(migrate_fd,&next_key,&migrate_event);
if (err < 0) {
fprintf(stderr, "failed to lookup infos: %d\n", err);
return -1;
}
if(migrate_event.count == migrate_event.rear) {
lookup_key = next_key;
continue;
}
u64 last_time_stamp = 0;
printf("\npid:%d\tprio:%d\tcount:%d\trear:%d\n",migrate_event.pid,migrate_event.prio,migrate_event.count,migrate_event.rear);
for(int i=migrate_event.rear;i<migrate_event.count;i++){
printf("time_stamp:%llu\t%d->%d\t",
migrate_event.migrate_info[i%MAX_MIGRATE].time,migrate_event.migrate_info[i%MAX_MIGRATE].orig_cpu,migrate_event.migrate_info[i%MAX_MIGRATE].dest_cpu);
if(i==migrate_event.rear && last_time_stamp == 0) {
last_time_stamp = migrate_event.migrate_info[i%MAX_MIGRATE].time;
printf("delay: /\n");
}else{
printf("delay: %d us\n",(migrate_event.migrate_info[i%MAX_MIGRATE].time - last_time_stamp)/1000);
last_time_stamp = migrate_event.migrate_info[i%MAX_MIGRATE].time;
}
}
migrate_event.rear = migrate_event.count;
bpf_map_update_elem(migrate_fd,&next_key,&migrate_event,BPF_ANY);
lookup_key = next_key;
}
printf("---------------------------------------------------------------------------------\n\n");
return 0;
}

int main(int argc, char **argv)
{
struct ring_buffer *rb = NULL;
int err;
// static const struct argp argp = {
// .options = opts,
// .parser = parse_arg,
// .doc = argp_program_doc,
// };

// err = argp_parse(&argp, argc, argv, 0, NULL, NULL);
// if (err)
// return err;


libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
/* 设置libbpf错误和调试信息回调 */
libbpf_set_print(libbpf_print_fn);

/* 更干净地处理Ctrl-C
SIGINT:由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGTERM:请求中止进程,kill命令发送
*/
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGALRM,sig_handler);

/* 打开BPF应用程序 */
skel = migrate_image_bpf__open();
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
return 1;
}

/* 加载并验证BPF程序 */
err = migrate_image_bpf__load(skel);
if (err) {
fprintf(stderr, "Failed to load and verify BPF skeleton\n");
goto cleanup;
}

ksyms = ksyms__load();
if (!ksyms) {
fprintf(stderr, "failed to load kallsyms\n");
goto cleanup;
}

/* 附加跟踪点处理程序 */
err = migrate_image_bpf__attach(skel);
if (err) {
fprintf(stderr, "Failed to attach BPF skeleton\n");
goto cleanup;
}

/* 处理事件 */
while (!exiting) {
sleep(1);
err = migrate_print();
if (err == -EINTR) {
err = 0;
break;
}
if (err < 0) {
printf("Error polling perf buffer: %d\n", err);
break;
}
}

/* 卸载BPF程序 */
cleanup:
// ring_buffer__free(rb);
migrate_image_bpf__destroy(skel);
return err < 0 ? -err : 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <asm/types.h>
#include <linux/version.h>

typedef unsigned long long u64;
typedef unsigned int u32;
/*----------------------------------------------*/
/* migrate_event结构体 */
/*----------------------------------------------*/
#define MAX_MIGRATE 16
// #define ARRY_OVERFLOW -1
struct per_migrate{//每次迁移,记录该次迁移信息;
u64 time;
u32 orig_cpu;
u32 dest_cpu;
};
//每个进程的迁移信息;
struct migrate_event{
int erro;
pid_t pid;
int prio;
int count,rear;//迁移频率
struct per_migrate migrate_info[MAX_MIGRATE];//该进程每次迁移信息;
};
Loading

0 comments on commit 8646cfd

Please sign in to comment.