fix(aya): Set PerfEventArray max_entries to nCPUs

Both libbpf and cilium/ebpf have will set the max_entries of a
BPF_MAP_TYPE_PERF_EVENT_ARRAY to the number of online CPUs if
it was omitted at map definition time. This adds that same
logic to Aya.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/1004/head
Dave Tucker 4 months ago committed by Michal Rostecki
parent ef0d1253ef
commit 25d986a26d

@ -88,7 +88,7 @@ mod tests {
use crate::{ use crate::{
generated::{ generated::{
bpf_cmd, bpf_cmd,
bpf_map_type::{BPF_MAP_TYPE_BLOOM_FILTER, BPF_MAP_TYPE_PERF_EVENT_ARRAY}, bpf_map_type::{BPF_MAP_TYPE_ARRAY, BPF_MAP_TYPE_BLOOM_FILTER},
}, },
maps::{ maps::{
test_utils::{self, new_map}, test_utils::{self, new_map},
@ -120,10 +120,8 @@ mod tests {
#[test] #[test]
fn test_try_from_wrong_map() { fn test_try_from_wrong_map() {
let map = new_map(test_utils::new_obj_map::<u32>( let map = new_map(test_utils::new_obj_map::<u32>(BPF_MAP_TYPE_ARRAY));
BPF_MAP_TYPE_PERF_EVENT_ARRAY, let map = Map::Array(map);
));
let map = Map::PerfEventArray(map);
assert_matches!( assert_matches!(
BloomFilter::<_, u32>::try_from(&map), BloomFilter::<_, u32>::try_from(&map),

@ -205,7 +205,7 @@ mod tests {
use crate::{ use crate::{
generated::{ generated::{
bpf_cmd, bpf_cmd,
bpf_map_type::{BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_PERF_EVENT_ARRAY}, bpf_map_type::{BPF_MAP_TYPE_ARRAY, BPF_MAP_TYPE_LPM_TRIE},
}, },
maps::{ maps::{
test_utils::{self, new_map}, test_utils::{self, new_map},
@ -249,10 +249,8 @@ mod tests {
#[test] #[test]
fn test_try_from_wrong_map() { fn test_try_from_wrong_map() {
let map = new_map(test_utils::new_obj_map::<u32>( let map = new_map(test_utils::new_obj_map::<u32>(BPF_MAP_TYPE_ARRAY));
BPF_MAP_TYPE_PERF_EVENT_ARRAY, let map = Map::Array(map);
));
let map = Map::PerfEventArray(map);
assert_matches!( assert_matches!(
LpmTrie::<_, u32, u32>::try_from(&map), LpmTrie::<_, u32, u32>::try_from(&map),

@ -30,7 +30,7 @@ use crate::{
copy_instructions, copy_instructions,
}, },
sys::{syscall, SysResult, Syscall, SyscallError}, sys::{syscall, SysResult, Syscall, SyscallError},
util::KernelVersion, util::{nr_cpus, KernelVersion},
Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN, Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN,
}; };
@ -46,6 +46,26 @@ pub(crate) fn bpf_create_map(
u.map_type = def.map_type(); u.map_type = def.map_type();
u.key_size = def.key_size(); u.key_size = def.key_size();
u.value_size = def.value_size(); u.value_size = def.value_size();
u.max_entries = def.max_entries();
// BPF_MAP_TYPE_PERF_EVENT_ARRAY's max_entries should not exceed the number of
// CPUs.
//
// By default, the newest versions of Aya, libbpf and cilium/ebpf define `max_entries` of
// `PerfEventArray` as `0`, with an intention to get it replaced with a correct value
// by the loader.
//
// We allow custom values (potentially coming either from older versions of aya-ebpf or
// programs written in C) as long as they don't exceed the number of CPUs.
//
// Otherwise, when the value is `0` or too large, we set it to the number of CPUs.
if def.map_type() == bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 {
let ncpus = nr_cpus().map_err(|e| (-1i64, e))? as u32;
if u.max_entries == 0 || u.max_entries > ncpus {
u.max_entries = ncpus;
}
};
u.max_entries = def.max_entries(); u.max_entries = def.max_entries();
u.map_flags = def.map_flags(); u.map_flags = def.map_flags();

Loading…
Cancel
Save