Patchwork Fix libitm futex handling on non-x86/ppc/sh/alpha targets

login
register
mail settings
Submitter Jakub Jelinek
Date March 26, 2014, 9:19 p.m.
Message ID <20140326211951.GQ1817@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/334107/
State New
Headers show

Comments

Jakub Jelinek - March 26, 2014, 9:19 p.m.
Hi!

The sys_futex0 caller expects return values as returned by raw syscalls,
i.e. value >= 0 success, negative value are errors -errorval.
But, the syscall function returns value >= 0 on success, and -1 on error,
with errno set to errorval.  This means if e.g. futex syscall fails with
EAGAIN, and EPERM is 1, we get GTM program terminated because we think
futex returned -EPERM.

Fixed thusly, bootstrapped/regtested on s390x-linux, ok for trunk/4.8?

Testcase that previously succeeded at most 9 times in a row before crashing
now succeeded over 38000 iterations in a row (before I've stopped it).

2014-03-26  Jakub Jelinek  <jakub@redhat.com>

	* config/linux/futex_bits.h: Include errno.h.
	(sys_futex0): If syscall returns -1, return -errno rather than
	-1.


	Jakub
Torvald Riegel - March 26, 2014, 9:43 p.m.
On Wed, 2014-03-26 at 22:19 +0100, Jakub Jelinek wrote:
> Hi!
> 
> The sys_futex0 caller expects return values as returned by raw syscalls,
> i.e. value >= 0 success, negative value are errors -errorval.
> But, the syscall function returns value >= 0 on success, and -1 on error,
> with errno set to errorval.  This means if e.g. futex syscall fails with
> EAGAIN, and EPERM is 1, we get GTM program terminated because we think
> futex returned -EPERM.
> 
> Fixed thusly, bootstrapped/regtested on s390x-linux, ok for trunk/4.8?

Looks good to me.  Thanks.

Patch

--- 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;
 }