Skip to content

Commit

Permalink
kvm_watcher:合并为主程序,对vcpu挂起轮询时间变化的监控 (#609)
Browse files Browse the repository at this point in the history
* 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
nanshuaibo authored Dec 1, 2023
1 parent 51cbed6 commit 70a9bf6
Show file tree
Hide file tree
Showing 14 changed files with 790 additions and 812 deletions.
15 changes: 7 additions & 8 deletions .github/workflows/kvm_watcher.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@ jobs:
sudo apt install linux-tools-$(uname -r)
sudo apt install linux-cloud-tools-$(uname -r)
sudo modprobe kvm
- name: Run kvm_exits
- name: Run kvm_watcher
run: |
cd eBPF_Supermarket/kvm_watcher/vm_exits
cd eBPF_Supermarket/kvm_watcher/
make
sudo ./kvm_exits -t 5
- name: Run kvm_vcpu
run: |
cd eBPF_Supermarket/kvm_watcher/vcpu
make
sudo ./kvm_vcpu -w -t 5
sudo ./kvm_watcher -w -t 5
sudo ./kvm_watcher -e -t 5 -s
sudo ./kvm_watcher -n -t 5
make clean
Original file line number Diff line number Diff line change
Expand Up @@ -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
125 changes: 125 additions & 0 deletions eBPF_Supermarket/kvm_watcher/include/kvm_exits.h
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(&times, &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(&times, &tid);
if(reas){
u32 reason;
struct exit_event *e;
int count=0;
duration_ns=bpf_ktime_get_ns() - reas->time;
bpf_map_delete_elem(&times, &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 */


87 changes: 87 additions & 0 deletions eBPF_Supermarket/kvm_watcher/include/kvm_vcpu.h
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 */
62 changes: 62 additions & 0 deletions eBPF_Supermarket/kvm_watcher/include/kvm_watcher.h
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 */
73 changes: 73 additions & 0 deletions eBPF_Supermarket/kvm_watcher/src/kvm_watcher.bpf.c
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;
}
Loading

0 comments on commit 70a9bf6

Please sign in to comment.