Skip to content

gollvm: find a better way to deal with g #37295

@erifan

Description

@erifan

Currently, gollvm stores the current g in tls. The runtime.getg () function returns the current g. This function will be inlined for better performance and the inlining will be disabled by GoSafeGetg pass in some situations. Cherry described this situation in this pass:

within a function,
//
//   load g
//   call mcall(...)
//   load g
//
// may be compiled to
//
//   leaq    g@TLS, %rdi
//   call    __tls_get_addr
//   movq    %rax, %rbx     // cache in a callee-save register %rbx
//   ... use g in %rax ...
//   call    foo
//   ... use g in %rbx ...
// This is incorrect if a thread switch happens at the call of foo.

A practical example of this situation: gofrontend/chan.go#154
By removing the inlining of the second and subsequent getg functions in a block, GoSafeGetg pass fixed this issue on linux/amd64. But on Linux / arm64, llvm performs cache optimization on the tls base address across the entire function range, so the g obtained by the second and subsequent getg in the above situation may still be wrong.

As I know, this kind of optimization is common in llvm and gcc, and it seems to be correct and very good for c / c ++. Before c / c ++ introduced a concept like goroutine, I think this optimization will not be changed. Please refer to similar issues: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26461, https://bugs.llvm.org/show_bug.cgi?id=19177.
Currently gollvm only supports linux / amd64 and linux / arm64, but as more platforms are supported in the future, I think this issue will be a problem on more platforms, so I think we need to find a better way to store the current g.

At present, the methods I can think of are as follows:

  1. Keep the current practice, store g in tls, try to remove the cache of tls base address.
  2. Follow the practice of main go, reserve a register to store g.
  3. Store g in a suitable location on the stack.
    @thanm @cherrymui @ianlancetaylor Any suggestions ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions