Skip to content

Commit 555a160

Browse files
Tao ChenKernel Patches Daemon
authored andcommitted
bpf: Add lookup_and_delete_elem for BPF_MAP_STACK_TRACE
The stacktrace map can be easily full, which will lead to failure in obtaining the stack. In addition to increasing the size of the map, another solution is to delete the stack_id after looking it up from the user, so extend the existing bpf_map_lookup_and_delete_elem() functionality to stacktrace map types. Signed-off-by: Tao Chen <chen.dylane@linux.dev>
1 parent eddc6bf commit 555a160

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2712,7 +2712,7 @@ int bpf_percpu_hash_update(struct bpf_map *map, void *key, void *value,
27122712
int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
27132713
u64 flags);
27142714

2715-
int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value);
2715+
int bpf_stackmap_extract(struct bpf_map *map, void *key, void *value, bool delete);
27162716

27172717
int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
27182718
void *key, void *value, u64 map_flags);

kernel/bpf/stackmap.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,15 @@ static void *stack_map_lookup_elem(struct bpf_map *map, void *key)
646646
}
647647

648648
/* Called from syscall */
649-
int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value)
649+
static int stack_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
650+
void *value, u64 flags)
651+
{
652+
return bpf_stackmap_extract(map, key, value, true);
653+
}
654+
655+
/* Called from syscall */
656+
int bpf_stackmap_extract(struct bpf_map *map, void *key, void *value,
657+
bool delete)
650658
{
651659
struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
652660
struct stack_map_bucket *bucket, *old_bucket;
@@ -663,7 +671,10 @@ int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value)
663671
memcpy(value, bucket->data, trace_len);
664672
memset(value + trace_len, 0, map->value_size - trace_len);
665673

666-
old_bucket = xchg(&smap->buckets[id], bucket);
674+
if (delete)
675+
old_bucket = bucket;
676+
else
677+
old_bucket = xchg(&smap->buckets[id], bucket);
667678
if (old_bucket)
668679
pcpu_freelist_push(&smap->freelist, &old_bucket->fnode);
669680
return 0;
@@ -754,6 +765,7 @@ const struct bpf_map_ops stack_trace_map_ops = {
754765
.map_free = stack_map_free,
755766
.map_get_next_key = stack_map_get_next_key,
756767
.map_lookup_elem = stack_map_lookup_elem,
768+
.map_lookup_and_delete_elem = stack_map_lookup_and_delete_elem,
757769
.map_update_elem = stack_map_update_elem,
758770
.map_delete_elem = stack_map_delete_elem,
759771
.map_check_btf = map_check_no_btf,

kernel/bpf/syscall.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ static int bpf_map_copy_value(struct bpf_map *map, void *key, void *value,
319319
} else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) {
320320
err = bpf_percpu_cgroup_storage_copy(map, key, value);
321321
} else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
322-
err = bpf_stackmap_copy(map, key, value);
322+
err = bpf_stackmap_extract(map, key, value, false);
323323
} else if (IS_FD_ARRAY(map) || IS_FD_PROG_ARRAY(map)) {
324324
err = bpf_fd_array_map_lookup_elem(map, key, value);
325325
} else if (IS_FD_HASH(map)) {
@@ -1651,7 +1651,8 @@ struct bpf_map *bpf_map_inc_not_zero(struct bpf_map *map)
16511651
}
16521652
EXPORT_SYMBOL_GPL(bpf_map_inc_not_zero);
16531653

1654-
int __weak bpf_stackmap_copy(struct bpf_map *map, void *key, void *value)
1654+
int __weak bpf_stackmap_extract(struct bpf_map *map, void *key, void *value,
1655+
bool delete)
16551656
{
16561657
return -ENOTSUPP;
16571658
}
@@ -2182,7 +2183,8 @@ static int map_lookup_and_delete_elem(union bpf_attr *attr)
21822183
} else if (map->map_type == BPF_MAP_TYPE_HASH ||
21832184
map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
21842185
map->map_type == BPF_MAP_TYPE_LRU_HASH ||
2185-
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
2186+
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
2187+
map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
21862188
if (!bpf_map_is_offloaded(map)) {
21872189
bpf_disable_instrumentation();
21882190
rcu_read_lock();

0 commit comments

Comments
 (0)