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

Use struct with pid and Go routine addr for Go BPF maps #1201

Merged
merged 11 commits into from
Sep 30, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions bpf/go_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,62 +32,62 @@ char __license[] SEC("license") = "Dual MIT/GPL";
// Then it is retrieved in the return uprobes and used to know the HTTP call duration as well as its
// attributes (method, path, and status code).

typedef struct goroutine_key {
typedef struct go_addr_key {
u64 pid; // PID of the process
u64 addr; // Address of the goroutine
} goroutine_key_t;
} go_addr_key_t;

typedef struct goroutine_metadata_t {
goroutine_key_t parent;
go_addr_key_t parent;
u64 timestamp;
} goroutine_metadata;

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the goroutine
__type(key, go_addr_key_t); // key: pointer to the goroutine
__type(value, goroutine_metadata); // value: timestamp of the goroutine creation
__uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} ongoing_goroutines SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the request goroutine
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, connection_info_t);
__uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} ongoing_server_connections SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the request goroutine
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, connection_info_t);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_client_connections SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the goroutine
__type(value, tp_info_t); // value: traceparent info
__type(key, go_addr_key_t); // key: pointer to the goroutine
__type(value, tp_info_t); // value: traceparent info
__uint(max_entries, MAX_CONCURRENT_SHARED_REQUESTS);
__uint(pinning, LIBBPF_PIN_BY_NAME);
} go_trace_map SEC(".maps");

static __always_inline void goroutine_key_from_id(goroutine_key_t *current, void *goroutine) {
static __always_inline void go_addr_key_from_id(go_addr_key_t *current, void *addr) {
u64 pid_tid = bpf_get_current_pid_tgid();
u32 pid = pid_from_pid_tgid(pid_tid);

current->addr = (u64)goroutine;
current->addr = (u64)addr;
current->pid = pid;
}

static __always_inline u64 find_parent_goroutine(goroutine_key_t *current) {
static __always_inline u64 find_parent_goroutine(go_addr_key_t *current) {
if (!current) {
return 0;
}

u64 r_addr = current->addr;
goroutine_key_t *parent = current;
go_addr_key_t *parent = current;

int attempts = 0;
do {
Expand Down Expand Up @@ -151,8 +151,8 @@ server_trace_parent(void *goroutine_addr, tp_info_t *tp, void *req_header) {
tp->flags = 1;
// Get traceparent from the Request.Header
void *traceparent_ptr = extract_traceparent_from_req_headers(req_header);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);
if (traceparent_ptr != NULL) {
unsigned char buf[TP_MAX_VAL_LENGTH];
long res = bpf_probe_read(buf, sizeof(buf), traceparent_ptr);
Expand Down Expand Up @@ -223,12 +223,12 @@ static __always_inline u8 client_trace_parent(void *goroutine_addr,

if (!found_trace_id) {
tp_info_t *tp = 0;
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

u64 parent_id = find_parent_goroutine(&g_key);
goroutine_key_t p_key = {};
goroutine_key_from_id(&p_key, (void *)parent_id);
go_addr_key_t p_key = {};
go_addr_key_from_id(&p_key, (void *)parent_id);

if (parent_id) { // we found a parent request
tp = (tp_info_t *)bpf_map_lookup_elem(&go_trace_map, &p_key);
Expand Down
67 changes: 35 additions & 32 deletions bpf/go_grpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ typedef struct grpc_srv_func_invocation {

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the request goroutine
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, u16);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_grpc_request_status SEC(".maps");
Expand All @@ -47,6 +47,7 @@ typedef struct grpc_transports {
connection_info_t conn;
} grpc_transports_t;

// TODO: use go_addr_key_t as key
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, void *); // key: pointer to the transport pointer
Expand All @@ -56,33 +57,35 @@ struct {

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: goroutine
__type(value, void *); // the transport *
__type(key, go_addr_key_t); // key: goroutine
__type(value, void *); // the transport *
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_grpc_operate_headers SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the request goroutine
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, grpc_client_func_invocation_t);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_grpc_client_requests SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: pointer to the request goroutine
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, grpc_srv_func_invocation_t);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_grpc_server_requests SEC(".maps");

// Context propagation
// TODO: use go_addr_key_t as key
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, u32); // key: stream id
__type(value, grpc_client_func_invocation_t); // stored info for the client request
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_streams SEC(".maps");

// TODO: use go_addr_key_t as key
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, void *); // key: pointer to the request goroutine
Expand All @@ -101,8 +104,8 @@ int uprobe_server_handleStream(struct pt_regs *ctx) {
bpf_dbg_printk("=== uprobe/server_handleStream === ");
void *goroutine_addr = GOROUTINE_PTR(ctx);
bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

void *stream_ptr = GO_PARAM4(ctx);
off_table_t *ot = get_offsets_table();
Expand Down Expand Up @@ -143,8 +146,8 @@ SEC("uprobe/netFdReadGRPC")
int uprobe_netFdReadGRPC(struct pt_regs *ctx) {
void *goroutine_addr = GOROUTINE_PTR(ctx);
bpf_dbg_printk("=== uprobe/proc netFD read goroutine %lx === ", goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

void *tr = bpf_map_lookup_elem(&ongoing_grpc_operate_headers, &g_key);
bpf_dbg_printk("tr %llx", tr);
Expand All @@ -167,8 +170,8 @@ int uprobe_http2Server_operateHeaders(struct pt_regs *ctx) {
void *tr = GO_PARAM1(ctx);
bpf_dbg_printk(
"=== uprobe/http2Server_operateHeaders tr %llx goroutine %lx === ", tr, goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

grpc_transports_t t = {
.type = TRANSPORT_HTTP2,
Expand All @@ -190,14 +193,14 @@ int uprobe_server_handler_transport_handle_streams(struct pt_regs *ctx) {
tr,
goroutine_addr);

goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

void *parent_go = (void *)find_parent_goroutine(&g_key);
if (parent_go) {
bpf_dbg_printk("found parent goroutine for transport handler [%llx]", parent_go);
goroutine_key_t p_key = {};
goroutine_key_from_id(&p_key, parent_go);
go_addr_key_t p_key = {};
go_addr_key_from_id(&p_key, parent_go);
connection_info_t *conn = bpf_map_lookup_elem(&ongoing_server_connections, &p_key);
bpf_dbg_printk("conn %llx", conn);
if (conn) {
Expand All @@ -221,8 +224,8 @@ int uprobe_server_handleStream_return(struct pt_regs *ctx) {
off_table_t *ot = get_offsets_table();

bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

grpc_srv_func_invocation_t *invocation =
bpf_map_lookup_elem(&ongoing_grpc_server_requests, &g_key);
Expand Down Expand Up @@ -323,8 +326,8 @@ int uprobe_transport_writeStatus(struct pt_regs *ctx) {
off_table_t *ot = get_offsets_table();

bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

void *status_ptr = GO_PARAM3(ctx);
bpf_dbg_printk("status_ptr %lx", status_ptr);
Expand Down Expand Up @@ -364,8 +367,8 @@ static __always_inline void clientConnStart(
.flags = 0,
};
off_table_t *ot = get_offsets_table();
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

if (ctx_ptr) {
void *val_ptr = 0;
Expand Down Expand Up @@ -426,8 +429,8 @@ int uprobe_ClientConn_NewStream(struct pt_regs *ctx) {
static __always_inline int grpc_connect_done(struct pt_regs *ctx, void *err) {
void *goroutine_addr = GOROUTINE_PTR(ctx);
bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

grpc_client_func_invocation_t *invocation =
bpf_map_lookup_elem(&ongoing_grpc_client_requests, &g_key);
Expand Down Expand Up @@ -509,8 +512,8 @@ int uprobe_ClientConn_Close(struct pt_regs *ctx) {

void *goroutine_addr = GOROUTINE_PTR(ctx);
bpf_dbg_printk("goroutine_addr %lx", goroutine_addr);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

bpf_map_delete_elem(&ongoing_grpc_client_requests, &g_key);

Expand Down Expand Up @@ -547,8 +550,8 @@ int uprobe_transport_http2Client_NewStream(struct pt_regs *ctx) {
void *goroutine_addr = GOROUTINE_PTR(ctx);
void *t_ptr = GO_PARAM1(ctx);
off_table_t *ot = get_offsets_table();
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

u64 grpc_t_conn_pos = go_offset_of(ot, (go_offset){.v = _grpc_t_scheme_pos});
bpf_dbg_printk(
Expand Down Expand Up @@ -627,7 +630,7 @@ typedef struct grpc_framer_func_invocation {

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, goroutine_key_t); // key: go routine doing framer write headers
__type(key, go_addr_key_t); // key: go routine doing framer write headers
__type(
value,
grpc_framer_func_invocation_t); // the goroutine of the round trip request, which is the key for our traceparent info
Expand Down Expand Up @@ -660,8 +663,8 @@ int uprobe_grpcFramerWriteHeaders(struct pt_regs *ctx) {
if (invocation) {
bpf_dbg_printk("Found invocation info %llx", invocation);
void *goroutine_addr = GOROUTINE_PTR(ctx);
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

void *w_ptr = (void *)(framer + framer_w_pos + 16);
bpf_probe_read(&w_ptr, sizeof(w_ptr), (void *)(framer + framer_w_pos + 8));
Expand Down Expand Up @@ -713,8 +716,8 @@ int uprobe_grpcFramerWriteHeaders_returns(struct pt_regs *ctx) {

void *goroutine_addr = GOROUTINE_PTR(ctx);
off_table_t *ot = get_offsets_table();
goroutine_key_t g_key = {};
goroutine_key_from_id(&g_key, goroutine_addr);
go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

grpc_framer_func_invocation_t *f_info =
bpf_map_lookup_elem(&grpc_framer_invocation_map, &g_key);
Expand Down
Loading
Loading