-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kvm_watcher:合并为主程序,对vcpu挂起轮询时间变化的监控 (#609)
* Upload 2023.6.29 会议纪要.md * Add files via upload * 上传2023.8.4会议纪要 * Update 2023.8.4 会议纪要.md * Add files via upload * add kvm_watcher dir * modify directory name * add kvm_watcher.yml * update yml * update .yml * update kvm_exit.c * update .yml * load kvm mod * 添加文件头信息 * 优化结果输出 * Update kvm_exits.bpf.c 优化代码格式 * 调整Action文件 * Update kvm_exits.c * Update kvm_exits.c * update kvm_exit.c * update kvm_exits.c * 修改变量名称 * modify dir name * add vcpu dir * Update kvm_watcher.yml Update kvm_watcher.yml * Update kvm_watcher.yml * Update kvm_watcher.yml * update action * update vcpu * 修改Makefile,删除vmlinux.h头文件 * 1 * 合并为主程序 * 更改缩进 * 调整代码缩进 * 调整代码缩进 * 调整代码缩进 * 调整代码缩进 * 调整代码缩进 * 修改action * 修改action * vcpu_halt_poll_ns * update kvm_watcher.c * update * 修改action * 删除可执行文件 * 删除可执行文件 * 调整代码缩进 * 完善代码逻辑 * 完善代码逻辑 * 调整代码缩进
- Loading branch information
1 parent
51cbed6
commit 70a9bf6
Showing
14 changed files
with
790 additions
and
812 deletions.
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
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 |
---|---|---|
|
@@ -5,19 +5,20 @@ ARCH ?= $(shell uname -m | sed 's/x86_64/x86/' \ | |
| sed 's/mips.*/mips/' \ | ||
| sed 's/riscv64/riscv/' \ | ||
| sed 's/loongarch64/loongarch/') | ||
APP = kvm_vcpu | ||
APP = src/kvm_watcher | ||
|
||
all: $(APP) | ||
|
||
.PHONY: $(APP) | ||
$(APP): | ||
ifeq ($(wildcard ./vmlinux.h),) | ||
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h | ||
ifeq ($(wildcard ./include/vmlinux.h),) | ||
bpftool btf dump file /sys/kernel/btf/vmlinux format c > ./include/vmlinux.h | ||
endif | ||
clang -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) -I/usr/include/x86_64-linux-gnu -I. -c [email protected] -o [email protected] | ||
bpftool gen skeleton [email protected] > [email protected] | ||
clang -g -O2 -Wall -I . -c [email protected] -o [email protected] | ||
clang -Wall -O2 -g [email protected] -static -lbpf -lelf -lz -o $@ | ||
clang -Wall -O2 -g [email protected] -static -lbpf -lelf -lz -o $(notdir $@) | ||
|
||
clean: | ||
rm -f *.o *.skel.h $(APP) vmlinux.h | ||
cd src && rm -f *.o *.skel.h | ||
rm -f $(notdir $(APP)) include/vmlinux.h |
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 |
---|---|---|
@@ -0,0 +1,125 @@ | ||
// 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] | ||
// | ||
// Kernel space BPF program used for counting VM exit reason. | ||
|
||
#ifndef __KVM_EXITS_H | ||
#define __KVM_EXITS_H | ||
|
||
#include "kvm_watcher.h" | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 8192); | ||
__type(key, pid_t); | ||
__type(value, struct reason_info); | ||
} times SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 8192); | ||
__type(key, u32); | ||
__type(value, u32); | ||
} counts SEC(".maps"); | ||
|
||
struct exit{ | ||
u64 pad; | ||
unsigned int exit_reason; | ||
unsigned long guest_rip; | ||
u32 isa; | ||
u64 info1; | ||
u64 info2; | ||
u32 intr_info; | ||
u32 error_code; | ||
unsigned int vcpu_id; | ||
}; | ||
|
||
int total=0; | ||
|
||
static int trace_kvm_exit(struct exit *ctx, pid_t vm_pid) | ||
{ | ||
u64 id,ts; | ||
id = bpf_get_current_pid_tgid(); | ||
pid_t tid = (u32)id; | ||
pid_t pid = id >> 32; | ||
if (vm_pid < 0 || pid == vm_pid){ | ||
ts = bpf_ktime_get_ns(); | ||
u32 reason; | ||
reason=(u32)ctx->exit_reason; | ||
struct reason_info reas={}; | ||
reas.reason=reason; | ||
reas.time=ts; | ||
u32 *count; | ||
count=bpf_map_lookup_elem(&counts, &reason); | ||
if(count){ | ||
(*count)++; | ||
reas.count=*count; | ||
}else{ | ||
u32 new_count = 1; | ||
reas.count=new_count; | ||
bpf_map_update_elem(&counts, &reason, &new_count, BPF_ANY); | ||
} | ||
bpf_map_update_elem(×, &tid, &reas, BPF_ANY); | ||
} | ||
return 0; | ||
} | ||
|
||
static int trace_kvm_entry(void *rb) | ||
{ | ||
struct reason_info *reas; | ||
pid_t pid, tid; | ||
u64 id, ts, *start_ts, duration_ns=0; | ||
id = bpf_get_current_pid_tgid(); | ||
pid = id >> 32; | ||
tid = (u32)id; | ||
reas = bpf_map_lookup_elem(×, &tid); | ||
if(reas){ | ||
u32 reason; | ||
struct exit_event *e; | ||
int count=0; | ||
duration_ns=bpf_ktime_get_ns() - reas->time; | ||
bpf_map_delete_elem(×, &tid); | ||
reason=reas->reason; | ||
count=reas->count; | ||
e = bpf_ringbuf_reserve(rb, sizeof(*e), 0); | ||
if (!e){ | ||
return 0; | ||
} | ||
e->reason_number=reason; | ||
e->process.pid=pid; | ||
e->duration_ns = duration_ns; | ||
bpf_get_current_comm(&e->process.comm, sizeof(e->process.comm)); | ||
e->process.tid=tid; | ||
e->total=++total; | ||
if (count) { | ||
e->count = count; | ||
} else { | ||
e->count = 1; | ||
} | ||
bpf_ringbuf_submit(e, 0); | ||
return 0; | ||
} | ||
else{ | ||
return 0; | ||
} | ||
} | ||
#endif /* __KVM_EXITS_H */ | ||
|
||
|
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 |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// 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] | ||
// | ||
// Kernel space BPF program used for monitoring data for vCPU HLT. | ||
|
||
#ifndef __KVM_VCPU_H | ||
#define __KVM_VCPU_H | ||
|
||
#include "kvm_watcher.h" | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
struct vcpu_wakeup{ | ||
u64 pad; | ||
__u64 ns; | ||
bool waited; | ||
bool vaild; | ||
}; | ||
|
||
struct halt_poll_ns{ | ||
u64 pad; | ||
bool grow; | ||
unsigned int vcpu_id; | ||
unsigned int new; | ||
unsigned int old; | ||
}; | ||
|
||
static int trace_kvm_vcpu_wakeup(struct vcpu_wakeup *ctx,void *rb,pid_t vm_pid) | ||
{ | ||
unsigned pid = bpf_get_current_pid_tgid() >> 32; | ||
if (vm_pid < 0 || pid == vm_pid){ | ||
u32 tid = bpf_get_current_pid_tgid(); | ||
struct vcpu_wakeup_event *e; | ||
e = bpf_ringbuf_reserve(rb, sizeof(*e), 0); | ||
if (!e){ | ||
return 0; | ||
} | ||
u64 hlt_time = bpf_ktime_get_ns(); | ||
e->waited = ctx->waited; | ||
e->process.pid = pid; | ||
e->process.tid = tid; | ||
e->dur_hlt_ns = ctx->ns; | ||
e->hlt_time = hlt_time; | ||
bpf_get_current_comm(&e->process.comm, sizeof(e->process.comm)); | ||
bpf_ringbuf_submit(e, 0); | ||
} | ||
return 0; | ||
} | ||
|
||
static int trace_kvm_halt_poll_ns(struct halt_poll_ns *ctx,void *rb,pid_t vm_pid) | ||
{ | ||
unsigned pid = bpf_get_current_pid_tgid() >> 32; | ||
if (vm_pid < 0 || pid == vm_pid){ | ||
u32 tid = bpf_get_current_pid_tgid(); | ||
struct halt_poll_ns_event *e; | ||
e = bpf_ringbuf_reserve(rb, sizeof(*e), 0); | ||
if (!e) | ||
return 0; | ||
u64 time = bpf_ktime_get_ns(); | ||
e->process.pid = pid; | ||
e->process.tid = tid; | ||
e->time = time; | ||
e->grow=ctx->grow; | ||
e->old=ctx->old; | ||
e->new=ctx->new; | ||
bpf_get_current_comm(&e->process.comm, sizeof(e->process.comm)); | ||
bpf_ringbuf_submit(e, 0); | ||
} | ||
return 0; | ||
} | ||
|
||
#endif /* __KVM_VCPU_H */ |
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 |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// 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] | ||
// | ||
// BPF program used for monitoring KVM event. | ||
|
||
#ifndef __KVM_WATCHER_H | ||
#define __KVM_WATCHER_H | ||
|
||
#define TASK_COMM_LEN 16 | ||
|
||
struct process{ | ||
unsigned pid; | ||
unsigned tid; | ||
char comm[TASK_COMM_LEN]; | ||
}; | ||
struct vcpu_wakeup_event { | ||
struct process process; | ||
unsigned long long dur_hlt_ns; | ||
bool waited; | ||
unsigned long long hlt_time; | ||
}; | ||
|
||
struct exit_event { | ||
struct process process; | ||
unsigned reason_number; | ||
unsigned long long duration_ns; | ||
int count; | ||
int total; | ||
}; | ||
|
||
struct ExitReason { | ||
int number; | ||
const char* name; | ||
}; | ||
|
||
struct reason_info { | ||
unsigned long long time; | ||
unsigned long reason; | ||
int count; | ||
}; | ||
|
||
struct halt_poll_ns_event { | ||
struct process process; | ||
bool grow; | ||
unsigned int new; | ||
unsigned int old; | ||
unsigned long long time; | ||
}; | ||
#endif /* __KVM_WATCHER_H */ |
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 |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// 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] | ||
// | ||
// Kernel space BPF program used for monitoring data for KVM event. | ||
|
||
#include "../include/vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include "../include/kvm_watcher.h" | ||
#include "../include/kvm_vcpu.h" | ||
#include "../include/kvm_exits.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
|
||
const volatile pid_t vm_pid = -1; | ||
const volatile bool execute_vcpu_wakeup=false; | ||
const volatile bool execute_exit=false; | ||
const volatile bool execute_halt_poll_ns=false; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
SEC("tp/kvm/kvm_vcpu_wakeup") | ||
int tp_vcpu_wakeup(struct vcpu_wakeup *ctx) | ||
{ | ||
if(execute_vcpu_wakeup){ | ||
trace_kvm_vcpu_wakeup(ctx,&rb,vm_pid); | ||
} | ||
return 0; | ||
} | ||
|
||
SEC("tp/kvm/kvm_halt_poll_ns") | ||
int tp_kvm_halt_poll_ns(struct halt_poll_ns *ctx) | ||
{ | ||
if(execute_halt_poll_ns){ | ||
trace_kvm_halt_poll_ns(ctx,&rb,vm_pid); | ||
} | ||
return 0; | ||
} | ||
|
||
SEC("tp/kvm/kvm_exit") | ||
int tp_exit(struct exit *ctx) | ||
{ | ||
if(execute_exit){ | ||
trace_kvm_exit(ctx,vm_pid); | ||
} | ||
return 0; | ||
} | ||
|
||
SEC("tp/kvm/kvm_entry") | ||
int tp_entry(struct exit *ctx) | ||
{ | ||
if(execute_exit){ | ||
trace_kvm_entry(&rb); | ||
} | ||
return 0; | ||
} |
Oops, something went wrong.