Skip to content

Commit

Permalink
libbpf-tools: add profile
Browse files Browse the repository at this point in the history
Signed-off-by: Eunseon Lee <[email protected]>
  • Loading branch information
ekyooo committed Jan 2, 2022
1 parent 8cac3fd commit dc805ce
Show file tree
Hide file tree
Showing 4 changed files with 590 additions and 0 deletions.
1 change: 1 addition & 0 deletions libbpf-tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ APPS = \
tcpconnlat \
tcprtt \
vfsstat \
profile \
#

FSDIST_ALIASES = btrfsdist ext4dist nfsdist xfsdist
Expand Down
100 changes: 100 additions & 0 deletions libbpf-tools/profile.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2021 Wenbo Zhang
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include <bpf/bpf_tracing.h>
#include "profile.h"

#define PF_KTHREAD 0x00200000 /* I am a kernel thread */
#define MAX_ENTRIES 10240

const volatile bool kernel_stacks_only = false;
const volatile bool user_stacks_only = false;
const volatile bool include_idle = false;
const volatile pid_t targ_tgid = -1;
const volatile pid_t targ_pid = -1;

struct {
__uint(type, BPF_MAP_TYPE_STACK_TRACE);
__uint(key_size, sizeof(u32));
} stackmap SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, struct key_t);
__type(value, sizeof(u64));
__uint(max_entries, MAX_ENTRIES);
} counts SEC(".maps");

SEC("perf_event")
int do_perf_event(struct bpf_perf_event_data *ctx) {
u64 id = bpf_get_current_pid_tgid();
u32 tgid = id >> 32;
u32 pid = id;
u32 *valp, val;

if (include_idle == false && pid == 0)
return 0;

if (targ_tgid != -1 && targ_tgid != tgid)
return 0;
if (targ_pid != -1 && targ_pid != pid)
return 0;

if (container_should_be_filtered()) {
return 0;
}

// create map key
struct key_t key = {.pid = tgid};
bpf_get_current_comm(&key.name, sizeof(key.name));

if (user_stacks_only)
key.kern_stack_id = -1;
else
key.kern_stack_id = bpf_get_stackid(ctx, &stackmap, 0);

if (kernel_stacks_only)
key.user_stack_id = -1;
else
key.user_stack_id = bpf_get_stackid(ctx, &stackmap, BPF_F_USER_STACK);

if (key.kern_stack_id >= 0) {
// populate extras to fix the kernel stack
u64 ip = PT_REGS_IP(&ctx->regs);
u64 page_offset;

// if ip isn't sane, leave key ips as zero for later checking
#if defined(CONFIG_X86_64) && defined(__PAGE_OFFSET_BASE)
// x64, 4.16, ..., 4.11, etc., but some earlier kernel didn't have it
page_offset = __PAGE_OFFSET_BASE;
#elif defined(CONFIG_X86_64) && defined(__PAGE_OFFSET_BASE_L4)
// x64, 4.17, and later
#if defined(CONFIG_DYNAMIC_MEMORY_LAYOUT) && defined(CONFIG_X86_5LEVEL)
page_offset = __PAGE_OFFSET_BASE_L5;
#else
page_offset = __PAGE_OFFSET_BASE_L4;
#endif
#else
// earlier x86_64 kernels, e.g., 4.6, comes here
// arm64, s390, powerpc, x86_32

page_offset = PAGE_OFFSET;
#endif

if (ip > page_offset) {
key.kernel_ip = ip;
}
}

valp = bpf_map_lookup_elem(&counts, &key);
val = 1;
if (!valp)
bpf_map_update_elem(&counts, &key, &val, BPF_OK);
else
__sync_fetch_and_add(&valp, &val);
return 0;
}

char LICENSE[] SEC("license") = "GPL";
Loading

0 comments on commit dc805ce

Please sign in to comment.