Skip to content

Commit

Permalink
aya, bpf: misc fixes following review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Tuetuopay committed Sep 24, 2023
1 parent 46551de commit 579e3ce
Show file tree
Hide file tree
Showing 16 changed files with 203 additions and 172 deletions.
9 changes: 1 addition & 8 deletions aya-bpf-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,7 @@ pub fn sk_msg(attrs: TokenStream, item: TokenStream) -> TokenStream {
///
/// #[xdp(frags)]
/// pub fn xdp(ctx: XdpContext) -> u32 {
/// match unsafe { try_xdp(ctx) } {
/// Ok(ret) => ret,
/// Err(ret) => ret,
/// }
/// }
///
/// unsafe fn try_xdp(_ctx: XdpContext) -> Result<u32, u32> {
/// Ok(XDP_PASS)
/// XDP_PASS
/// }
/// ```
#[proc_macro_error]
Expand Down
2 changes: 1 addition & 1 deletion aya-bpf-macros/src/xdp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl Xdp {
Some(name) => {
return Err(Error::new_spanned(
"map",
format!("invalid value. expected 'cpumap' or 'devmap', found '{name}'"),
format!("Invalid value. Expected 'cpumap' or 'devmap', found '{name}'"),
))
}
None => None,
Expand Down
8 changes: 0 additions & 8 deletions aya-obj/src/obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ pub struct Features {
bpf_cookie: bool,
cpumap_prog_id: bool,
devmap_prog_id: bool,
devmap_hash_prog_id: bool,
btf: Option<BtfFeatures>,
}

Expand All @@ -65,7 +64,6 @@ impl Features {
bpf_cookie: bool,
cpumap_prog_id: bool,
devmap_prog_id: bool,
devmap_hash_prog_id: bool,
btf: Option<BtfFeatures>,
) -> Self {
Self {
Expand All @@ -76,7 +74,6 @@ impl Features {
bpf_cookie,
cpumap_prog_id,
devmap_prog_id,
devmap_hash_prog_id,
btf,
}
}
Expand Down Expand Up @@ -116,11 +113,6 @@ impl Features {
self.devmap_prog_id
}

/// Returns whether XDP Hash Device Maps support chained program IDs.
pub fn devmap_hash_prog_id(&self) -> bool {
self.devmap_hash_prog_id
}

/// If BTF is supported, returns which BTF features are supported.
pub fn btf(&self) -> Option<&BtfFeatures> {
self.btf.as_ref()
Expand Down
6 changes: 1 addition & 5 deletions aya/src/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ fn detect_features() -> Features {
is_bpf_cookie_supported(),
is_prog_id_supported(BPF_MAP_TYPE_CPUMAP),
is_prog_id_supported(BPF_MAP_TYPE_DEVMAP),
is_prog_id_supported(BPF_MAP_TYPE_DEVMAP_HASH),
btf,
);
debug!("BPF Feature Detection: {:#?}", f);
Expand Down Expand Up @@ -484,12 +483,9 @@ impl<'a> BpfLoader<'a> {
Ok(BPF_MAP_TYPE_CPUMAP) => {
obj.set_value_size(if FEATURES.cpumap_prog_id() { 8 } else { 4 })
}
Ok(BPF_MAP_TYPE_DEVMAP) => {
Ok(BPF_MAP_TYPE_DEVMAP | BPF_MAP_TYPE_DEVMAP_HASH) => {
obj.set_value_size(if FEATURES.devmap_prog_id() { 8 } else { 4 })
}
Ok(BPF_MAP_TYPE_DEVMAP_HASH) => {
obj.set_value_size(if FEATURES.devmap_hash_prog_id() { 8 } else { 4 })
}
_ => (),
}
let btf_fd = btf_fd.as_deref().map(|fd| fd.as_fd());
Expand Down
2 changes: 1 addition & 1 deletion aya/src/maps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ pub enum Map {
DevMapHash(MapData),
/// A [`XskMap`] map.
XskMap(MapData),
/// An unsupported map type
/// An unsupported map type.
Unsupported(MapData),
}

Expand Down
70 changes: 40 additions & 30 deletions aya/src/maps/xdp/cpu_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
os::fd::{AsFd, AsRawFd},
};

use aya_obj::generated::{bpf_cpumap_val, bpf_cpumap_val__bindgen_ty_1};
use aya_obj::generated::bpf_cpumap_val;

use crate::{
maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError},
Expand All @@ -15,6 +15,8 @@ use crate::{
Pod, FEATURES,
};

use super::XdpMapError;

/// An array of available CPUs.
///
/// XDP programs can use this map to redirect packets to a target
Expand All @@ -29,19 +31,24 @@ use crate::{
/// # let elf_bytes = &[];
/// use aya::maps::xdp::CpuMap;
///
/// let ncpus = aya::util::nr_cpus().unwrap() as u32;
/// let mut bpf = aya::BpfLoader::new()
/// .set_max_entries("CPUS", aya::util::nr_cpus().unwrap() as u32)
/// .set_max_entries("CPUS", ncpus)
/// .load(elf_bytes)
/// .unwrap();
/// let mut cpumap = CpuMap::try_from(bpf.map_mut("CPUS").unwrap())?;
/// let flags = 0;
/// let queue_size = 2048;
/// for i in 0u32..8u32 {
/// for i in 0..ncpus {
/// cpumap.set(i, queue_size, None, flags);
/// }
///
/// # Ok::<(), aya::BpfError>(())
/// ```
///
/// # See also
///
/// Kernel documentation: <https://docs.kernel.org/next/bpf/map_cpumap.html>
#[doc(alias = "BPF_MAP_TYPE_CPUMAP")]
pub struct CpuMap<T> {
inner: T,
Expand All @@ -67,7 +74,7 @@ impl<T: Borrow<MapData>> CpuMap<T> {
self.inner.borrow().obj.max_entries()
}

/// Returns the queue size and possible program for a given CPU index.
/// Returns the queue size and optional program for a given CPU index.
///
/// # Errors
///
Expand All @@ -81,7 +88,7 @@ impl<T: Borrow<MapData>> CpuMap<T> {
let value = if FEATURES.cpumap_prog_id() {
bpf_map_lookup_elem::<_, bpf_cpumap_val>(fd, &cpu_index, flags).map(|value| {
value.map(|value| CpuMapValue {
qsize: value.qsize,
queue_size: value.qsize,
// SAFETY: map writes use fd, map reads use id.
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/include/uapi/linux/bpf.h#L6241
prog_id: NonZeroU32::new(unsafe { value.bpf_prog.id }),
Expand All @@ -90,7 +97,7 @@ impl<T: Borrow<MapData>> CpuMap<T> {
} else {
bpf_map_lookup_elem::<_, u32>(fd, &cpu_index, flags).map(|value| {
value.map(|qsize| CpuMapValue {
qsize,
queue_size: qsize,
prog_id: None,
})
})
Expand All @@ -115,52 +122,52 @@ impl<T: BorrowMut<MapData>> CpuMap<T> {
/// When sending the packet to the CPU at the given index, the kernel will queue up to
/// `queue_size` packets before dropping them.
///
/// Another XDP program can be passed in that will be run on the target CPU, instead of the CPU
/// that receives the packets. This allows to perform minimal computations on CPUs that
/// directly handle packets from a NIC's RX queues, and perform possibly heavier ones in other,
/// less busy CPUs.
/// Starting from Linux kernel 5.9, another XDP program can be passed in that will be run on the
/// target CPU, instead of the CPU that receives the packets. This allows to perform minimal
/// computations on CPUs that directly handle packets from a NIC's RX queues, and perform
/// possibly heavier ones in other, less busy CPUs.
///
/// Note that only XDP programs with the `map = "cpumap"` argument can be passed. See the
/// kernel-space `aya_bpf::xdp` for more information.
/// The chained program must be loaded with the `BPF_XDP_CPUMAP` attach type. When using
/// `aya-ebpf`, that means XDP programs that specify the `map = "cpumap"` argument. See the
/// kernel-space `aya_ebpf::xdp` for more information.
///
/// # Errors
///
/// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
/// if `bpf_map_update_elem` fails, [`MapError::ProgIdNotSupported`] if the kernel does not
/// support program ids and one is provided.
/// if `bpf_map_update_elem` fails, [`XdpMapError::ChainedProgramNotSupported`] if the kernel
/// does not support chained programs and one is provided.
pub fn set(
&mut self,
cpu_index: u32,
queue_size: u32,
program: Option<&ProgramFd>,
flags: u64,
) -> Result<(), MapError> {
) -> Result<(), XdpMapError> {
let data = self.inner.borrow_mut();
check_bounds(data, cpu_index)?;
let fd = data.fd().as_fd();

let res = if FEATURES.cpumap_prog_id() {
let value = bpf_cpumap_val {
qsize: queue_size,
bpf_prog: bpf_cpumap_val__bindgen_ty_1 {
// Default is valid as the kernel will only consider fd > 0:
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/cpumap.c#L466
fd: program
.map(|prog| prog.as_fd().as_raw_fd())
.unwrap_or_default(),
},
};
let mut value = unsafe { std::mem::zeroed::<bpf_cpumap_val>() };
value.qsize = queue_size;
// Default is valid as the kernel will only consider fd > 0:
// https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/cpumap.c#L466
value.bpf_prog.fd = program
.map(|prog| prog.as_fd().as_raw_fd())
.unwrap_or_default();
bpf_map_update_elem(fd, Some(&cpu_index), &value, flags)
} else {
if program.is_some() {
return Err(MapError::ProgIdNotSupported);
return Err(XdpMapError::ChainedProgramNotSupported);
}
bpf_map_update_elem(fd, Some(&cpu_index), &queue_size, flags)
};

res.map_err(|(_, io_error)| SyscallError {
call: "bpf_map_update_elem",
io_error,
res.map_err(|(_, io_error)| {
MapError::from(SyscallError {
call: "bpf_map_update_elem",
io_error,
})
})?;
Ok(())
}
Expand All @@ -179,7 +186,10 @@ impl<T: Borrow<MapData>> IterableMap<u32, CpuMapValue> for CpuMap<T> {
unsafe impl Pod for bpf_cpumap_val {}

#[derive(Clone, Copy, Debug)]
/// The value of a CPU map.
pub struct CpuMapValue {
pub qsize: u32,
/// Size of the for the CPU.
pub queue_size: u32,
/// Chained XDP program ID.
pub prog_id: Option<NonZeroU32>,
}
Loading

0 comments on commit 579e3ce

Please sign in to comment.