On 1 September 2016 at 12:05, Nadav Har'El <[email protected]> wrote:
> Hi, we are trying to run code compiled with the golang compiler to on the > OSv kernel. > OSv is a unikernel (kernel for a virtual-machine intending to run a single > program at a time). It is mostly compatible with the Linux glibc ABI, > meaning that you can "mostly" take unmodified Linux executable code and run > it on OSv. > > We're in fact very close to running golang-compiled code on OSv. But we're > having trouble with the code's use of TLS (thread-local storage), and I > wanted to ask for advice from the experts on golang's implementation. > > If I understand correctly, golang uses only one per-thread variable, "g" > (or maybe also a second one, "m"?). > > The ELF ABI has a standard (https://www.akkadia.org/drepper/tls.pdf) on > how several components of an executable linked at run time can "share" the > single fs_base offset (on x86) used to implement TLS. So while Go only > needs a single "g" thread-local variable, some other shared library loaded > in the same process might need an additional thread-local variable, and the > ELF standard nicely allows to pull that off. > > BUT, from the code we've inspected, it seems that golang-compiled code > doesn't use this technique. Instead, it seems it uses arch_prctl's > ARCH_SET_FS to completely take over the fs_base of Go threads. This would > cause big problems for us when these Go threads want to call other non-Go > functions (in OSv, the system calls are ordinary functions too). > Is this really a problem? AFAIK Go programs don't call OSv functions directly and use syscall instruction for everything. This means that we have only two places where change between executing Go program and OSv can occur: syscall and interrupt. We could add logic in those places that would set %fs appropriately to the application needs. In other words, once application uses ARCH_SET_FS OSv would maintain two %fs values. One to be set when OSv itself is executing (and the libraries it uses) and the other when the application runs. The switch between these values happens at interrupt and syscall exit and entry. Obviously, we won't be able to support applications that use ARCH_SET_FS *and* link against symbols provided by OSv but it happens to be sufficient solution for Go programs. > > My question is - is there a "build mode" or something where Go can > allocate its "g" variable in the usual ELF way - and cooperate with other C > code running in the same process - instead of taking over the fs_base? > > I have read conflicting reports on what the "c-shared" mode does. On one > hand it seems it does *something* similar to what I want - it seems it has > a single TLS variable (in the "initial exec" variant of the ELF TLS > standard). On the other hand, I also read it still uses prctl()... > > So *should* c-shared do what I am looking for? Does it in fact do this > currently? > > Thanks. I'm looking forward to seeing Go code running on OSv soon :-) > > -- > Nadav Har'El > [email protected] > > -- > You received this message because you are subscribed to the Google Groups > "OSv Development" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
