mirror of https://github.com/aya-rs/aya
fix consumer index handling for pinned ringbuf map
Newly loaded ring buffer maps assumed that the consumer index was at position 0. This is not always true for pinned maps since they are persistent and therefore remember the consumer index position from the last time that they were read from Fixes: #1309reviewable/pr1318/r1
parent
a3aa387a2e
commit
d8bd45b84c
@ -0,0 +1,49 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use aya_ebpf::{
|
||||
macros::{map, uprobe},
|
||||
maps::{PerCpuArray, RingBuf},
|
||||
programs::ProbeContext,
|
||||
};
|
||||
use integration_common::ring_buf::Registers;
|
||||
#[cfg(not(test))]
|
||||
extern crate ebpf_panic;
|
||||
|
||||
#[map]
|
||||
static RING_BUF: RingBuf = RingBuf::pinned(0, 0);
|
||||
|
||||
// Use a PerCpuArray to store the registers so that we can update the values from multiple CPUs
|
||||
// without needing synchronization. Atomics exist [1], but aren't exposed.
|
||||
//
|
||||
// [1]: https://lwn.net/Articles/838884/
|
||||
#[map]
|
||||
static REGISTERS: PerCpuArray<Registers> = PerCpuArray::with_max_entries(1, 0);
|
||||
|
||||
#[uprobe]
|
||||
pub fn ring_buf_test(ctx: ProbeContext) {
|
||||
let Registers { dropped, rejected } = match REGISTERS.get_ptr_mut(0) {
|
||||
Some(regs) => unsafe { &mut *regs },
|
||||
None => return,
|
||||
};
|
||||
let mut entry = match RING_BUF.reserve::<u64>(0) {
|
||||
Some(entry) => entry,
|
||||
None => {
|
||||
*dropped += 1;
|
||||
return;
|
||||
}
|
||||
};
|
||||
// Write the first argument to the function back out to RING_BUF if it is even,
|
||||
// otherwise increment the counter in REJECTED. This exercises discarding data.
|
||||
let arg: u64 = match ctx.arg(0) {
|
||||
Some(arg) => arg,
|
||||
None => return,
|
||||
};
|
||||
if arg % 2 == 0 {
|
||||
entry.write(arg);
|
||||
entry.submit(0);
|
||||
} else {
|
||||
*rejected += 1;
|
||||
entry.discard(0);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue