mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-27 21:03:31 -04:00
bpf: Factor stackid_new_bucket from __bpf_get_stackid
The new stackid_new_bucket allocates the new bucket and initializes it with the trace data. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260803210149.296496-4-jolsa@kernel.org
This commit is contained in:
committed by
Andrii Nakryiko
parent
0ca56befcf
commit
bb4e6f4e1b
@@ -559,31 +559,52 @@ static int stackid_fastpath(struct stackid *stackid, struct bpf_map *map,
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static struct stack_map_bucket *
|
||||
stackid_new_bucket(struct stackid *stackid, struct bpf_map *map)
|
||||
{
|
||||
struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
|
||||
struct bpf_stack_build_id *id_offs;
|
||||
struct stack_map_bucket *bucket;
|
||||
u32 i;
|
||||
|
||||
bucket = (struct stack_map_bucket *) pcpu_freelist_pop(&smap->freelist);
|
||||
if (unlikely(!bucket))
|
||||
return NULL;
|
||||
|
||||
if (stack_map_use_build_id(map)) {
|
||||
id_offs = (struct bpf_stack_build_id *)bucket->data;
|
||||
for (i = 0; i < stackid->nr; i++)
|
||||
id_offs[i].ip = stackid->ips[i];
|
||||
} else {
|
||||
memcpy(bucket->data, stackid->ips, stackid->len);
|
||||
}
|
||||
|
||||
bucket->hash = stackid->hash;
|
||||
bucket->nr = stackid->nr;
|
||||
return bucket;
|
||||
}
|
||||
|
||||
static long __bpf_get_stackid(struct stackid *stackid, struct bpf_map *map,
|
||||
struct perf_callchain_entry *trace, u64 flags)
|
||||
{
|
||||
struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
|
||||
struct stack_map_bucket *new_bucket, *old_bucket;
|
||||
bool user = flags & BPF_F_USER_STACK;
|
||||
u32 trace_len, i;
|
||||
u32 trace_len;
|
||||
int err;
|
||||
|
||||
err = stackid_fastpath(stackid, map, trace, flags);
|
||||
if (err != -ENOENT)
|
||||
return err;
|
||||
|
||||
new_bucket = stackid_new_bucket(stackid, map);
|
||||
if (!new_bucket)
|
||||
return -ENOMEM;
|
||||
|
||||
if (stack_map_use_build_id(map)) {
|
||||
struct bpf_stack_build_id *id_offs;
|
||||
|
||||
/* for build_id+offset, pop a bucket before slow cmp */
|
||||
new_bucket = (struct stack_map_bucket *)
|
||||
pcpu_freelist_pop(&smap->freelist);
|
||||
if (unlikely(!new_bucket))
|
||||
return -ENOMEM;
|
||||
new_bucket->nr = stackid->nr;
|
||||
id_offs = (struct bpf_stack_build_id *)new_bucket->data;
|
||||
for (i = 0; i < stackid->nr; i++)
|
||||
id_offs[i].ip = stackid->ips[i];
|
||||
stack_map_get_build_id_offset(id_offs, stackid->nr, user, false /* !may_fault */);
|
||||
trace_len = stackid->nr * sizeof(struct bpf_stack_build_id);
|
||||
if (stackid->hash_matches && stackid->bucket->nr == stackid->nr &&
|
||||
@@ -595,17 +616,8 @@ static long __bpf_get_stackid(struct stackid *stackid, struct bpf_map *map,
|
||||
pcpu_freelist_push(&smap->freelist, &new_bucket->fnode);
|
||||
return -EEXIST;
|
||||
}
|
||||
} else {
|
||||
new_bucket = (struct stack_map_bucket *)
|
||||
pcpu_freelist_pop(&smap->freelist);
|
||||
if (unlikely(!new_bucket))
|
||||
return -ENOMEM;
|
||||
memcpy(new_bucket->data, stackid->ips, stackid->len);
|
||||
}
|
||||
|
||||
new_bucket->hash = stackid->hash;
|
||||
new_bucket->nr = stackid->nr;
|
||||
|
||||
old_bucket = xchg(&smap->buckets[stackid->id], new_bucket);
|
||||
if (old_bucket)
|
||||
pcpu_freelist_push(&smap->freelist, &old_bucket->fnode);
|
||||
|
||||
Reference in New Issue
Block a user