-
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.
- Loading branch information
Showing
4 changed files
with
784 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,137 @@ | ||
# 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 | ||
LIBBLAZESYM_SRC := $(abspath ../../blazesym/) | ||
LIBBLAZESYM_INC := $(abspath $(LIBBLAZESYM_SRC)/include) | ||
LIBBLAZESYM_OBJ := $(abspath $(OUTPUT)/libblazesym.a) | ||
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)) -I$(LIBBLAZESYM_INC) | ||
CFLAGS := -g -Wall | ||
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS) | ||
|
||
APPS = mem_watcher | ||
|
||
CARGO ?= $(shell which cargo) | ||
ifeq ($(strip $(CARGO)),) | ||
BZS_APPS := | ||
else | ||
BZS_APPS := profile | ||
APPS += $(BZS_APPS) | ||
# Required by libblazesym | ||
ALL_LDFLAGS += -lrt -ldl -lpthread -lm | ||
endif | ||
|
||
# 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 | ||
|
||
|
||
$(LIBBLAZESYM_SRC)/target/release/libblazesym.a:: | ||
$(Q)cd $(LIBBLAZESYM_SRC) && $(CARGO) build --release | ||
|
||
$(LIBBLAZESYM_OBJ): $(LIBBLAZESYM_SRC)/target/release/libblazesym.a | $(OUTPUT) | ||
$(call msg,LIB, $@) | ||
$(Q)cp $(LIBBLAZESYM_SRC)/target/release/libblazesym.a $@ | ||
|
||
# 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 $@ | ||
|
||
$(patsubst %,$(OUTPUT)/%.o,$(BZS_APPS)): $(LIBBLAZESYM_OBJ) | ||
|
||
$(BZS_APPS): $(LIBBLAZESYM_OBJ) | ||
|
||
# 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: |
127 changes: 127 additions & 0 deletions
127
eBPF_Supermarket/Memory_Subsystem/mem_watcher/mem_watcher.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,127 @@ | ||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
#include <bpf/bpf_core_read.h> | ||
#include "mem_watcher.h" | ||
|
||
char LICENSE[] SEC("license") = "Dual BSD/GPL"; | ||
|
||
struct { | ||
__uint(type, BPF_MAP_TYPE_RINGBUF); | ||
__uint(max_entries, 256 * 1024); | ||
} rb SEC(".maps"); | ||
|
||
SEC("kprobe/get_page_from_freelist") | ||
int BPF_KPROBE(get_page_from_freelist, gfp_t gfp_mask, unsigned int order, int alloc_flags, const struct alloc_context *ac) | ||
{ | ||
struct event *e; | ||
unsigned long *t, y; | ||
int a; | ||
|
||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) | ||
return 0; | ||
y = BPF_CORE_READ(ac, preferred_zoneref, zone, watermark_boost); | ||
t = BPF_CORE_READ(ac, preferred_zoneref, zone, _watermark); | ||
|
||
e->present = BPF_CORE_READ(ac, preferred_zoneref, zone, present_pages); | ||
e->min = t[0] + y; | ||
e->low = t[1] + y; | ||
e->high = t[2] + y; | ||
e->flag = (int)gfp_mask; | ||
|
||
bpf_ringbuf_submit(e, 0); | ||
return 0; | ||
} | ||
|
||
SEC("kprobe/shrink_page_list") | ||
int BPF_KPROBE(shrink_page_list, struct list_head *page_list, struct pglist_data *pgdat, struct scan_control *sc) | ||
{ | ||
struct event *e; | ||
unsigned long y; | ||
unsigned int *a; | ||
|
||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) | ||
return 0; | ||
e->reclaim = BPF_CORE_READ(sc, nr_to_reclaim);//要回收页面 | ||
y = BPF_CORE_READ(sc, nr_reclaimed); | ||
e->reclaimed = y;//已经回收的页面 | ||
a =(unsigned int *)(&y + 1); | ||
e->unqueued_dirty = *(a + 1);//还没开始回写和还没在队列等待的脏页 | ||
e->congested = *(a + 2);//正在块设备上回写的页面,含写入交换空间的页面 | ||
e->writeback = *(a + 3);//正在回写的页面 | ||
|
||
|
||
|
||
bpf_ringbuf_submit(e, 0); | ||
return 0; | ||
} | ||
|
||
SEC("kprobe/finish_task_switch") | ||
int BPF_KPROBE(finish_task_switch, struct task_struct *prev) { | ||
struct event *e; | ||
struct mm_rss_stat rss = {}; | ||
struct mm_struct *mms; | ||
long long *t; | ||
|
||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) | ||
return 0; | ||
|
||
e->pid = BPF_CORE_READ(prev, pid); | ||
e->vsize = BPF_CORE_READ(prev, mm, total_vm); | ||
e->Vdata = BPF_CORE_READ(prev, mm, data_vm); | ||
e->Vstk = BPF_CORE_READ(prev, mm, stack_vm); | ||
e->nvcsw = BPF_CORE_READ(prev, nvcsw); | ||
e->nivcsw = BPF_CORE_READ(prev, nivcsw); | ||
|
||
rss = BPF_CORE_READ(prev, mm, rss_stat); | ||
t = (long long *)(rss.count); | ||
e->rssfile = *t; | ||
e->rssanon = *(t + 1); | ||
e->vswap = *(t + 2); | ||
e->rssshmem = *(t + 3); | ||
e->size = *t + *(t + 1) + *(t + 3); | ||
|
||
bpf_ringbuf_submit(e, 0); | ||
return 0; | ||
} | ||
|
||
SEC("kprobe/get_page_from_freelist") | ||
int BPF_KPROBE(get_page_from_freelist_second, gfp_t gfp_mask, unsigned int order, int alloc_flags, const struct alloc_context *ac) { | ||
struct event *e; | ||
unsigned long *t; | ||
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0); | ||
if (!e) | ||
return 0; | ||
|
||
// e->present = BPF_CORE_READ(ac, preferred_zoneref, zone, zone_pgdat, node_spanned_pages); | ||
t = (unsigned long *)BPF_CORE_READ(ac, preferred_zoneref, zone, zone_pgdat, vm_stat); | ||
// t = (unsigned long *)BPF_CORE_READ(ac, preferred_zoneref, zone, vm_stat); | ||
e->anon_inactive = t[0] * 4; | ||
e->anon_active = t[1] * 4; | ||
e->file_inactive = t[2] * 4; | ||
e->file_active = t[3] * 4; | ||
e->unevictable = t[4] * 4; | ||
|
||
|
||
e->file_dirty = t[20] * 4; | ||
e->writeback = t[21] * 4; | ||
e->anon_mapped = t[17] * 4; | ||
e->file_mapped = t[18] * 4; | ||
e->shmem = t[23] * 4; | ||
|
||
e->slab_reclaimable = t[5] * 4; | ||
e->kernel_misc_reclaimable = t[29] * 4; | ||
e->slab_unreclaimable = t[6] * 4; | ||
|
||
e->unstable_nfs = t[27] * 4; | ||
e->writeback_temp = t[22] * 4; | ||
|
||
e->anon_thps = t[26] * 4; | ||
e->shmem_thps = t[24] * 4; | ||
e->pmdmapped = t[25] * 4; | ||
bpf_ringbuf_submit(e, 0); | ||
return 0; | ||
} |
Oops, something went wrong.