以下是我如何尝试将结构的BPF_MAP_TYPE_PERCPU_ARRAY
初始化为默认值。该数组包含用户空间程序将读取的计数器。
#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";
但当我尝试加载BPF程序时,我会遇到这个错误:
libbpf: map 'counter_table': should be map-in-map.
此特定部分触发此错误:
.values = {
[0] = &xdp_stats
}
在libbpf中,当使用.values
条目加载BPF结构时,它会检查该类型是否为BPF_MAP_TYPE_ARRAY_OF_MAPS
、BPF_MAP_TYPE_HASH_OF_MAPS
或BPF_MAP_TYPE_PROG_ARRAY
。否则,它将不允许您使用.values
。检查是在libbpf中定义的。
我找不到任何直接说明这一点的内核文档,但我相信这些数组将被零初始化,所以没有必要初始化它们。以下是我能找到的最中肯的文档:
BPF_MAP_TYPE_ARRAY
Array maps have the following characteristics:
[...]
* All array elements pre-allocated and zero initialized
at init time
(来源(
我找不到任何关于BPF_MAP_TYPE_PERCPU_ARRAY
的文档。我认为是相似的。