Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,35 @@ jobs:
run: cargo run -- exec -m walltime --skip-upload --warmup-time 0s --max-rounds 5 -- ls -la

bpf-tests:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, codspeed-macro]
# Each memtrack integration test binary runs its cases serially
# (eBPF tracker can't overlap with itself in one process), so we
# shard at the test-binary level to parallelize across jobs.
test: [c_tests, cpp_tests, rust_tests, spawn_tests, dlopen_tests]
test: [c_tests, cpp_tests, rust_tests, spawn_tests, dlopen_tests, rss_tests]
include:
# The folio CO-RE relocations in the rmap hooks depend on kernel
# struct layouts that changed across versions (folio.flags in 6.18,
# pageflags values in 6.10/6.12); keep older-kernel images in the
# matrix so the legacy layouts stay covered once the latest images
# move past them.
- os: ubuntu-22.04
test: rss_tests
- os: ubuntu-22.04-arm
test: rss_tests
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
lfs: true
submodules: true
- name: Show kernel version
run: uname -rm
- uses: ./.github/actions/install-rust
with:
cache-key: ${{ matrix.test }}
cache-key: ${{ matrix.os }}-${{ matrix.test }}
- uses: ./.github/actions/install-bpf-deps

- name: Install additional allocators
Expand All @@ -115,8 +128,11 @@ jobs:
run: sudo -E $(which cargo) test --lib --test ${{ matrix.test }} -- --test-threads 1 --nocapture
working-directory: crates/memtrack

# Since we ran the tests with sudo, the build artifacts will have root ownership
# Since we ran the tests with sudo, the build artifacts will have root
# ownership; always restore it so a failed run cannot poison the
# workspace of later jobs on persistent self-hosted runners.
- name: Clean up
if: always()
run: sudo chown -R $USER:$USER . ~/.cargo

benchmarks:
Expand Down
1 change: 1 addition & 0 deletions crates/memtrack/.clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ BasedOnStyle: Google
PointerAlignment: Left
ColumnLimit: 100
IndentWidth: 4
AllowShortFunctionsOnASingleLine: None
2 changes: 1 addition & 1 deletion crates/memtrack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ bindgen = "0.72"
tempfile = { workspace = true }
rstest = { workspace = true }
test-log = { workspace = true }
insta = { workspace = true }
insta = { workspace = true, features = ["json", "redactions"] }
test-with = { workspace = true }

[package.metadata.dist]
Expand Down
34 changes: 18 additions & 16 deletions crates/memtrack/src/ebpf/c/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@
#include "utils/map_helpers.h"
#include "utils/process_tracking.h"

#define UPROBE_ARG_RET(name, arg_expr, submit_block) \
BPF_HASH_MAP(name##_arg, __u64, __u64, 10000); \
SEC("uprobe") \
int uprobe_##name(struct pt_regs* ctx) { return store_param(&name##_arg, arg_expr); } \
SEC("uretprobe") \
int uretprobe_##name(struct pt_regs* ctx) { \
__u64* arg_ptr = take_param(&name##_arg); \
if (!arg_ptr) { \
return 0; \
} \
__u64 ret_val = PT_REGS_RC(ctx); \
if (ret_val == 0) { \
return 0; \
} \
__u64 arg0 = *arg_ptr; \
submit_block; \
#define UPROBE_ARG_RET(name, arg_expr, submit_block) \
BPF_HASH_MAP(name##_arg, __u64, __u64, 10000); \
SEC("uprobe") \
int uprobe_##name(struct pt_regs* ctx) { \
return store_param(&name##_arg, arg_expr); \
} \
SEC("uretprobe") \
int uretprobe_##name(struct pt_regs* ctx) { \
__u64* arg_ptr = take_param(&name##_arg); \
if (!arg_ptr) { \
return 0; \
} \
__u64 ret_val = PT_REGS_RC(ctx); \
if (ret_val == 0) { \
return 0; \
} \
__u64 arg0 = *arg_ptr; \
submit_block; \
}

#define UPROBE_RET(name, arg_expr, submit_block) \
Expand Down
21 changes: 21 additions & 0 deletions crates/memtrack/src/ebpf/c/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#define EVENT_TYPE_MMAP 6
#define EVENT_TYPE_MUNMAP 7
#define EVENT_TYPE_BRK 8
#define EVENT_TYPE_RSS 9
#define EVENT_TYPE_RMAP 10
#define EVENT_TYPE_FORK 11
#define EVENT_TYPE_EXEC 12
#define EVENT_TYPE_EXIT 13

/* Common header shared by all event types */
struct event_header {
Expand Down Expand Up @@ -45,6 +50,22 @@ struct event {
uint64_t addr; /* address of mapping */
uint64_t size; /* size of mapping */
} mmap;

struct {
int32_t member;
uint64_t size;
} rss;

struct {
int32_t member; /* MM_* counter index, same values as rss.member */
int64_t delta;
uint64_t addr;
} rmap;

/* Process lifecycle events (fork carries the parent; exec/exit have no payload) */
struct {
uint32_t parent_pid;
} fork;
} data;
};

Expand Down
1 change: 1 addition & 0 deletions crates/memtrack/src/ebpf/c/main.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "allocator.h"
#include "attach.h"
#include "event.h"
#include "rss.bpf.h"
#include "utils/event_helpers.h"
#include "utils/map_helpers.h"
#include "utils/process_tracking.h"
Expand Down
Loading