History

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.

Jiri Olsa committed 3 months ago

Commit bb4e6f41 parent 0ca56be1 file · +30 −18Browse files

Unified · Split

kernel/bpf/stackmap.c+30−18
@@ -559,31 +559,52 @@ static int stackid_fastpath(struct stackid *stackid, struct bpf_map *map, · 558 unmodified lines
559559 return -ENOENT;
560560 }
561561
562+static struct stack_map_bucket *
563+stackid_new_bucket(struct stackid *stackid, struct bpf_map *map)
564+{
565+ struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
566+ struct bpf_stack_build_id *id_offs;
567+ struct stack_map_bucket *bucket;
568+ u32 i;
569+
570+ bucket = (struct stack_map_bucket *) pcpu_freelist_pop(&smap->freelist);
571+ if (unlikely(!bucket))
572+ return NULL;
573+
574+ if (stack_map_use_build_id(map)) {
575+ id_offs = (struct bpf_stack_build_id *)bucket->data;
576+ for (i = 0; i < stackid->nr; i++)
577+ id_offs[i].ip = stackid->ips[i];
578+ } else {
579+ memcpy(bucket->data, stackid->ips, stackid->len);
580+ }
581+
582+ bucket->hash = stackid->hash;
583+ bucket->nr = stackid->nr;
584+ return bucket;
585+}
586+
562587 static long __bpf_get_stackid(struct stackid *stackid, struct bpf_map *map,
563588 struct perf_callchain_entry *trace, u64 flags)
564589 {
565590 struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
566591 struct stack_map_bucket *new_bucket, *old_bucket;
567592 bool user = flags & BPF_F_USER_STACK;
568− u32 trace_len, i;
593+ u32 trace_len;
569594 int err;
570595
571596 err = stackid_fastpath(stackid, map, trace, flags);
572597 if (err != -ENOENT)
573598 return err;
574599
600+ new_bucket = stackid_new_bucket(stackid, map);
601+ if (!new_bucket)
602+ return -ENOMEM;
603+
575604 if (stack_map_use_build_id(map)) {
576605 struct bpf_stack_build_id *id_offs;
577606
578− /* for build_id+offset, pop a bucket before slow cmp */
579− new_bucket = (struct stack_map_bucket *)
580− pcpu_freelist_pop(&smap->freelist);
581− if (unlikely(!new_bucket))
582− return -ENOMEM;
583− new_bucket->nr = stackid->nr;
584607 id_offs = (struct bpf_stack_build_id *)new_bucket->data;
585− for (i = 0; i < stackid->nr; i++)
586− id_offs[i].ip = stackid->ips[i];
587608 stack_map_get_build_id_offset(id_offs, stackid->nr, user, false /* !may_fault */);
588609 trace_len = stackid->nr * sizeof(struct bpf_stack_build_id);
589610 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, · 5 unmodified lines
595616 pcpu_freelist_push(&smap->freelist, &new_bucket->fnode);
596617 return -EEXIST;
597618 }
598− } else {
599− new_bucket = (struct stack_map_bucket *)
600− pcpu_freelist_pop(&smap->freelist);
601− if (unlikely(!new_bucket))
602− return -ENOMEM;
603− memcpy(new_bucket->data, stackid->ips, stackid->len);
604619 }
605620
606− new_bucket->hash = stackid->hash;
607− new_bucket->nr = stackid->nr;
608−
609621 old_bucket = xchg(&smap->buckets[stackid->id], new_bucket);
610622 if (old_bucket)
611623 pcpu_freelist_push(&smap->freelist, &old_bucket->fnode);