我想使用
BPF_MAP_TYPE_PERCPU_ARRAY
来计算 SK_SKB
钩子处收到的数据包数量。我在创建地图后立即使用 bpftool map dump
检查了地图值,似乎对于某些 CPU,这些值未初始化为零。
这是地图定义:
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(max_entries, 1);
__type(key, int);
__type(value, __u64);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} request_count_map SEC(".maps");
这是
bpftool map dump
的输出:
$ sudo bpftool map dump id 287
[{
"key": 0,
"values": [{
"cpu": 0,
"value": 0
},{
"cpu": 1,
"value": 94322157119214
},{
"cpu": 2,
"value": 140730068914171
},{
"cpu": 3,
"value": 94322160575280
},{
"cpu": 4,
"value": 94322160592312
},{
"cpu": 5,
"value": 94322160592512
},{
"cpu": 6,
"value": 80
},{
"cpu": 7,
"value": 0
},{
"cpu": 8,
"value": 0
},{
"cpu": 9,
"value": 140730068932048
},{
"cpu": 10,
"value": 0
},{
"cpu": 11,
"value": 0
},{
"cpu": 12,
"value": 0
},{
"cpu": 13,
"value": 0
},{
"cpu": 14,
"value": 0
},{
"cpu": 15,
"value": 0
},{
"cpu": 16,
"value": 80
},{
"cpu": 17,
"value": 0
},{
"cpu": 18,
"value": 0
},{
"cpu": 19,
"value": 140730068932048
}
]
}
]
从文档(here和here)来看,预期的行为似乎是值初始化为零?
编辑:我意识到我在加载地图时正在更新地图,如下:
int index = 0;
__u64 value = 0;
// Get the svc_identifier_map fd.
reqcnt_map_fd = bpf_obj_get(reqcnt_map_filename);
// Add the svc identifier to the svc_identifier_map.
err = bpf_map_update_elem(respcnt_map_fd, &index, &value, BPF_ANY);
if (err) {
goto fail;
}
但是,这些值仍应为零?
当您从每个 CPU 映射上的用户空间调用
bpf_map_update_elem
时,您需要提供指向 {value type}[__NR_CPU__]
的指针作为值。在你的例子中,你提供了一个指向 __u64
的指针,它要小得多。所以 libbpf 本质上是在你的 value
之后读取堆栈/内存,直到它足够了。因此,您将部分堆栈/未初始化的内存写入了映射中。