per_cpu_array.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. use core::{marker::PhantomData, mem, ptr::NonNull};
  2. use aya_bpf_cty::c_void;
  3. use crate::{
  4. bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY},
  5. helpers::bpf_map_lookup_elem,
  6. maps::PinningType,
  7. };
  8. #[repr(transparent)]
  9. pub struct PerCpuArray<T> {
  10. def: bpf_map_def,
  11. _t: PhantomData<T>,
  12. }
  13. impl<T> PerCpuArray<T> {
  14. pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerCpuArray<T> {
  15. PerCpuArray {
  16. def: bpf_map_def {
  17. type_: BPF_MAP_TYPE_PERCPU_ARRAY,
  18. key_size: mem::size_of::<u32>() as u32,
  19. value_size: mem::size_of::<T>() as u32,
  20. max_entries,
  21. map_flags: flags,
  22. id: 0,
  23. pinning: PinningType::None as u32,
  24. },
  25. _t: PhantomData,
  26. }
  27. }
  28. pub const fn pinned(max_entries: u32, flags: u32) -> PerCpuArray<T> {
  29. PerCpuArray {
  30. def: bpf_map_def {
  31. type_: BPF_MAP_TYPE_PERCPU_ARRAY,
  32. key_size: mem::size_of::<u32>() as u32,
  33. value_size: mem::size_of::<T>() as u32,
  34. max_entries,
  35. map_flags: flags,
  36. id: 0,
  37. pinning: PinningType::ByName as u32,
  38. },
  39. _t: PhantomData,
  40. }
  41. }
  42. #[inline(always)]
  43. pub fn get(&mut self, index: u32) -> Option<&T> {
  44. unsafe {
  45. // FIXME: alignment
  46. self.lookup(index).map(|p| p.as_ref())
  47. }
  48. }
  49. #[inline(always)]
  50. pub fn get_mut(&mut self, index: u32) -> Option<&mut T> {
  51. unsafe {
  52. // FIXME: alignment
  53. self.lookup(index).map(|mut p| p.as_mut())
  54. }
  55. }
  56. #[inline(always)]
  57. unsafe fn lookup(&mut self, index: u32) -> Option<NonNull<T>> {
  58. let ptr = bpf_map_lookup_elem(
  59. &mut self.def as *mut _ as *mut _,
  60. &index as *const _ as *const c_void,
  61. );
  62. NonNull::new(ptr as *mut T)
  63. }
  64. }