Here's how I'm trying to initialize a BPF_MAP_TYPE_PERCPU_ARRAY
of structs to a default value. The array contains counters the user space program will read.
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
struct xdp_stats_t {
__u64 total_packets;
};
struct xdp_stats_t xdp_stats = {0};
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(key_size, sizeof(__u32));
__uint(value_size, sizeof(struct xdp_stats_t));
__uint(max_entries, 1);
__array(values, struct xdp_stats_t);
} counter_table SEC(".maps") = {
.values = {
[0] = &xdp_stats
}
};
SEC("xdp")
int main_prog(struct xdp_md *ctx) {
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
But I get this error when I try to load the BPF program:
libbpf: map 'counter_table': should be map-in-map.
CodePudding user response:
This specific part is triggering this error:
.values = {
[0] = &xdp_stats
}
In libbpf, when loading a BPF structure with a .values
entry, it checks that the type is either a BPF_MAP_TYPE_ARRAY_OF_MAPS
, a BPF_MAP_TYPE_HASH_OF_MAPS
, or BPF_MAP_TYPE_PROG_ARRAY
. If not, it won't let you use .values
. The check is defined in libbpf here.
I can't find any kernel documentation that says this directly, but I believe those arrays will be zero-initialized, so there's no need to initialize them. Here's the most on-point documentation I can find:
BPF_MAP_TYPE_ARRAY
Array maps have the following characteristics:
[...]
* All array elements pre-allocated and zero initialized
at init time
(Source.)
I can't find any documentation saying the same thing about BPF_MAP_TYPE_PERCPU_ARRAY
. I assume it's similar.