Bug 1080486
| Summary: | libitm: futex failed (Operation not permitted) | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Miroslav Franc <mfranc> | ||||
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> | ||||
| Status: | CLOSED ERRATA | QA Contact: | Miroslav Franc <mfranc> | ||||
| Severity: | medium | Docs Contact: | |||||
| Priority: | unspecified | ||||||
| Version: | 7.0 | CC: | mnewsome, mpolacek, ohudlick, rth, triegel | ||||
| Target Milestone: | rc | ||||||
| Target Release: | --- | ||||||
| Hardware: | s390x | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | gcc-4.8.3-1.el7 | Doc Type: | Bug Fix | ||||
| Doc Text: |
No description necessary
|
Story Points: | --- | ||||
| Clone Of: | |||||||
| : | 1180633 (view as bug list) | Environment: | |||||
| Last Closed: | 2015-03-05 07:04:54 UTC | Type: | Bug | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Bug Depends On: | |||||||
| Bug Blocks: | 1180633 | ||||||
| Attachments: |
|
||||||
Created attachment 878683 [details]
strace log
Seems to be a libitm bug (I'd say quite severe). In libitm/config/futex.cc we have:
void
futex_wait (std::atomic<int> *addr, int val)
{
long res;
res = sys_futex0 (addr, gtm_futex_wait, val);
if (__builtin_expect (res == -ENOSYS, 0))
{
gtm_futex_wait = FUTEX_WAIT;
gtm_futex_wake = FUTEX_WAKE;
res = sys_futex0 (addr, FUTEX_WAIT, val);
}
if (__builtin_expect (res < 0, 0))
{
if (res == -EWOULDBLOCK || res == -ETIMEDOUT)
;
else if (res == -EFAULT)
GTM_fatal ("futex failed (EFAULT %p)", addr);
else
GTM_fatal ("futex failed (%s)", strerror(-res));
}
}
i.e. it assumes that sys_futex0 returns either 0, or negative number as error code. That is what libitm/config/linux/{x86,powerpc,alpha,sparc,sh}/futex_bits.h implementation of sys_futex0 ensures.
But, libitm/config/linux/futex_bits.h, which is used on all other architectures,
e.g. s390, s390x, aarch64, or arm, sys_futex0 is implemented using syscall(3) function, which returns for errors -1 and error value in errno.
So, I guess completely untested patch like this could fix this:
2014-03-26 Jakub Jelinek <jakub>
* config/linux/futex_bits.h: Include errno.h.
(sys_futex0): If syscall returns -1, return -errno rather than
-1.
--- libitm/config/linux/futex_bits.h 2014-01-03 11:41:27.495153749 +0100
+++ libitm/config/linux/futex_bits.h 2014-03-26 18:03:15.307302524 +0100
@@ -31,9 +31,13 @@
#include <unistd.h>
#include <sys/syscall.h>
+#include <errno.h>
static inline long
sys_futex0 (std::atomic<int> *addr, long op, long val)
{
- return syscall (SYS_futex, (int*) addr, op, val, 0);
+ long res = syscall (SYS_futex, (int*) addr, op, val, 0);
+ if (__builtin_expect (res == -1, 0))
+ return -errno;
+ return res;
}
Yes indeed. And it appears libgomp/config/linux/futex.h has the same bug. But the libgomp bug only affects arches other than i?86/x86_64/ppc*/s390* (e.g. arm and aarch64), and only with older kernels that don't support private futexes. Fixed upstream: http://gcc.gnu.org/r208856 (and r208855), tested with a scratch build, with that libitm.so I ran the #c0 testcase successfully over 38000 times (while without this fix it succeeded at most 9 times in a row). Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2015-0320.html |
Description of problem: Simple test cases fails on s390x. Not sure whether it's s390x specific or not. Version-Release number of selected component (if applicable): libitm-4.8.2-16.el7.s390x kernel-3.10.0-113.el7.s390x glibc-2.17-55.el7.s390x How reproducible: ~20 % of attempts (at least for me) --- simple-2.c --- #include <stdlib.h> #include <pthread.h> static int x; static void *start (void *dummy __attribute__((unused))) { __transaction_atomic { x++; } return NULL; } int main() { pthread_t p[10]; int i; for (i = 0; i < 10; ++i) pthread_create (p+i, NULL, start, NULL); for (i = 0; i < 10; ++i) pthread_join (p[i], NULL); if (x != 10) abort (); return 0; } --- --- --- Steps to Reproduce: 1. gcc -g simple-2.c -O2 -o T_simple-2 -fgnu-tm -lpthread 2. ./T_simple-2 # few times (while ./T_simple-2; do :;done) Actual results: libitm: futex failed (Operation not permitted) $? = 1