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

Showing the changes to kernel/bpf/stackmap.c (1 of 1 file). Show all

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
559 return -ENOENT;559 return -ENOENT;
560}560}
561 561
562static struct stack_map_bucket *
563stackid_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
562static long __bpf_get_stackid(struct stackid *stackid, struct bpf_map *map,587static long __bpf_get_stackid(struct stackid *stackid, struct bpf_map *map,
563 struct perf_callchain_entry *trace, u64 flags)588 struct perf_callchain_entry *trace, u64 flags)
564{589{
565 struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);590 struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
566 struct stack_map_bucket *new_bucket, *old_bucket;591 struct stack_map_bucket *new_bucket, *old_bucket;
567 bool user = flags & BPF_F_USER_STACK;592 bool user = flags & BPF_F_USER_STACK;
568 u32 trace_len, i;593 u32 trace_len;
569 int err;594 int err;
570 595
571 err = stackid_fastpath(stackid, map, trace, flags);596 err = stackid_fastpath(stackid, map, trace, flags);
572 if (err != -ENOENT)597 if (err != -ENOENT)
573 return err;598 return err;
574 599
600 new_bucket = stackid_new_bucket(stackid, map);
601 if (!new_bucket)
602 return -ENOMEM;
603
575 if (stack_map_use_build_id(map)) {604 if (stack_map_use_build_id(map)) {
576 struct bpf_stack_build_id *id_offs;605 struct bpf_stack_build_id *id_offs;
577 606
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;
584 id_offs = (struct bpf_stack_build_id *)new_bucket->data;607 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];
587 stack_map_get_build_id_offset(id_offs, stackid->nr, user, false /* !may_fault */);608 stack_map_get_build_id_offset(id_offs, stackid->nr, user, false /* !may_fault */);
588 trace_len = stackid->nr * sizeof(struct bpf_stack_build_id);609 trace_len = stackid->nr * sizeof(struct bpf_stack_build_id);
589 if (stackid->hash_matches && stackid->bucket->nr == stackid->nr &&610 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
595 pcpu_freelist_push(&smap->freelist, &new_bucket->fnode);616 pcpu_freelist_push(&smap->freelist, &new_bucket->fnode);
596 return -EEXIST;617 return -EEXIST;
597 }618 }
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);
604 }619 }
605 620
606 new_bucket->hash = stackid->hash;
607 new_bucket->nr = stackid->nr;
608
609 old_bucket = xchg(&smap->buckets[stackid->id], new_bucket);621 old_bucket = xchg(&smap->buckets[stackid->id], new_bucket);
610 if (old_bucket)622 if (old_bucket)
611 pcpu_freelist_push(&smap->freelist, &old_bucket->fnode);623 pcpu_freelist_push(&smap->freelist, &old_bucket->fnode);