无法初始化 BPF_MAP_TYPE_PERCPU_ARRAY

Unable to initialize BPF_MAP_TYPE_PERCPU_ARRAY

以下是我尝试将 BPF_MAP_TYPE_PERCPU_ARRAY 结构初始化为默认值的方法。该数组包含用户 space 程序将读取的计数器。

#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_MAPSBPF_MAP_TYPE_HASH_OF_MAPS 还是 BPF_MAP_TYPE_PROG_ARRAY。如果没有,它不会让你使用 .values。检查在 libbpf here.

中定义

我找不到任何直接说明这一点的内核文档,但我相信这些数组将是 zero-initialized,因此无需初始化它们。这是我能找到的最多 on-point 文档:

BPF_MAP_TYPE_ARRAY
              Array maps have the following characteristics:

              [...]

              *  All array elements pre-allocated and zero initialized
                 at init time

(Source.)

我找不到任何关于 BPF_MAP_TYPE_PERCPU_ARRAY 的文档。我假设它是相似的。