Reserve ring buffer in kprobe and submit it in kretprobe
- Dominant language
- C
- Stars
- 22.7k
- Forks
- 4.1k
- Avg merge
- 10d 4h
- Merged PRs (30d)
- 3
Description
Hello, I'm new to eBPF. Currently, I want to use eBPF to trace the successful syscalls with high performance.
Specifically, I allocate the data in the entry of syscall (hooked by kprobe) by ringbuf_reserve and store the pointer on a map. Then, in the return of the syscall (hooked by kretprobe), I get the pointer and do ringbuf_submit/ringbuf_discard according to the return value of this syscall.
However, I got this eBPF error:
```
Unreleased reference id=3 alloc_insn=9
processed 263 insns (limit 1000000) max_states_per_insn 0 total_states 22 peak_states 22 mark_read 20
Traceback (most recent call last):
File "./kernel_trace.py", line 44, in
b.attach_kprobe(event="vfs_unlink", fn_name="trace_vfs_unlink")
File "/usr/lib/python3/dist-packages/bcc-0.31.0+0b5be9bb-py3.8.egg/bcc/__init__.py", line 877, in attach_kprobe
File "/usr/lib/python3/dist-packages/bcc-0.31.0+0b5be9bb-py3.8.egg/bcc/__init__.py", line 552, in load_func
Exception: Failed to load BPF program b'trace_vfs_unlink': Invalid argument
```
I guess this error is caused by eBPF not being aware the reserved ring buffer will be handled in kretprobe. Any idea to solve/bypass this? Thanks in advance.
Here is my code snippets
```
BPF_RINGBUF_OUTPUT(ring_buffer, 1024);
int trace_vfs_rename(struct pt_regs *ctx, struct renamedata *rd) {
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid >> 32;
u32 tid = (u32)pid_tgid;
/* Allocate the data structure in ring buffer */
data_t *data = (data_t *)ring_buffer.ringbuf_reserve(sizeof(data_t));
if (data == NULL) {
return 0;
}
/* Fill the data structure, ignored here */
/* Insert the data ptr to map*/
currdata.update(&tid, data);
return 0;
}
int trace_return(struct pt_regs *ctx)
{
data_t **data;
u32 tid = (u32)bpf_get_current_pid_tgid();
int ret = PT_REGS_RC(ctx);
/* Get the ring buffer pointer from map */
data = currdata.lookup(&tid);
if (data == 0)
return 0;
currdata.delete(&tid);
/* Skip the failed function call */
if (ret)
return 0;
/* Submit the successful syscalls */
ring_buffer.ringbuf_submit(*data, sizeof(**data), 0);
return 0;
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the trace_vfs_rename and trace_return handlers in the issue, focusing on the ringbuf_reserve, map storage, and ringbuf_submit/ringbuf_discard flow. Check how the verifier treats reserved references across kprobe and kretprobe programs; done means establishing a supported resolution or documenting the limitation and its workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux
- Domain
- observability, operating-systems
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100