You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by li...@apache.org on 2023/03/20 09:24:46 UTC
[skywalking-rover] branch main updated: Improve the performance of getting the goid in the Golang (#82)
This is an automated email from the ASF dual-hosted git repository.
liuhan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-rover.git
The following commit(s) were added to refs/heads/main by this push:
new de4c613 Improve the performance of getting the goid in the Golang (#82)
de4c613 is described below
commit de4c6132ba0afe4d033652a4367d890382610d36
Author: mrproliu <74...@qq.com>
AuthorDate: Mon Mar 20 17:24:39 2023 +0800
Improve the performance of getting the goid in the Golang (#82)
---
CHANGES.md | 1 +
bpf/include/api.h | 10 +++++
bpf/include/{goid.c => goid.h} | 49 ++++++++--------------
bpf/include/symbol_offsets.h | 4 --
bpf/profiling/continuous/go_tls.c | 2 +-
bpf/profiling/network/go_tls.c | 2 +-
bpf/profiling/offcpu.h | 7 +---
.../continuous/checker/bpf/network/ssl.go | 2 +-
pkg/profiling/task/network/ssl.go | 2 +-
pkg/tools/ssl/gotls.go | 11 +----
10 files changed, 34 insertions(+), 56 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 6955adb..82cc739 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -10,6 +10,7 @@ Release Notes.
* Support OpenSSL 3.0.x.
* Optimized the data structure in BPF.
* Support continuous profiling.
+* Improve the performance when getting `goid` in eBPF.
#### Bug Fixes
* Fix HTTP method name in protocol analyzer
diff --git a/bpf/include/api.h b/bpf/include/api.h
index aac5cca..fa4aa16 100644
--- a/bpf/include/api.h
+++ b/bpf/include/api.h
@@ -45,4 +45,14 @@ typedef enum
{
true=1, false=0
} bool;
+
+struct thread_struct {
+ long unsigned int fsbase;
+} __attribute__((preserve_access_index));
+
+struct task_struct {
+ __u32 pid;
+ __u32 tgid;
+ struct thread_struct thread;
+} __attribute__((preserve_access_index));
#endif
\ No newline at end of file
diff --git a/bpf/include/goid.c b/bpf/include/goid.h
similarity index 55%
rename from bpf/include/goid.c
rename to bpf/include/goid.h
index 80c0813..92f0598 100644
--- a/bpf/include/goid.c
+++ b/bpf/include/goid.h
@@ -15,6 +15,9 @@
// specific language governing permissions and limitations
// under the License.
+#pragma once
+
+#include "api.h"
#include "symbol_offsets.h"
struct {
@@ -24,47 +27,29 @@ struct {
__type(value, __u64);
} go_tgid_goid_map SEC(".maps");
static __inline __u64 get_goid(__u64 id) {
- __u64 *val;
- val = bpf_map_lookup_elem(&go_tgid_goid_map, &id);
- return !val ? 0 : *val;
-}
-static __inline void set_goid(__u64 id, __u64 goid) {
- bpf_map_update_elem(&go_tgid_goid_map, &id, &goid, 0);
-}
-
-SEC("uprobe/casgstatus")
-int go_casgstatus(struct pt_regs* ctx) {
- const void* sp = (const void*)PT_REGS_SP(ctx);
- __u64* regs = go_regabi_regs(ctx);
- if (regs == NULL) {
- return 0;
- }
-
- __u64 id = bpf_get_current_pid_tgid();
__u32 tgid = id >> 32;
struct go_tls_args_symaddr_t* symaddrs = get_go_tls_args_symaddr(tgid);
if (symaddrs == NULL) {
return 0;
}
- // get runtime.g
- void* gptr = NULL;
- assign_go_tls_arg(&gptr, sizeof(gptr), symaddrs->casg_status_gp_loc, sp, regs);
- if (gptr == NULL) {
+ // Get fsbase from `struct task_struct`.
+ const struct task_struct* task_ptr = (struct task_struct*)bpf_get_current_task();
+ if (!task_ptr) {
return 0;
}
- // get goid in runtime.g
- int64_t goid;
- bpf_probe_read(&goid, sizeof(goid), gptr + symaddrs->gid_offset);
+ // thread local storage
+ const void* fs_base;
+ bpf_probe_read_kernel(&fs_base, sizeof(fs_base), &(task_ptr->thread.fsbase));
- // newval in runtime.g
- __u32 status;
- assign_go_tls_arg(&status, sizeof(status), symaddrs->casg_status_new_val_loc, sp, regs);
+ __u64 g_addr;
+ // struct g location
+ int32_t g_addr_offset = -8;
+ bpf_probe_read_user(&g_addr, sizeof(void*), (void*)(fs_base + g_addr_offset));
- // check the status is running
- if (status == 2) {
- set_goid(id, goid);
- }
- return 0;
+ // goid in struct g
+ __u64 goid;
+ bpf_probe_read_user(&goid, sizeof(void*), (void*)(g_addr + symaddrs->gid_offset));
+ return goid;
}
\ No newline at end of file
diff --git a/bpf/include/symbol_offsets.h b/bpf/include/symbol_offsets.h
index 33b19ef..798b40c 100644
--- a/bpf/include/symbol_offsets.h
+++ b/bpf/include/symbol_offsets.h
@@ -84,10 +84,6 @@ struct go_tls_args_symaddr_t {
__u64 tcp_conn_offset;
__u64 is_client_offset;
- // casg
- struct go_tls_arg_location_t casg_status_gp_loc;
- struct go_tls_arg_location_t casg_status_new_val_loc;
-
// read
struct go_tls_arg_location_t read_connection_loc;
struct go_tls_arg_location_t read_buffer_loc;
diff --git a/bpf/profiling/continuous/go_tls.c b/bpf/profiling/continuous/go_tls.c
index 60ed538..87325ac 100644
--- a/bpf/profiling/continuous/go_tls.c
+++ b/bpf/profiling/continuous/go_tls.c
@@ -16,7 +16,7 @@
// under the License.
#include "go_tls.h"
-#include "goid.c"
+#include "goid.h"
SEC("uprobe/go_tls_write")
int go_tls_write(struct pt_regs* ctx) {
diff --git a/bpf/profiling/network/go_tls.c b/bpf/profiling/network/go_tls.c
index 3fde4a5..5dbaa59 100644
--- a/bpf/profiling/network/go_tls.c
+++ b/bpf/profiling/network/go_tls.c
@@ -16,7 +16,7 @@
// under the License.
#include "go_tls.h"
-#include "goid.c"
+#include "goid.h"
SEC("uprobe/go_tls_write")
int go_tls_write(struct pt_regs* ctx) {
diff --git a/bpf/profiling/offcpu.h b/bpf/profiling/offcpu.h
index cc5a73b..95332c1 100644
--- a/bpf/profiling/offcpu.h
+++ b/bpf/profiling/offcpu.h
@@ -44,9 +44,4 @@ struct {
__type(key, struct key_t);
__type(value, struct value_t);
__uint(max_entries, 10000);
-} counts SEC(".maps");
-
-struct task_struct {
- __u32 pid;
- __u32 tgid;
-} __attribute__((preserve_access_index));
\ No newline at end of file
+} counts SEC(".maps");
\ No newline at end of file
diff --git a/pkg/profiling/continuous/checker/bpf/network/ssl.go b/pkg/profiling/continuous/checker/bpf/network/ssl.go
index 50261f4..747a95a 100644
--- a/pkg/profiling/continuous/checker/bpf/network/ssl.go
+++ b/pkg/profiling/continuous/checker/bpf/network/ssl.go
@@ -29,7 +29,7 @@ func addSSLProcess(pid int, linker *btf.Linker, bpf *bpfObjects) error {
register.Envoy(bpf.EnvoyTlsArgsSymaddrMap, bpf.OpensslWrite, bpf.OpensslWriteRet, bpf.OpensslRead, bpf.OpensslReadRet)
- register.GoTLS(bpf.GoTlsArgsSymaddrMap, bpf.GoCasgstatus, bpf.GoTlsWrite, bpf.GoTlsWriteRet, bpf.GoTlsRead, bpf.GoTlsReadRet)
+ register.GoTLS(bpf.GoTlsArgsSymaddrMap, bpf.GoTlsWrite, bpf.GoTlsWriteRet, bpf.GoTlsRead, bpf.GoTlsReadRet)
register.Node(bpf.OpensslSymaddrMap, nil, bpf.OpensslWrite, bpf.OpensslWriteRet, bpf.OpensslRead, bpf.OpensslReadRet,
nil, nil, nil)
diff --git a/pkg/profiling/task/network/ssl.go b/pkg/profiling/task/network/ssl.go
index d3fd33e..0e23e7e 100644
--- a/pkg/profiling/task/network/ssl.go
+++ b/pkg/profiling/task/network/ssl.go
@@ -29,7 +29,7 @@ func addSSLProcess(pid int, loader *bpf.Loader) error {
register.Envoy(nil, loader.OpensslWrite, loader.OpensslWriteRet, loader.OpensslRead, loader.OpensslReadRet)
- register.GoTLS(loader.GoTlsArgsSymaddrMap, loader.GoCasgstatus, loader.GoTlsWrite, loader.GoTlsWriteRet, loader.GoTlsRead, loader.GoTlsReadRet)
+ register.GoTLS(loader.GoTlsArgsSymaddrMap, loader.GoTlsWrite, loader.GoTlsWriteRet, loader.GoTlsRead, loader.GoTlsReadRet)
register.Node(nil, loader.NodeTlsSymaddrMap, loader.OpensslWrite, loader.OpensslWriteRet, loader.OpensslRead, loader.OpensslReadRet,
loader.NodeTlsRetSsl, loader.NodeTlsWrap, loader.NodeTlsWrapRet)
diff --git a/pkg/tools/ssl/gotls.go b/pkg/tools/ssl/gotls.go
index 2a88498..8a52ba8 100644
--- a/pkg/tools/ssl/gotls.go
+++ b/pkg/tools/ssl/gotls.go
@@ -62,10 +62,6 @@ type GoTLSSymbolAddress struct {
TCPConnOffset uint64
IsClientOffset uint64
- // casgstatus(goroutine status change) function relate locations
- CasgStatusGPLoc GoSymbolLocation
- CasgStatusNEWValLoc GoSymbolLocation
-
// write function relate locations
WriteConnectionLoc GoSymbolLocation
WriteBufferLoc GoSymbolLocation
@@ -79,7 +75,7 @@ type GoTLSSymbolAddress struct {
ReadRet1Loc GoSymbolLocation
}
-func (r *Register) GoTLS(symbolAddrMap *ebpf.Map, goIDChange, write, writeRet, read, readRet *ebpf.Program) {
+func (r *Register) GoTLS(symbolAddrMap *ebpf.Map, write, writeRet, read, readRet *ebpf.Program) {
r.addHandler("goTLS", func() (bool, error) {
buildVersionSymbol := r.searchSymbolInModules(r.modules, func(a, b string) bool {
return a == b
@@ -113,7 +109,6 @@ func (r *Register) GoTLS(symbolAddrMap *ebpf.Map, goIDChange, write, writeRet, r
}
exeFile := r.linker.OpenUProbeExeFile(pidExeFile)
- exeFile.AddLinkWithType("runtime.casgstatus", true, goIDChange)
exeFile.AddGoLink(goTLSWriteSymbol, write, writeRet, elfFile)
exeFile.AddGoLink(goTLSReadSymbol, read, readRet, elfFile)
if e := r.linker.HasError(); e != nil {
@@ -201,10 +196,6 @@ func (r *Register) generateGOTLSSymbolOffsets(register *Register, elfFile *elf.F
assignError = r.assignGoTLSStructureOffset(assignError, reader, goTLSRuntimeG, "goid", &symbolAddresses.GIDOffset)
assignError = r.assignGoTLSStructureOffset(assignError, reader, goTLSConnSymbol, "isClient", &symbolAddresses.IsClientOffset)
- // gid status change
- assignError = r.assignGoTLSArgsLocation(assignError, gidStatusFunction, "gp", &symbolAddresses.CasgStatusGPLoc)
- assignError = r.assignGoTLSArgsLocation(assignError, gidStatusFunction, "newval", &symbolAddresses.CasgStatusNEWValLoc)
-
// write
assignError = r.assignGoTLSArgsLocation(assignError, writeFunction, "c", &symbolAddresses.WriteConnectionLoc)
assignError = r.assignGoTLSArgsLocation(assignError, writeFunction, "b", &symbolAddresses.WriteBufferLoc)