-
Notifications
You must be signed in to change notification settings - Fork 175
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #803 from Super-Lzzx/develop
mem_wather:添加缺页异常检测代码
- Loading branch information
Showing
5 changed files
with
343 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# mem_watcher可视化 | ||
## 配置环境 | ||
在使用mem_watcher可视化之前,请先配置docker、go的环境,具体配置方法可参考: | ||
### 配置docker | ||
[在 Ubuntu 上安装 Docker Desktop |Docker 文档](https://docs.docker.com/desktop/install/ubuntu/#install-docker-desktop) | ||
[在 Linux 上安装 Docker Desktop |Docker 文档](https://docs.docker.com/desktop/install/linux-install/) | ||
### go环境 | ||
配置好dacker环境后接着配置go的环境 | ||
我们首先对我们现有的工具进行编译 | ||
- 首先先进入lmp目录下的`lmp/eBPF_Supermarket/Memory_Subsystem/mem_watcher`文件夹 | ||
然后进行编译,其实这一步也可以忽略掉 | ||
```c | ||
make -j 20 | ||
``` | ||
- 在lmp目录下的`eBPF_Visualization/eBPF_prometheus`文件夹下 | ||
- 执行make指令,编译可视化的go语言工具 | ||
- 执行`make start_service`指令,配置下载docker镜像并启动grafana和prometheus服务 | ||
- 执行如下指令开始采集数据以及相关处理: | ||
```c | ||
./data-visual collect /home/ubuntu/lmp/eBPF_Supermarket/Memory_Subsystem/mem_watcher -p | ||
``` | ||
切记根据自己的文件所在目录进行修改,如果不知道或者不确定的可以在自己的程序文件下输入`pwd`命令进行查看,如果目录出现错误会失败。 | ||
|
||
在网页打开网址:http://81.70.204.7:8090/metrics 此处为localhost:8090/metrics,便可以看到http网页中的数据; | ||
这个网址需要根据你自己的虚拟机的ip进行修改。 | ||
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a2aab03835bf44ca8a27023c8c445bad.png) | ||
- 在网页打开网址:http://81.70.204.7:3000/ 即可进入grafana服务,使用初始密码登录(user:admin pswd: admin)进入管理界面: | ||
- 点击【Home-Connection-Add new connection】,选择Prometheus,建立与Prometheus服务器的连接: | ||
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1e41ec78f5fa4923a5a1e18cab233c62.png) | ||
|
||
这个172.17.0.1表示docker0网桥的 IPv4 地址。在 Docker 中,通常会将docker0的第一个 IP 地址分配给Docker主机自身。因此,172.17.0.1是 Docker主机上Docker守护进程的 IP 地址,所以在Grafana数据源这块设置成http://172.17.0.1:9090 ,然后点击下面的【Save & test】按钮 | ||
- 进入可视化配置界面: | ||
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6e37ecb4c62245b2a68a80dc07643ac9.png) | ||
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/fbdb65ef1cc54c128594a96cad5e2386.png) | ||
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4f3a33b65929429b96b683e573593938.png) | ||
## mem_watcher子工具可视化输出(样例) | ||
### mem_watcher -p | ||
- reclaimed | ||
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/eed35e475ba6422ca176f966b011902c.png) | ||
可以进行压力测试 | ||
首先使用`sudo apt-get install stress`安装压力测试工具。 | ||
使用下面的命令对内存进行施压 `stress -m 3 --vm-bytes 300M` | ||
会生成3个进程,每个进程占用300M内存。 |
114 changes: 114 additions & 0 deletions
114
eBPF_Supermarket/Memory_Subsystem/old_project/time/Makefile
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,114 @@ | ||
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) | ||
OUTPUT := .output | ||
CLANG ?= clang | ||
LIBBPF_SRC := $(abspath ../../libbpf/src) | ||
BPFTOOL_SRC := $(abspath ../../bpftool/src) | ||
LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a) | ||
BPFTOOL_OUTPUT ?= $(abspath $(OUTPUT)/../bpftool) | ||
BPFTOOL ?= $(BPFTOOL_OUTPUT)/bootstrap/bpftool | ||
|
||
ARCH ?= $(shell uname -m | sed 's/x86_64/x86/' \ | ||
| sed 's/arm.*/arm/' \ | ||
| sed 's/aarch64/arm64/' \ | ||
| sed 's/ppc64le/powerpc/' \ | ||
| sed 's/mips.*/mips/' \ | ||
| sed 's/riscv64/riscv/' \ | ||
| sed 's/loongarch64/loongarch/') | ||
VMLINUX := ../../vmlinux/$(ARCH)/vmlinux.h | ||
# Use our own libbpf API headers and Linux UAPI headers distributed with | ||
# libbpf to avoid dependency on system-wide headers, which could be missing or | ||
# outdated | ||
INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX)) | ||
CFLAGS := -g -Wall | ||
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) | ||
|
||
APPS = time | ||
|
||
# Get Clang's default includes on this system. We'll explicitly add these dirs | ||
# to the includes list when compiling with `-target bpf` because otherwise some | ||
# architecture-specific dirs will be "missing" on some architectures/distros - | ||
# headers such as asm/types.h, asm/byteorder.h, asm/socket.h, asm/sockios.h, | ||
# sys/cdefs.h etc. might be missing. | ||
# | ||
# Use '-idirafter': Don't interfere with include mechanics except where the | ||
# build would have failed anyways. | ||
CLANG_BPF_SYS_INCLUDES = $(shell $(CLANG) -v -E - </dev/null 2>&1 \ | ||
| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') | ||
|
||
ifeq ($(V),1) | ||
Q = | ||
msg = | ||
else | ||
Q = @ | ||
msg = @printf ' %-8s %s%s\n' \ | ||
"$(1)" \ | ||
"$(patsubst $(abspath $(OUTPUT))/%,%,$(2))" \ | ||
"$(if $(3), $(3))"; | ||
MAKEFLAGS += --no-print-directory | ||
endif | ||
|
||
define allow-override | ||
$(if $(or $(findstring environment,$(origin $(1))),\ | ||
$(findstring command line,$(origin $(1)))),,\ | ||
$(eval $(1) = $(2))) | ||
endef | ||
|
||
$(call allow-override,CC,$(CROSS_COMPILE)cc) | ||
$(call allow-override,LD,$(CROSS_COMPILE)ld) | ||
|
||
.PHONY: all | ||
all: $(APPS) | ||
|
||
.PHONY: clean | ||
clean: | ||
$(call msg,CLEAN) | ||
$(Q)rm -rf $(OUTPUT) $(APPS) | ||
|
||
$(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT): | ||
$(call msg,MKDIR,$@) | ||
$(Q)mkdir -p $@ | ||
|
||
# Build libbpf | ||
$(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf | ||
$(call msg,LIB,$@) | ||
$(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \ | ||
OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \ | ||
INCLUDEDIR= LIBDIR= UAPIDIR= \ | ||
install | ||
|
||
# Build bpftool | ||
$(BPFTOOL): | $(BPFTOOL_OUTPUT) | ||
$(call msg,BPFTOOL,$@) | ||
$(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap | ||
|
||
# Build BPF code | ||
$(OUTPUT)/%.bpf.o: %.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT) $(BPFTOOL) | ||
$(call msg,BPF,$@) | ||
$(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) \ | ||
$(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) \ | ||
-c $(filter %.c,$^) -o $(patsubst %.bpf.o,%.tmp.bpf.o,$@) | ||
$(Q)$(BPFTOOL) gen object $@ $(patsubst %.bpf.o,%.tmp.bpf.o,$@) | ||
|
||
# Generate BPF skeletons | ||
$(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL) | ||
$(call msg,GEN-SKEL,$@) | ||
$(Q)$(BPFTOOL) gen skeleton $< > $@ | ||
|
||
# Build user-space code | ||
$(patsubst %,$(OUTPUT)/%.o,$(APPS)): %.o: %.skel.h | ||
|
||
$(OUTPUT)/%.o: %.c $(wildcard %.h) | $(OUTPUT) | ||
$(call msg,CC,$@) | ||
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@ | ||
|
||
# Build application binary | ||
$(APPS): %: $(OUTPUT)/%.o $(LIBBPF_OBJ) | $(OUTPUT) | ||
$(call msg,BINARY,$@) | ||
$(Q)$(CC) $(CFLAGS) $^ $(ALL_LDFLAGS) -lelf -lz -o $@ | ||
|
||
# delete failed targets | ||
.DELETE_ON_ERROR: | ||
|
||
# keep intermediate (.skel.h, .bpf.o, etc) targets | ||
.SECONDARY: | ||
|
67 changes: 67 additions & 0 deletions
67
eBPF_Supermarket/Memory_Subsystem/old_project/time/time.bpf.c
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,67 @@ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "time.h" | ||
|
||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
struct { | ||
__uint(type, BPF_MAP_TYPE_HASH); | ||
__uint(max_entries, 8192); | ||
__type(key, pid_t); | ||
__type(value, u64); | ||
} exec_start SEC(".maps"); | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
//动态挂载 | ||
SEC("kprobe/handle_mm_fault") | ||
int BPF_KPROBE(handle_mm_fault_enter) | ||
{ | ||
unsigned int pid; | ||
u64 current_time; | ||
pid=bpf_get_current_pid_tgid();//pid | ||
|
||
current_time= bpf_ktime_get_ns()/1000;//挂载前进程时间 | ||
bpf_map_update_elem(&exec_start, &pid, ¤t_time, BPF_ANY);//更新map元素 | ||
|
||
//bpf_printk("KPROBE ENTRY pid=%d,comm=%s,state=%d,current_time=%d\n",pid,comm,state,current_time); | ||
return 0; | ||
} | ||
|
||
SEC("kretprobe/handle_mm_fault") | ||
int BPF_KRETPROBE(handle_mm_fault_exit) | ||
{ | ||
struct task_struct *t = (struct task_struct *)bpf_get_current_task();//获取task_struct结构体数据 | ||
struct event *e; | ||
unsigned int pid; | ||
u64 *start_ts; | ||
u64 duration_ns = 0; | ||
char comm[20]; | ||
|
||
/* get PID and TID of exiting thread/process */ | ||
|
||
pid = bpf_get_current_pid_tgid(); | ||
|
||
start_ts=bpf_map_lookup_elem(&exec_start,&pid); | ||
if (!start_ts) | ||
return 0; | ||
duration_ns = bpf_ktime_get_ns()/1000 - *start_ts;//获取系统进程执行时间 | ||
bpf_map_delete_elem(&exec_start,&pid);//删除当前进程pid对应键值对 | ||
//ringbuf提交 | ||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);//malloc | ||
if (!e) | ||
return 0; | ||
|
||
e->duration_ns=duration_ns; | ||
e->pid=pid; | ||
bpf_get_current_comm(&e->comm,sizeof(e->comm)); | ||
e->state=BPF_CORE_READ(t,__state); | ||
bpf_ringbuf_submit(e, 0); | ||
return 0; | ||
} | ||
|
102 changes: 102 additions & 0 deletions
102
eBPF_Supermarket/Memory_Subsystem/old_project/time/time.c
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,102 @@ | ||
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) | ||
/* Copyright (c) 2020 Facebook */ | ||
#include <argp.h> | ||
#include <signal.h> | ||
#include <stdio.h> | ||
#include <time.h> | ||
#include <sys/resource.h> | ||
#include <bpf/libbpf.h> | ||
#include "time.h" | ||
#include "time.skel.h" | ||
|
||
|
||
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) | ||
{ | ||
//if (level == LIBBPF_DEBUG && !env.verbose) | ||
// return 0; | ||
return vfprintf(stderr, format, args); | ||
} | ||
|
||
static volatile bool exiting = false; | ||
|
||
static void sig_handler(int sig) | ||
{ | ||
exiting = true; | ||
} | ||
|
||
static int handle_event(void *ctx, void *data, size_t data_sz) | ||
{ | ||
const struct event *e = data; | ||
printf("%-8d %-5d %-16lld %-7s\n", e->pid, e->state, e->duration_ns,e->comm); | ||
return 0; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
struct ring_buffer *rb = NULL; | ||
struct time_bpf *skel; | ||
int 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); | ||
|
||
/* Load and verify BPF application */ | ||
skel = time_bpf__open(); | ||
if (!skel) { | ||
fprintf(stderr, "Failed to open and load BPF skeleton\n"); | ||
return 1; | ||
} | ||
|
||
/* Load & verify BPF programs */ | ||
err = time_bpf__load(skel); | ||
if (err) { | ||
fprintf(stderr, "Failed to load and verify BPF skeleton\n"); | ||
goto cleanup; | ||
} | ||
|
||
/* Attach tracepoints */ | ||
err = time_bpf__attach(skel); | ||
if (err) { | ||
fprintf(stderr, "Failed to attach BPF skeleton\n"); | ||
goto cleanup; | ||
} | ||
|
||
/* Set up ring buffer polling */ | ||
rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_event, NULL, NULL); | ||
if (!rb) { | ||
err = -1; | ||
fprintf(stderr, "Failed to create ring buffer\n"); | ||
goto cleanup; | ||
} | ||
|
||
/* Process events */ | ||
|
||
while (!exiting) { | ||
err = ring_buffer__poll(rb, 100 /* timeout, ms */); | ||
/* Ctrl-C will cause -EINTR */ | ||
if (err == -EINTR) { | ||
err = 0; | ||
break; | ||
} | ||
if (err < 0) { | ||
printf("Error polling perf buffer: %d\n", err); | ||
break; | ||
} | ||
} | ||
|
||
cleanup: | ||
/* Clean up */ | ||
ring_buffer__free(rb); | ||
time_bpf__destroy(skel); | ||
|
||
return err < 0 ? -err : 0; | ||
} | ||
|
||
|
||
|
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,17 @@ | ||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | ||
/* Copyright (c) 2020 Facebook */ | ||
#ifndef __BOOTSTRAP_H | ||
#define __BOOTSTRAP_H | ||
|
||
#define TASK_COMM_LEN 16 | ||
#define MAX_FILENAME_LEN 127 | ||
|
||
struct event { | ||
int pid; | ||
unsigned int state; | ||
unsigned long long duration_ns; | ||
bool exit_event; | ||
char comm[TASK_COMM_LEN]; | ||
}; | ||
|
||
#endif /* __BOOTSTRAP_H */ |