Skip to content

Commit 47f7984

Browse files
AsphalttKernel Patches Daemon
authored andcommitted
bpf: Avoid unintended eviction when updating lru_hash maps
When updating an existing element in lru_hash maps, the current implementation always calls prealloc_lru_pop() to get a new node before checking if the key already exists. If the map is full, this triggers LRU eviction and removes an existing element, even though the update operation only needs to modify the value of an existing key in-place. This is problematic because: 1. Users may unexpectedly lose entries when doing simple value updates 2. The eviction overhead is unnecessary for existing key updates Fix this by first checking if the key exists before allocating a new node. If the key is found, update the value in-place, refresh the LRU reference, and return immediately without triggering any eviction. Fixes: 29ba732 ("bpf: Add BPF_MAP_TYPE_LRU_HASH") Signed-off-by: Leon Hwang <[email protected]>
1 parent 52f5a27 commit 47f7984

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

kernel/bpf/hashtab.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,27 @@ static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value
12071207
b = __select_bucket(htab, hash);
12081208
head = &b->head;
12091209

1210+
ret = htab_lock_bucket(b, &flags);
1211+
if (ret)
1212+
goto err_lock_bucket;
1213+
1214+
l_old = lookup_elem_raw(head, hash, key, key_size);
1215+
1216+
ret = check_flags(htab, l_old, map_flags);
1217+
if (ret)
1218+
goto err;
1219+
1220+
if (l_old) {
1221+
bpf_lru_node_set_ref(&l_old->lru_node);
1222+
copy_map_value(&htab->map, htab_elem_value(l_old, map->key_size), value);
1223+
check_and_free_fields(htab, l_old);
1224+
}
1225+
1226+
htab_unlock_bucket(b, flags);
1227+
1228+
if (l_old)
1229+
return 0;
1230+
12101231
/* For LRU, we need to alloc before taking bucket's
12111232
* spinlock because getting free nodes from LRU may need
12121233
* to remove older elements from htab and this removal

0 commit comments

Comments
 (0)