perf_event_array.rs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. use core::{cell::UnsafeCell, marker::PhantomData, mem};
  2. use crate::{
  3. bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_F_CURRENT_CPU},
  4. helpers::bpf_perf_event_output,
  5. maps::PinningType,
  6. BpfContext,
  7. };
  8. #[repr(transparent)]
  9. pub struct PerfEventArray<T> {
  10. def: UnsafeCell<bpf_map_def>,
  11. _t: PhantomData<T>,
  12. }
  13. unsafe impl<T: Sync> Sync for PerfEventArray<T> {}
  14. impl<T> PerfEventArray<T> {
  15. pub const fn new(flags: u32) -> PerfEventArray<T> {
  16. PerfEventArray::with_max_entries(0, flags)
  17. }
  18. pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerfEventArray<T> {
  19. PerfEventArray {
  20. def: UnsafeCell::new(bpf_map_def {
  21. type_: BPF_MAP_TYPE_PERF_EVENT_ARRAY,
  22. key_size: mem::size_of::<u32>() as u32,
  23. value_size: mem::size_of::<u32>() as u32,
  24. max_entries,
  25. map_flags: flags,
  26. id: 0,
  27. pinning: PinningType::None as u32,
  28. }),
  29. _t: PhantomData,
  30. }
  31. }
  32. pub const fn pinned(max_entries: u32, flags: u32) -> PerfEventArray<T> {
  33. PerfEventArray {
  34. def: UnsafeCell::new(bpf_map_def {
  35. type_: BPF_MAP_TYPE_PERF_EVENT_ARRAY,
  36. key_size: mem::size_of::<u32>() as u32,
  37. value_size: mem::size_of::<u32>() as u32,
  38. max_entries,
  39. map_flags: flags,
  40. id: 0,
  41. pinning: PinningType::ByName as u32,
  42. }),
  43. _t: PhantomData,
  44. }
  45. }
  46. pub fn output<C: BpfContext>(&self, ctx: &C, data: &T, flags: u32) {
  47. self.output_at_index(ctx, BPF_F_CURRENT_CPU as u32, data, flags)
  48. }
  49. pub fn output_at_index<C: BpfContext>(&self, ctx: &C, index: u32, data: &T, flags: u32) {
  50. let flags = (flags as u64) << 32 | index as u64;
  51. unsafe {
  52. bpf_perf_event_output(
  53. ctx.as_ptr(),
  54. self.def.get() as *mut _,
  55. flags,
  56. data as *const _ as *mut _,
  57. mem::size_of::<T>() as u64,
  58. );
  59. }
  60. }
  61. }