-
Notifications
You must be signed in to change notification settings - Fork 173
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
优化代码输出结果 #578
Merged
Merged
优化代码输出结果 #578
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
1edfd84
Upload 2023.6.29 会议纪要.md
nanshuaibo 2d0eea9
Merge branch 'linuxkerneltravel:develop' into develop
nanshuaibo f5caeb1
Add files via upload
nanshuaibo c41296e
Merge branch 'linuxkerneltravel:develop' into develop
nanshuaibo 071a871
上传2023.8.4会议纪要
nanshuaibo 38a20ba
Update 2023.8.4 会议纪要.md
nanshuaibo 687dab7
Merge branch 'linuxkerneltravel:develop' into develop
nanshuaibo ecd9e61
Add files via upload
nanshuaibo 8860390
Merge branch 'linuxkerneltravel:develop' into develop
nanshuaibo 6afcb1a
add kvm_watcher dir
nanshuaibo 62764a3
modify directory name
nanshuaibo 398a108
add kvm_watcher.yml
nanshuaibo 3269f7b
update yml
nanshuaibo 8d07c57
update .yml
nanshuaibo b8d639d
update kvm_exit.c
nanshuaibo 57f1f1c
update .yml
nanshuaibo 5bdfba7
load kvm mod
nanshuaibo 90aa90a
添加文件头信息
nanshuaibo 4955ce5
Merge branch 'linuxkerneltravel:develop' into develop
nanshuaibo 1a61d23
优化结果输出
nanshuaibo f25e04c
Update kvm_exits.bpf.c
nanshuaibo 90cd78b
调整Action文件
nanshuaibo 40d54a6
Merge branch 'develop' of github.com:nanshuaibo/lmp into develop
nanshuaibo 1d72cef
Update kvm_exits.c
nanshuaibo 3e62c21
Update kvm_exits.c
nanshuaibo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,4 +31,4 @@ jobs: | |
run: | | ||
cd eBPF_Supermarket/kvm_watcher/kvm_exits | ||
make | ||
sudo ./kvm_exits | ||
sudo ./kvm_exits -t 5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,14 +18,18 @@ | |
|
||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <signal.h> | ||
#include <sys/resource.h> | ||
#include <time.h> | ||
#include <argp.h> | ||
#include <bpf/libbpf.h> | ||
#include "kvm_exits.skel.h" | ||
#include "kvm_exits.h" | ||
|
||
// 存储所有退出原因的映射关系 | ||
|
||
// 存储所有exit reason的映射关系 | ||
// from arch/x86/include/uapi/asm/vmx.h | ||
struct ExitReason exitReasons[] = { | ||
{0, "EXCEPTION_NMI"}, | ||
|
@@ -102,6 +106,163 @@ const char* getExitReasonName(int number) { | |
return "Unknown"; // 如果找不到对应的退出原因,返回一个默认值 | ||
} | ||
|
||
typedef struct { | ||
int exit_reason; | ||
char info[256]; // 替换成适当的大小 | ||
unsigned long long total_dur; | ||
unsigned long long avg_dur; | ||
} ExitInfo; | ||
|
||
// 链表节点 | ||
typedef struct Node { | ||
ExitInfo data; | ||
struct Node* next; | ||
} Node; | ||
|
||
Node* exitInfoBuffer = NULL; | ||
|
||
void addExitInfo(Node** head, int exit_reason, const char* info,unsigned long long dur,int count) { | ||
Node* newNode = (Node*)malloc(sizeof(Node)); | ||
newNode->data.exit_reason = exit_reason; | ||
strncpy(newNode->data.info, info, sizeof(newNode->data.info)); | ||
newNode->next = NULL; | ||
newNode->data.total_dur = dur; | ||
newNode->data.avg_dur = dur / count; | ||
|
||
// 检查是否已经存在相同 exit reason 的信息 | ||
Node* current = *head; | ||
Node* previous = NULL; | ||
while (current != NULL) { | ||
if (current->data.exit_reason == exit_reason) { | ||
// 更新已存在的信息 | ||
strncpy(current->data.info, info, sizeof(current->data.info)); | ||
current->data.total_dur=dur+current->data.total_dur; | ||
current->data.avg_dur=current->data.total_dur/count; | ||
free(newNode); // 释放新节点,因为信息已经更新 | ||
return; | ||
} | ||
previous = current; | ||
current = current->next; | ||
} | ||
// 没有找到相同的 exit reason,将新节点添加到链表 | ||
if (previous != NULL) { | ||
previous->next = newNode; | ||
} else { | ||
*head = newNode; | ||
} | ||
} | ||
|
||
// 查找指定退出原因的信息 | ||
const char* findExitInfo(Node* head, int exit_reason) { | ||
Node* current = head; | ||
while (current != NULL) { | ||
if (current->data.exit_reason == exit_reason) { | ||
return current->data.info; | ||
} | ||
current = current->next; | ||
} | ||
return NULL; | ||
} | ||
|
||
// 释放链表 | ||
void freeExitInfoList(Node* head) { | ||
while (head != NULL) { | ||
Node* temp = head; | ||
head = head->next; | ||
free(temp); | ||
} | ||
} | ||
|
||
void printExitInfo(Node* head) { | ||
Node* current = head; | ||
printf("%-23s %-10s %-14s %-8s %-13s \n", "EXIT_REASON", "COMM","PID/TID","COUNT","AVG_DURATION(ns)"/*,"PCT"*/); | ||
while (current != NULL) { | ||
printf("%-2d/%-20s %-32s %-13llu \n", current->data.exit_reason,getExitReasonName(current->data.exit_reason), current->data.info,current->data.avg_dur); | ||
current = current->next; | ||
} | ||
} | ||
|
||
int doesVmProcessExist(pid_t pid) { | ||
char proc_name[256]; | ||
snprintf(proc_name, sizeof(proc_name), "/proc/%d/cmdline", pid); | ||
FILE *file = fopen(proc_name, "r"); | ||
if (file) { | ||
size_t size; | ||
size = fread(proc_name, 1, sizeof(proc_name), file); | ||
if (size > 0) { | ||
if (proc_name[size - 1] == '\n') { | ||
proc_name[size - 1] = '\0'; // Remove newline character | ||
} | ||
if (strstr(proc_name, "qemu-system-x86_64") != NULL) { | ||
fclose(file); | ||
return 1; // VmProcess name contains the target string | ||
} else { | ||
fclose(file); | ||
fprintf(stderr, "Process exist!but is not vmprocess: %d\n", pid); | ||
return 0; // VmProcess name does not contain the target string | ||
} | ||
} | ||
fclose(file); | ||
} | ||
fprintf(stderr, "Process name does not find: %d\n", pid); | ||
return 0; // VmProcess with the given PID not found | ||
} | ||
|
||
static struct env { | ||
int monitoring_time; | ||
pid_t vm_pid; | ||
} env={ | ||
.monitoring_time=0, | ||
.vm_pid=0, | ||
}; | ||
|
||
const char *argp_program_version = "kvm_exits 1.0"; | ||
const char *argp_program_bug_address = "<[email protected]>"; | ||
const char argp_program_doc[] = "BPF program used for outputting VM exit reason\n"; | ||
|
||
static const struct argp_option opts[] = { | ||
{ "monitoring_time", 't', "TIME-SEC", 0, "Set the time for profiling VM exit event reasons" }, | ||
{ "vm_pid", 'p', "PID", 0, "Specify the virtual machine pid to monitor." }, | ||
{}, | ||
}; | ||
|
||
static error_t parse_arg(int key, char *arg, struct argp_state *state) | ||
{ | ||
switch (key) { | ||
case 't': | ||
errno = 0; | ||
env.monitoring_time = strtol(arg, NULL, 10); | ||
if (errno || env.monitoring_time <= 0) { | ||
fprintf(stderr, "Invalid duration: %s\n", arg); | ||
argp_usage(state); | ||
} | ||
else{ | ||
alarm(env.monitoring_time); | ||
} | ||
break; | ||
case 'p': | ||
env.vm_pid=strtol(arg, NULL, 10); | ||
if(env.vm_pid<=0 || doesVmProcessExist(env.vm_pid)==0 ){ | ||
fprintf(stderr, "Invalid vm_pid: %s\n", arg); | ||
argp_usage(state); | ||
} | ||
break; | ||
case ARGP_KEY_ARG: | ||
argp_usage(state); | ||
break; | ||
default: | ||
return ARGP_ERR_UNKNOWN; | ||
} | ||
return 0; | ||
} | ||
|
||
static const struct argp argp = { | ||
.options = opts, | ||
.parser = parse_arg, | ||
.doc = argp_program_doc, | ||
}; | ||
|
||
|
||
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) | ||
{ | ||
return vfprintf(stderr, format, args); | ||
|
@@ -112,38 +273,47 @@ static volatile bool exiting = false; | |
static void sig_handler(int sig) | ||
{ | ||
exiting = true; | ||
printf("\n"); | ||
printf("---------------------------------------------------------------------------\n"); | ||
printExitInfo(exitInfoBuffer); | ||
freeExitInfoList(exitInfoBuffer); | ||
} | ||
|
||
static int handle_event(void *ctx, void *data, size_t data_sz) | ||
{ | ||
const struct event *e = data; | ||
printf("%-2d/%-20s %-10s %-5u/%-8u %-10d %-12llu %.2f%%\n", e->reason_number,getExitReasonName(e->reason_number), e->comm, e->pid,e->tid,e->count,e->duration_ns,(double)e->count / e->total * 100.0); | ||
|
||
char info_buffer[256]; | ||
printf("%-2d/%-20s %-10s %-5u/%-8u %-8d %-13llu \n", e->reason_number,getExitReasonName(e->reason_number), e->comm, e->pid,e->tid,e->count,e->duration_ns/*,(double)e->count / e->total * 100.0*/); | ||
snprintf(info_buffer, sizeof(info_buffer), "%-10s %-5u/%-8u %-8d", e->comm, e->pid,e->tid,e->count); | ||
addExitInfo(&exitInfoBuffer,e->reason_number,info_buffer,e->duration_ns,e->count); | ||
return 0; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
struct ring_buffer *rb = NULL; | ||
struct ring_buffer *rb = NULL; | ||
struct kvm_exits_bpf *skel; | ||
int err; | ||
|
||
alarm(3); | ||
/* Parse command line arguments */ | ||
err = argp_parse(&argp, argc, argv, 0, NULL, NULL); | ||
if (err) | ||
return err; | ||
|
||
/* Set up libbpf errors and debug info callback */ | ||
libbpf_set_print(libbpf_print_fn); | ||
|
||
/* Cleaner handling of Ctrl-C */ | ||
signal(SIGINT, sig_handler); | ||
signal(SIGTERM, sig_handler); | ||
signal(SIGALRM, sig_handler); | ||
signal(SIGALRM, sig_handler); | ||
/* Open BPF application */ | ||
skel = kvm_exits_bpf__open(); | ||
if (!skel) { | ||
fprintf(stderr, "Failed to open BPF skeleton\n"); | ||
return 1; | ||
} | ||
|
||
skel->rodata->vm_pid = env.vm_pid; | ||
/* Load & verify BPF programs */ | ||
err = kvm_exits_bpf__load(skel); | ||
if (err) { | ||
|
@@ -166,7 +336,7 @@ int main(int argc, char **argv) | |
goto cleanup; | ||
} | ||
/* Process events */ | ||
printf("%-23s %-10s %-14s %-10s %-11s %-10s \n", "EXIT_REASON", "COMM","PID/TID","COUNT","DURATION(ns)","PCT"); | ||
printf("%-23s %-10s %-14s %-8s %-13s \n", "EXIT_REASON", "COMM","PID/TID","COUNT","DURATION(ns)"/*,"PCT"*/); | ||
while (!exiting) { | ||
err = ring_buffer__poll(rb, 10 /* timeout, ms */); | ||
/* Ctrl-C will cause -EINTR */ | ||
|
@@ -180,6 +350,7 @@ int main(int argc, char **argv) | |
} | ||
} | ||
cleanup: | ||
/* Clean up */ | ||
ring_buffer__free(rb); | ||
kvm_exits_bpf__destroy(skel); | ||
return -err; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里是缩进了 2 个 tab 吗?