Improve the performance of getting the goid in the Golang (#82)

diff --git a/CHANGES.md b/CHANGES.md
index 6955adb..82cc739 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -10,6 +10,7 @@
 * 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 @@
 {
     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.c
deleted file mode 100644
index 80c0813..0000000
--- a/bpf/include/goid.c
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to Apache Software Foundation (ASF) under one or more contributor
-// license agreements. See the NOTICE file distributed with
-// this work for additional information regarding copyright
-// ownership. Apache Software Foundation (ASF) licenses this file to you 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 "symbol_offsets.h"
-
-struct {
-	__uint(type, BPF_MAP_TYPE_HASH);
-	__uint(max_entries, 1024);
-	__type(key, __u64);
-	__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) {
-        return 0;
-    }
-
-    // get goid in runtime.g
-    int64_t goid;
-    bpf_probe_read(&goid, sizeof(goid), gptr + symaddrs->gid_offset);
-
-    // newval in runtime.g
-    __u32 status;
-    assign_go_tls_arg(&status, sizeof(status), symaddrs->casg_status_new_val_loc, sp, regs);
-
-    // check the status is running
-    if (status == 2) {
-        set_goid(id, goid);
-    }
-    return 0;
-}
\ No newline at end of file
diff --git a/bpf/include/goid.h b/bpf/include/goid.h
new file mode 100644
index 0000000..92f0598
--- /dev/null
+++ b/bpf/include/goid.h
@@ -0,0 +1,55 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+#pragma once
+
+#include "api.h"
+#include "symbol_offsets.h"
+
+struct {
+	__uint(type, BPF_MAP_TYPE_HASH);
+	__uint(max_entries, 1024);
+	__type(key, __u64);
+	__type(value, __u64);
+} go_tgid_goid_map SEC(".maps");
+static __inline __u64 get_goid(__u64 id) {
+    __u32 tgid = id >> 32;
+    struct go_tls_args_symaddr_t* symaddrs = get_go_tls_args_symaddr(tgid);
+    if (symaddrs == NULL) {
+       return 0;
+    }
+
+    // Get fsbase from `struct task_struct`.
+    const struct task_struct* task_ptr = (struct task_struct*)bpf_get_current_task();
+    if (!task_ptr) {
+        return 0;
+    }
+
+    // thread local storage
+    const void* fs_base;
+    bpf_probe_read_kernel(&fs_base, sizeof(fs_base), &(task_ptr->thread.fsbase));
+
+    __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));
+
+    // 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 @@
     __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 @@
 	__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 @@
 
 	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 @@
 
 	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 @@
 	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 @@
 	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 @@
 		}
 
 		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 @@
 	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)