From 85362c75425c1133b3b5feff5b178ce9720ba225 Mon Sep 17 00:00:00 2001 From: Jiping Yin Date: Thu, 12 Dec 2024 20:59:27 +0800 Subject: [PATCH] fix: agent - eBPF Correct the maximum data push delay When a delay occurs in the eBPF data push cycle (i.e., the time difference between the current and previous trigger exceeds 100 milliseconds), we set the maximum data push delay to a special value (`PUSH_DELAY_EXCEEDED_MARKER`: 199000) to indicate that a delay has occurred, instead of providing the specific delay value. The reason is that in a multi-core environment, direct variable assignment in eBPF cannot ensure atomicity. Therefore, we use a special value to signify the occurrence of a delay. --- agent/src/ebpf/kernel/include/socket_trace.h | 2 ++ agent/src/ebpf/kernel/socket_trace.bpf.c | 14 +++++--------- agent/src/ebpf/user/config.h | 7 ++++++- agent/src/ebpf/user/socket.c | 3 +-- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/agent/src/ebpf/kernel/include/socket_trace.h b/agent/src/ebpf/kernel/include/socket_trace.h index ec65a2b2a2f..28c77fd0e8e 100644 --- a/agent/src/ebpf/kernel/include/socket_trace.h +++ b/agent/src/ebpf/kernel/include/socket_trace.h @@ -34,6 +34,8 @@ #define INFER_CONTINUE 1 #define INFER_TERMINATE 2 +#define MAX_PUSH_DELAY_TIME_NS 100000000ULL // 100ms + typedef long unsigned int __kernel_size_t; enum { diff --git a/agent/src/ebpf/kernel/socket_trace.bpf.c b/agent/src/ebpf/kernel/socket_trace.bpf.c index 071a48852dd..47bd28a672c 100644 --- a/agent/src/ebpf/kernel/socket_trace.bpf.c +++ b/agent/src/ebpf/kernel/socket_trace.bpf.c @@ -2734,16 +2734,9 @@ static __inline int finalize_data_output(void *ctx, v_buff->events_num = 0; v_buff->len = 0; if (diff > PERIODIC_PUSH_DELAY_THRESHOLD_NS) { - __u32 k0 = 0; - struct trace_stats *stats; tracer_ctx->last_period_timestamp = tracer_ctx->period_timestamp; tracer_ctx->period_timestamp = curr_time; - stats = trace_stats_map__lookup(&k0); - if (stats == NULL) - return -1; - if (diff > stats->period_event_max_delay) - stats->period_event_max_delay = diff; } return 0; @@ -3384,8 +3377,11 @@ static __inline int push_socket_data(struct syscall_comm_enter_ctx *ctx) v_buff->events_num = 0; v_buff->len = 0; - if (diff > trace_stats->period_event_max_delay) - trace_stats->period_event_max_delay = diff; + if (diff > MAX_PUSH_DELAY_TIME_NS) { + // Indicates that a delay occurred in this data push. + __sync_fetch_and_add(&trace_stats->period_event_max_delay, 1); + } + } } diff --git a/agent/src/ebpf/user/config.h b/agent/src/ebpf/user/config.h index 01892b31a06..704a5c7fa43 100644 --- a/agent/src/ebpf/user/config.h +++ b/agent/src/ebpf/user/config.h @@ -266,7 +266,12 @@ enum cfg_feature_idx { * the data resident in the eBPF buffer. This value is the periodic time, unit * is milliseconds. */ -#define KICK_KERN_PERIOD 40000000 // Set default interval to 30 milliseconds +#define KICK_KERN_PERIOD 40000000 // Set default interval to 40 milliseconds +/* + * A special value should be assigned to indicate the case where no data has + * been pushed after exceeding 100 milliseconds. + */ +#define PUSH_DELAY_EXCEEDED_MARKER 199000 // 199 ms /* * timer config diff --git a/agent/src/ebpf/user/socket.c b/agent/src/ebpf/user/socket.c index 274bdaa51e6..5ebeb987d8d 100644 --- a/agent/src/ebpf/user/socket.c +++ b/agent/src/ebpf/user/socket.c @@ -2701,8 +2701,7 @@ struct socket_trace_stats socket_tracer_stats(void) stats_total.period_event_count) / NS_IN_USEC; if (stats_total.period_event_max_delay > 0) { - stats.period_push_max_delay = - stats_total.period_event_max_delay / NS_IN_USEC; + stats.period_push_max_delay = PUSH_DELAY_EXCEEDED_MARKER; } else { stats.period_push_max_delay = stats.period_push_avg_delay; }