[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 John Ousterhout changed: What|Removed |Added CC||ouster at cs dot stanford.edu --- Comment #10 from John Ousterhout --- I accidentally posted this on issue 26461, so I'm reposting here; sorry for the duplicate... Kernel threads are great, and it may seem like there's no need for user-level threads now that kernel threads are universally available. But layering user-level threads on top of kernel threads can offer a speedup of at least 10x for common operations. The fact that so many different people have responded on this issue and issue 26461 is pretty good evidence that it can be useful to do "context switching" on top of kernel threads. My research group has recently run up against this same problem. Thread-local variables (i.e. kernel-thread-locals) are still useful in this environment (for example, we use one to keep track of the user thread that's loaded on the current kernel thread). One of the great things about gcc is that it has supported a huge variety of applications and design styles; it would be a shame for gcc to preclude this particular class of applications. Is it unreasonably difficult to add a mechanism to force gcc to flush cached thread-local addresses? Those of us using the mechanism would be happy to pay a small performance penalty for it, but presumably that won't affect applications that don't use the mechanism. Please reconsider?
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #9 from Tor Myklebust --- OK, I gather that the gcc developers, as a group, are against changing this behaviour. (I can speculate why; almost all code that uses TLS will see a slowdown.) In order to work around this behaviour, one needs a way to tell gcc that %fs:0 may have been modified. I don't see a way to do this. None of the following hacks, if placed before and after the call to something(), produce a desirable result: - asm volatile("":::"memory"); no change in output. - asm volatile("":::"fs"); unknown register name 'fs' in 'asm'. - asm volatile("":::"%fs"); unknown register name '%fs' in 'asm'. - __seg_fs uintptr_t *hack = 0; asm volatile("" : "+r"(hack) :: "memory"); no change in behaviour, though the TLS region pointer at %fs:0 gets roundtripped through %rax.
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 Richard Biener changed: What|Removed |Added Target||x86_64-*-* Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #8 from Richard Biener --- Thus invalid.
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #7 from Jakub Jelinek --- This is not a bug, that is how TLS is designed. You shouldn't change threads in the middle of a function. If you do, you shouldn't use TLS, but something different; basically you are implementing your own threading library then and you are responsible for arranging that it works.
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #6 from Tor Myklebust --- Created attachment 41085 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41085&action=edit Program referenced in comment 4
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #5 from Tor Myklebust --- Created attachment 41084 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41084&action=edit Program referenced in comment 4
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #4 from Tor Myklebust --- I suppose the program attached doesn't demonstrate that. I ran: info gcc 'C ext' 'thread' I read the following text: When the address-of operator is applied to a thread-local variable, it is evaluated at run time and returns the address of the current thread's instance of that variable. An address so obtained may be used by any thread. When a thread terminates, any pointers to thread-local variables in that thread become invalid. This states that I get the address of the current thread's instance of a thread-local variable when I '&' a variable declared __thread. I edited f() to take the address of foo and pass the address to dump(), and edited dump() to print both the const char ** passed in and the string pointed to by the pointed-to pointer. The result is attached. The program continues to fail with '-O3 -fPIC.' (It also fails with only '-O3.') But now the program relies on the documentation snippet above; it takes the address of the thread-local variable foo once before the call to switch_thread and once after the call to switch_thread and prints the string pointed to by the pointer obtained by taking the address of the thread-local variable foo. Before the call to switch_thread, the current thread's instance of foo points to the string ":(" and dump() faithfully prints a sad face. However, after the call to switch_thread, the current thread's instance of the thread-local variable foo points to the string ":)." With '-O3 -fPIC', the second call to dump() erroneously prints ":(." Since the observed behaviour of the program when compiled with '-O3 -fPIC' deviates from the behaviour specified for the program by the compiler's documentation, I conclude that there is a bug either in the compiler or its documentation---this is a bug. Your comment about swapcontext appears to be a red herring. Whether swapcontext is aware of TLS is irrelevant. I am not aware of any language in the C standard or in gcc's documentation that forbids changing the thread executing a given piece of code with a given stack while it is running. Although gcc has done no analysis to prove that this assumption is sound, the code being generated by gcc effectively assumes that a global pointer is not mutated within a function call.
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #3 from Andrew Pinski --- Why do you think this is a bug? swapcontext is not TLS aware at all and was not designed to be.
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #2 from Tor Myklebust --- For completeness, this issue was raised as Stackoverflow question 43081742 by user merlin2011.
[Bug ipa/80258] On x86_64 with -fPIC, accesses to TLS can see the wrong thread's TLS
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80258 --- Comment #1 from Tor Myklebust --- Created attachment 41083 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41083&action=edit A program that breaks with -O3 -fPIC