Course contentsShow
← Linux
Lesson 1639 of 1,81914. Observability and Performance TroubleshootingFree lesson

Custom Perf Event Analysis

Synthesize custom event streams by combining disparate perf tracepoints and kprobes.

Synthesizing Custom Event Streams

In this lesson, you will learn how to synthesize high-fidelity observability data by correlating disparate kernel tracepoints and kprobes into unified custom event streams.

Beyond Single-Source Tracing

When investigating complex performance regressions, looking at a single probe (like sys_read or a block I/O tracepoint) is often insufficient. Real-world performance issues—such as a specific application stall—often emerge from the interaction between different kernel subsystems. Custom Perf Event Analysis involves capturing disparate data points across the kernel and "stitching" them together into a meaningful sequence of events.

By combining kprobes for entry/exit points in proprietary or non-instrumented code with standard tracepoints in the networking or scheduler subsystems, you can build a causal chain of events.

The Synthesis Workflow

The goal is to maintain a shared correlation ID (like a process ID, thread ID, or a custom request ID) across your probes. By storing state in a BPF_HASH or BPF_PERCPU_HASH, you can link the start of an operation at one probe site with its eventual completion at another.

Consider this logic for tracking request latency across two distinct kernel boundaries:

struct val_t { u64 start_ts; };
BPF_HASH(start_map, u32, struct val_t);

// Probe 1: Start of operation (e.g., request entry)
int kprobe__entry_func(struct pt_regs *ctx) {
    u32 pid = bpf_get_current_pid_tgid();
    struct val_t val = { .start_ts = bpf_ktime_get_ns() };
    start_map.update(&pid, &val);
    return 0;
}

// Probe 2: End of operation (e.g., a tracepoint for resource completion)
int tracepoint__exit_func(void *ctx) {
    u32 pid = bpf_get_current_pid_tgid();
    struct val_t *val = start_map.lookup(&pid);
    if (val) {
        u64 delta = bpf_ktime_get_ns() - val->start_ts;
        // Emit custom event stream data here
        start_map.delete(&pid);
    }
    return 0;
}

By synthesizing these streams, you transform isolated kernel observations into a cohesive timeline of how a specific task traverses the kernel's internal state machine. This allows you to ignore the noise of system-wide activity and focus strictly on the lifecycle of a single request type, effectively creating your own custom performance events.

Key Takeaway: Custom perf event analysis allows you to correlate disjointed kernel events by using eBPF maps to bridge state between multiple probes, transforming fragmented logs into a unified narrative of system performance.