Skip to content

Commit

Permalink
Use BPF_MAP_TYPE_PERCPU_ARRAY to alloc event
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlias committed Sep 18, 2024
1 parent 6ef1993 commit b9936a0
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
char __license[] SEC("license") = "Dual MIT/GPL";

#define MAX_CONCURRENT 50
#define MAX_SIZE 412
// TODO: tune this. This is a just a guess, but we should be able to determine
// the maximum size of a span (based on limits) and set this. Ideally, we could
// also look into a tiered allocation strategy so we do not over allocate
// space (i.e. small, medium, large data sizes).
#define MAX_SIZE 1024

// Injected const.
volatile const u64 span_context_trace_id_pos;
Expand All @@ -36,11 +40,18 @@ struct {
__uint(max_entries, MAX_CONCURRENT);
} active_spans_by_span_ptr SEC(".maps");

struct event {
struct event_t {
u32 size;
char data[MAX_SIZE];
};

struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(struct event_t));
__uint(max_entries, 1);
} new_event SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
} events SEC(".maps");
Expand Down Expand Up @@ -216,27 +227,40 @@ int uprobe_Span_ended(struct pt_regs *ctx) {

u64 len = (u64)get_argument(ctx, 3);
if (len > MAX_SIZE) {
bpf_printk("span data too large: %d\n", len);
bpf_printk("span data too large: %d", len);
return -1;
}
if (len == 0) {
bpf_printk("empty span data");
return 0;
}

struct event event;
event.size = (u32)len;

void *data_ptr = get_argument(ctx, 2);
if (data_ptr == NULL) {
bpf_printk("empty span data");
return 0;
}

__builtin_memset(&event.data, 0, MAX_SIZE);
bpf_probe_read(&event.data, (u32)event.size, data_ptr);
u32 key = 0;
struct event_t *event = bpf_map_lookup_elem(&new_event, &key);
if (event == NULL) {
bpf_printk("failed to initialize new event");
return -2;
}
event->size = (u32)len;

if (event->size < MAX_SIZE) {
long rc = bpf_probe_read(&event->data, event->size, data_ptr);
if (rc < 0) {
bpf_printk("failed to read encoded span data");
return -3;
}
} else {
bpf_printk("read too large: %d", event->size);
return -4;
}

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, event, sizeof(*event));

return 0;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import (

//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -target amd64,arm64 -cc clang -cflags $CFLAGS bpf ./bpf/probe.bpf.c

// maxSize is the maximum payload size of binary data transported in an event.
// This needs to remain in sync with the eBPF program.
const maxSize = 1024

// New returns a new [probe.Probe].
func New(logger logr.Logger) probe.Probe {
id := probe.ID{
Expand Down Expand Up @@ -79,7 +83,7 @@ func New(logger logr.Logger) probe.Probe {

type event struct {
Size uint32
SpanData [412]byte
SpanData [maxSize]byte
}

type converter struct {
Expand Down

0 comments on commit b9936a0

Please sign in to comment.