Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# toolchain.lock) so a generated project stays self-contained. `sync-toolchain`
# refreshes both from a tag.
TOOLCHAIN_REPO ?= git@github.com:yeet-src/toolchain.git
TOOLCHAIN_TAG ?= v0.1
TOOLCHAIN_TAG ?= v0.10.1

new:
@scripts/new "$(DEST)" $(NAME)
Expand Down
11 changes: 10 additions & 1 deletion template/build/gen-vmlinux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,14 @@ if [ ! -r /sys/kernel/btf/vmlinux ]; then
fi

mkdir -p "$(dirname "$OUT")"
"$BPFTOOL" btf dump file /sys/kernel/btf/vmlinux format c >"$OUT"
# Mark the generated header as a system header so clang keeps -Wall quiet
# about it. The dump is not warning-clean: the kernel builds with tagged
# anonymous members (`struct foo;` as an unnamed struct/union member), which
# bpftool emits verbatim and clang >= 22 flags with -Wmissing-declarations.
# Nothing in it is ours to fix, and the pragma only affects diagnostics —
# CO-RE relocations and preserve_access_index are untouched.
{
echo "#pragma clang system_header"
"$BPFTOOL" btf dump file /sys/kernel/btf/vmlinux format c
} >"$OUT"
echo "generated $OUT"
36 changes: 25 additions & 11 deletions template/src/bpf/runqlat.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,29 @@ struct {
__type(value, __u64);
} runq_hist SEC(".maps");

// floor(log2(v)) without a loop: a 6-step binary search on the bit width.
// Branch-free and a fixed instruction count, so the verifier has nothing to
// bound — the obvious `while (v >>= 1) slot++` needs `#pragma unroll`, and
// clang (22+) refuses to unroll a loop with an early exit. log2(0) == 0.
static __always_inline __u32 log2u(__u32 v)
{
__u32 shift, r;

r = (v > 0xFFFF) << 4; v >>= r;
shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
shift = (v > 0xF) << 2; v >>= shift; r |= shift;
shift = (v > 0x3) << 1; v >>= shift; r |= shift;
r |= (v >> 1);
return r;
}

static __always_inline __u32 log2l(__u64 v)
{
__u32 hi = v >> 32;

return hi ? log2u(hi) + 32 : log2u((__u32)v);
}

static __always_inline void mark_runnable(__u32 pid)
{
__u64 ts = bpf_ktime_get_ns();
Expand Down Expand Up @@ -60,17 +83,8 @@ int on_switch_lat(struct trace_event_raw_sched_switch *ctx)
__u64 delta = bpf_ktime_get_ns() - *tsp;
bpf_map_delete_elem(&runq_start, &pid);

// slot = floor(log2(delta_ns))
__u32 slot = 0;
__u64 d = delta;
#pragma unroll
for (int i = 0; i < MAX_SLOTS; i++) {
if (d <= 1) {
break;
}
d >>= 1;
slot++;
}
// slot = floor(log2(delta_ns)), clamped to the last bucket
__u32 slot = log2l(delta);
if (slot >= MAX_SLOTS) {
slot = MAX_SLOTS - 1;
}
Expand Down
Loading