Skip to content

Commit 3d44565

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 310cb68 commit 3d44565

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
@@ -2704,7 +2704,7 @@ int bpf_percpu_hash_update(struct bpf_map *map, void *key, void *value,
27042704
int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
27052705
u64 flags);
27062706

2707-
int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value);
2707+
int bpf_stackmap_copy_and_delete(struct bpf_map *map, void *key, void *value, bool delete);
27082708

27092709
int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
27102710
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_copy_and_delete(map, key, value, true);
653+
}
654+
655+
/* Called from syscall */
656+
int bpf_stackmap_copy_and_delete(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
@@ -318,7 +318,7 @@ static int bpf_map_copy_value(struct bpf_map *map, void *key, void *value,
318318
} else if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE) {
319319
err = bpf_percpu_cgroup_storage_copy(map, key, value);
320320
} else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
321-
err = bpf_stackmap_copy(map, key, value);
321+
err = bpf_stackmap_copy_and_delete(map, key, value, false);
322322
} else if (IS_FD_ARRAY(map) || IS_FD_PROG_ARRAY(map)) {
323323
err = bpf_fd_array_map_lookup_elem(map, key, value);
324324
} else if (IS_FD_HASH(map)) {
@@ -1627,7 +1627,8 @@ struct bpf_map *bpf_map_inc_not_zero(struct bpf_map *map)
16271627
}
16281628
EXPORT_SYMBOL_GPL(bpf_map_inc_not_zero);
16291629

1630-
int __weak bpf_stackmap_copy(struct bpf_map *map, void *key, void *value)
1630+
int __weak bpf_stackmap_copy_and_delete(struct bpf_map *map, void *key, void *value,
1631+
bool delete)
16311632
{
16321633
return -ENOTSUPP;
16331634
}
@@ -2158,7 +2159,8 @@ static int map_lookup_and_delete_elem(union bpf_attr *attr)
21582159
} else if (map->map_type == BPF_MAP_TYPE_HASH ||
21592160
map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
21602161
map->map_type == BPF_MAP_TYPE_LRU_HASH ||
2161-
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
2162+
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
2163+
map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
21622164
if (!bpf_map_is_offloaded(map)) {
21632165
bpf_disable_instrumentation();
21642166
rcu_read_lock();

0 commit comments

Comments
 (0)