Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[eBPF] Adjust Profiler #6365

Merged
merged 7 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion agent/src/ebpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ OBJS := user/elf.o \
user/mem.o \
user/vec.o \
user/bihash.o \
user/profile/profile_common.o \
$(patsubst %.c,%.o,$(wildcard user/profile/extended/*.c)) \
user/profile/perf_profiler.o \
user/profile/stringifier.o \
user/profile/java/df_jattach.o \
Expand Down Expand Up @@ -175,7 +177,7 @@ user/perf_profiler_bpf_common.c: tools/bintobuffer kernel/perf_profiler.bpf.c

$(STATIC_OBJDIR) $(SHARED_OBJDIR):
$(call msg,MKDIR,$@)
$(Q)mkdir -p $@/user/profile/java
$(Q)mkdir -p $@/user/profile/{java,extended}

$(STATIC_OBJDIR)/user/socket.o: user/socket.c $(SOCKET_TRACE_ELFS) | $(STATIC_OBJDIR)
$(call msg,CC,$@)
Expand Down
1 change: 1 addition & 0 deletions agent/src/ebpf/kernel/include/bpf_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ _Pragma("GCC error \"PT_GO_REGS_PARM\"");
#define KRETPROG(F) SEC("kretprobe/"__stringify(F)) int kretprobe__##F
#define KPROG(F) SEC("kprobe/"__stringify(F)) int kprobe__##F
#define TPPROG(F) SEC("tracepoint/syscalls/"__stringify(F)) int bpf_func_##F
#define TP_SCHED_PROG(F) SEC("tracepoint/sched/"__stringify(F)) int bpf_func_##F

#ifndef CUR_CPU_IDENTIFIER
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
Expand Down
3 changes: 2 additions & 1 deletion agent/src/ebpf/kernel/include/perf_profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef enum {
ERROR_IDX, /* Count the number of failed push notifications. */
ENABLE_IDX, /* Enable profiler sampling flag.
0: disable sampling; 1: enable sampling. */

MINBLOCK_TIME_IDX, /* The minimum blocking time, applied in the profiler extension.*/
PROFILER_CNT
} profiler_idx;

Expand All @@ -49,6 +49,7 @@ struct stack_trace_key_t {
int kernstack;
int userstack;
__u64 timestamp;
__u64 duration_ns;
};

#endif /* DF_BPF_PERF_PROFILER_H */
1 change: 1 addition & 0 deletions agent/src/ebpf/kernel/perf_profiler.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,4 @@ int bpf_perf_event(struct bpf_perf_event_data *ctx)

return 0;
}

13 changes: 12 additions & 1 deletion agent/src/ebpf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ pub const EVENT_TYPE_PROC_EXEC: u32 = 1 << 5;
#[allow(dead_code)]
pub const EVENT_TYPE_PROC_EXIT: u32 = 1 << 6;

// Profiler types
#[allow(dead_code)]
pub const PROFILER_TYPE_UNKNOWN: u8 = 0;
#[allow(dead_code)]
pub const PROFILER_TYPE_ONCPU: u8 = 1;

//Process exec/exit events
#[repr(C)]
#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -367,6 +373,7 @@ pub struct SK_TRACE_STATS {
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct stack_profile_data {
pub profiler_type : u8, // Profiler type, such as 1(PROFILER_TYPE_ONCPU).
pub timestamp: u64, // Timestamp of the stack trace data(unit: nanoseconds).
pub pid: u32, // User-space process-ID.
/*
Expand All @@ -381,9 +388,10 @@ pub struct stack_profile_data {
pub k_stack_id: u32, // Kernel space stackID.
pub cpu: u32, // The captured stack trace data is generated on which CPU?
/*
* The profiler captures the number of occurrences of the same
* The profiler captures the sum of durations of occurrences of the same
* data by querying with the quadruple
* "<pid + stime + u_stack_id + k_stack_id + tid + cpu>" as the key.
* In microseconds as the unit of time.
*/
pub count: u32,
/*
Expand Down Expand Up @@ -647,6 +655,9 @@ extern "C" {
timeout: c_int,
callback: extern "C" fn(data: *mut c_char, len: c_int),
) -> c_int;

pub fn enable_oncpu_profiler() -> c_int;
pub fn disable_oncpu_profiler() -> c_int;
}

#[no_mangle]
Expand Down
6 changes: 6 additions & 0 deletions agent/src/ebpf/tools/code.style
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#! /bin/bash

indent -npro -kr -i8 -ts8 -nss -nsc -ncs -nprs -sob -l80 -ss -cp1 --space-after-for --space-after-if --space-after-while --space-special-semicolon --blank-lines-after-procedures -v $1
sed -i "s/{ }/{}/g" $1
sed -i "s/) ;/);/g" $1
sed -i "s/^ //g" $1
46 changes: 23 additions & 23 deletions agent/src/ebpf/user/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#define EV_NAME_SIZE 1024

#define BOOT_TIME_UPDATE_PERIOD 60 // 系统启动时间更新周期, 单位:秒
#define BOOT_TIME_UPDATE_PERIOD 60 // 系统启动时间更新周期, 单位:秒

// eBPF Map Name
#define MAP_MEMBERS_OFFSET_NAME "__members_offset"
Expand Down Expand Up @@ -68,7 +68,7 @@ enum {
//thread index for bihash
enum {
THREAD_PROFILER_READER_IDX = 0,
THREAD_PROC_ACT_IDX_BASE
THREAD_PROC_ACT_IDX_BASE = 2,
};

/*
Expand Down Expand Up @@ -122,7 +122,7 @@ enum {
* may lead to increased overhead and memory usage, so it is
* recommended to use it with caution.
*/
#ifndef PERF_MAX_STACK_DEPTH
#ifndef PERF_MAX_STACK_DEPTH
#define PERF_MAX_STACK_DEPTH 127
#endif

Expand All @@ -131,19 +131,19 @@ enum {
*/
#define MAP_STACK_A_NAME "__stack_map_a"
#define MAP_STACK_B_NAME "__stack_map_b"
#define MAP_PROFILER_STATE_MAP "__profiler_state_map"
#define MAP_PROFILER_STATE_NAME "__profiler_state_map"

#define STRINGIFIER_STACK_STR_HASH_BUCKETS_NUM 8192
#define STRINGIFIER_STACK_STR_HASH_MEM_SZ (1ULL << 30) // 1Gbytes
#define STRINGIFIER_STACK_STR_HASH_MEM_SZ (1ULL << 30) // 1Gbytes

#define SYMBOLIZER_CACHES_HASH_BUCKETS_NUM 8192
#define SYMBOLIZER_CACHES_HASH_MEM_SZ (1ULL << 31) // 2Gbytes
#define SYMBOLIZER_CACHES_HASH_MEM_SZ (1ULL << 31) // 2Gbytes

#define STACK_TRACE_MSG_HASH_BUCKETS_NUM 8192
#define STACK_TRACE_MSG_HASH_MEM_SZ (1ULL << 32) // 4Gbytes
#define STACK_TRACE_MSG_HASH_MEM_SZ (1ULL << 32) // 4Gbytes

#define PROFILER_READER_EPOLL_TIMEOUT 500 //msecs
#define EPOLL_SHORT_TIMEOUT 100 //mescs
#define PROFILER_READER_EPOLL_TIMEOUT 500 //msecs
#define EPOLL_SHORT_TIMEOUT 100 //mescs

/*
* Process information recalibration time, this time is the number of seconds
Expand All @@ -152,7 +152,7 @@ enum {
* The Java process will delay obtaining the symbol table by
* 'PROC_INFO_VERIFY_TIME' seconds after it starts running.
*/
#define PROC_INFO_VERIFY_TIME 60 // 60 seconds
#define PROC_INFO_VERIFY_TIME 60 // 60 seconds

/*
* This value is used to determine which type of Java agent's so library to
Expand All @@ -168,12 +168,12 @@ enum {
* date the Java symbol table. This is done The purpose is to avoid freque-
* nt updates of the java symbol table.
*/
#define JAVA_SYMS_UPDATE_DELAY_DEF 60 // 60 seconds
#define JAVA_SYMS_UPDATE_DELAY_MIN 5 // 5 seconds
#define JAVA_SYMS_UPDATE_DELAY_MAX 3600 // 3600 seconds
#define JAVA_SYMS_UPDATE_DELAY_DEF 60 // 60 seconds
#define JAVA_SYMS_UPDATE_DELAY_MIN 5 // 5 seconds
#define JAVA_SYMS_UPDATE_DELAY_MAX 3600 // 3600 seconds

/* Profiler - maximum data push interval time (in nanosecond). */
#define MAX_PUSH_MSG_TIME_INTERVAL 1000000000ULL /* 1 seconds */
#define MAX_PUSH_MSG_TIME_INTERVAL 1000000000ULL /* 1 seconds */

/*
* timer config
Expand All @@ -192,40 +192,40 @@ enum {
* the data resident in the eBPF buffer. This value is the periodic time, unit
* is milliseconds.
*/
#define KICK_KERN_PERIOD 10 // 10 ticks(100 milliseconds)
#define KICK_KERN_PERIOD 10 // 10 ticks(100 milliseconds)

/*
* System boot time update cycle time, unit is milliseconds.
*/
#define SYS_TIME_UPDATE_PERIOD 1000 // 1000 ticks(10 seconds)
#define SYS_TIME_UPDATE_PERIOD 1000 // 1000 ticks(10 seconds)

/*
* Check whether the eBPF Map exceeds the maximum value and use it to release
* stale data (unit is milliseconds).
*/
#define CHECK_MAP_EXCEEDED_PERIOD 100 // 100 ticks(1 seconds)
#define CHECK_MAP_EXCEEDED_PERIOD 100 // 100 ticks(1 seconds)

/*
* Used to check whether the kernel adaptation is successful, here is the
* check cycle time (unit is milliseconds).
*/
#define CHECK_KERN_ADAPT_PERIOD 100 // 100 ticks(1 seconds)
#define CHECK_KERN_ADAPT_PERIOD 100 // 100 ticks(1 seconds)

/*
* The maximum space occupied by the Java symbol files in the target POD.
* Its valid range is [2, 100], which means it falls within the interval
* of 2Mi to 100Mi. If the configuration value is outside this range, the
* default value of 10(10Mi), will be used.
*/
#define JAVA_POD_WRITE_FILES_SPACE_MIN 2097152 // 2Mi
#define JAVA_POD_WRITE_FILES_SPACE_MAX 104857600 // 100Mi
#define JAVA_POD_WRITE_FILES_SPACE_DEF 10485760 // 10Mi
#define JAVA_POD_WRITE_FILES_SPACE_MIN 2097152 // 2Mi
#define JAVA_POD_WRITE_FILES_SPACE_MAX 104857600 // 100Mi
#define JAVA_POD_WRITE_FILES_SPACE_DEF 10485760 // 10Mi
/*
* The `df_java_agent_musl.so` and `df_java_agent.so` files will also be
* placed in the target POD for loading operations. They occupy less than
* 300Ki of space.
*/
#define JAVA_POD_EXTRA_SPACE_MMA 307200 // 300Ki
#define JAVA_POD_EXTRA_SPACE_MMA 307200 // 300Ki

/*
* The perf profiler utilizes a perf buffer (per CPUs) for transporting stack data,
Expand Down Expand Up @@ -263,6 +263,6 @@ enum {
* The random value has a maximum limit specified above(measured in seconds).
*/

#define PROFILER_DEFER_RANDOM_MAX 60 // 60 seconds
#define PROFILER_DEFER_RANDOM_MAX 60 // 60 seconds

#endif /* DF_EBPF_CONFIG_H */
38 changes: 38 additions & 0 deletions agent/src/ebpf/user/profile/extended/extended.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2024 Yunshan Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <sys/stat.h>
#include <bcc/perf_reader.h>
#include "../../config.h"
#include "../../utils.h"
#include "../../common.h"
#include "../../mem.h"
#include "../../log.h"
#include "../../types.h"
#include "../../vec.h"
#include "../../tracer.h"
#include "../../socket.h"

/*
* You can rewrite the extended_reader_create() function to expand
* the functionality of other function stack profiling. Inside it,
* you can append new readers to read data from the eBPF perfbuf
* and enable new threads to handle the reception.
*/
int __attribute__ ((weak)) extended_reader_create(struct bpf_tracer *tracer)
yinjiping marked this conversation as resolved.
Show resolved Hide resolved
{
return 0;
}
20 changes: 20 additions & 0 deletions agent/src/ebpf/user/profile/extended/extended.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2024 Yunshan Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef DF_PROFILE_EXT_H
#define DF_PROFILE_EXT_H
int extended_reader_create(struct bpf_tracer *tracer);
#endif /* DF_PROFILE_EXT_H */
10 changes: 6 additions & 4 deletions agent/src/ebpf/user/profile/java/gen_syms_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ void gen_java_symbols_file(int pid, int *ret_val, bool error_occurred)

char args[PERF_PATH_SZ * 2];
snprintf(args, sizeof(args),
"%d %d," DF_AGENT_LOCAL_PATH_FMT ".map," DF_AGENT_LOCAL_PATH_FMT ".log",
pid, g_java_syms_write_bytes_max, pid, pid);
"%d %d," DF_AGENT_LOCAL_PATH_FMT ".map,"
DF_AGENT_LOCAL_PATH_FMT ".log", pid,
g_java_syms_write_bytes_max, pid, pid);

i64 curr_local_sz;
curr_local_sz = get_local_symbol_file_sz(pid, target_ns_pid);
Expand Down Expand Up @@ -131,6 +132,7 @@ void java_syms_update_main(void *arg)

if (task != NULL) {
struct symbolizer_proc_info *p = task->p;
symbolizer_proc_lock(p);
/* JAVA process has not exited. */
if (AO_GET(&p->use) > 1) {
int ret;
Expand All @@ -151,10 +153,10 @@ void java_syms_update_main(void *arg)

AO_SET(&p->new_java_syms_file, true);
}

symbolizer_proc_unlock(p);
/* Ensure that all tasks are completed before releasing. */
if (AO_SUB_F(&p->use, 1) == 0) {
clib_mem_free((void *)p);
free_proc_cache(p);
}

clib_mem_free((void *)task);
Expand Down