我观察到eBPF LRU散列图(BPF_MAP_TYPE_LRU_HASH
)中的元素被错误地逐出.在下面的代码中,我插入到大小为8的LRU散列映射中,并每秒打印其内容:
package main
import (
"fmt"
"github.com/cilium/ebpf"
"log"
"time"
)
func main() {
spec := ebpf.MapSpec{
Name: "test_map",
Type: ebpf.LRUHash,
KeySize: 4,
ValueSize: 8,
MaxEntries: 8,
}
hashMap, err := ebpf.NewMap(&spec)
if err != nil {
log.Fatalln("Could not create map:", err)
}
var insertKey uint32
for range time.Tick(time.Second) {
err = hashMap.Update(insertKey, uint64(insertKey), ebpf.UpdateAny)
if err != nil {
log.Printf("Update failed. insertKey=%d|value=%d|err=%s", insertKey, insertKey, err)
}
var key uint32
var value uint64
count := 0
elementsStr := ""
iter := hashMap.Iterate()
for iter.Next(&key, &value) {
elementsStr += fmt.Sprintf("(%d, %d) ", key, value)
count++
}
log.Printf("Total elements: %d, elements: %s", count, elementsStr)
insertKey++
}
}
当我运行上面的程序时,我看到以下内容:
2023/03/29 17:32:29 Total elements: 1, elements: (0, 0)
2023/03/29 17:32:30 Total elements: 2, elements: (1, 1) (0, 0)
2023/03/29 17:32:31 Total elements: 3, elements: (1, 1) (0, 0) (2, 2)
2023/03/29 17:32:32 Total elements: 3, elements: (3, 3) (0, 0) (2, 2)
...
由于映射有八个条目,我预计第四行将显示四个值,但它只显示三个值,因为条目(1, 1)
已被逐出.
如果我将max_entries
更改为1024,我注意到这个问题是在插入第200个元素之后发生的,但有时它会在插入第200个元素之后发生.这是不一致的.
这个问题不仅限于从用户空间创建/插入 map ,因为我在创建 map 并插入 map 的XDP程序中发现了这个问题;上面的问题重现了我在实际程序中观察到的问题.在我的实际程序中,也有1024个条目,我注意到在插入16元素后发生了这个问题.
我在运行Linux内核5.16.7的生产服务器上对此进行了测试.
我在Linux VM上进行了测试,并将内核升级到了6.2.8,我观察到驱逐策略有所不同.例如,当max_entries
是8时,我观察到:
2023/03/29 20:38:02 Total elements: 1, elements: (0, 0)
2023/03/29 20:38:03 Total elements: 2, elements: (0, 0) (1, 1)
2023/03/29 20:38:04 Total elements: 3, elements: (0, 0) (2, 2) (1, 1)
2023/03/29 20:38:05 Total elements: 4, elements: (0, 0) (2, 2) (1, 1) (3, 3)
2023/03/29 20:38:06 Total elements: 5, elements: (4, 4) (0, 0) (2, 2) (1, 1) (3, 3)
2023/03/29 20:38:07 Total elements: 6, elements: (4, 4) (0, 0) (2, 2) (1, 1) (5, 5) (3, 3)
2023/03/29 20:38:08 Total elements: 7, elements: (4, 4) (0, 0) (2, 2) (1, 1) (6, 6) (5, 5) (3, 3)
2023/03/29 20:38:09 Total elements: 8, elements: (7, 7) (4, 4) (0, 0) (2, 2) (1, 1) (6, 6) (5, 5) (3, 3)
2023/03/29 20:38:10 Total elements: 1, elements: (8, 8)
...
当max_entries
是1024时,我注意到在添加1025个元素后,总共有897个元素.我无法在我们的生产服务器上使用内核6.2.8进行测试.