This is the mail archive of the
libc-ports@sources.redhat.com
mailing list for the libc-ports project.
Re: [parisc-linux] Re: [PATCH] Fix the atomic compare and swap function on hppa
On Tue, May 22, 2007 at 10:05:11AM -0400, Carlos O'Donell wrote:
> On 5/22/07, Aurelien Jarno <aurelien@aurel32.net> wrote:
> >Well we still have a problem, the failure occurs less often, but still
> >sometimes. Apparently it is cause by the kernel returning -EDEADLOCK.
> >How should that be handled? The same way as -EAGAIN?
>
> No.
>
> The only way you can get -EDEADLOCK back is to build a kernel with
> ENABLE_LWS_DEBUG, this is strictly a developer only feature, please do
> not enable this.
>
> Please verify that ENABLE_LWS_DEBUG is defined as 0 in:
> arch/parisc/kernel/syscall.S:467 #define ENABLE_LWS_DEBUG 0
>
As discussed on IRC, there is actually a bug in the kernel:
#define ENABLE_LWS_DEBUG 0
...
# ifdef ENABLE_LWS_DEBUG
ENABLE_LWS_DEBUG is defined as 0, so the debug code is enabled.
Please find below a patch which fixes the -EAGAIN problem by harcoding
the value directly into the code. It also adds a workaround for unfixed
kernels which return -EDEADLOCK.
Cheers,
Aurelien
2007-05-22 Aurelien Jarno <aurelien@aurel32.net>
* sysdeps/unix/sysv/linux/hppa/bits/atomic.h: check for -11
(-EAGAIN) instead of 11. Loop again when the kernel returns
error -45 (-EDEADLOCK) to workaround a kernel bug (debugging
code enabled).
--- ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h.orig 2007-05-20 03:28:39.000000000 +0200
+++ ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h 2007-05-20 03:24:41.000000000 +0200
@@ -56,10 +56,14 @@
#define LWS_CAS "0"
/* Note r31 is the link register */
#define LWS_CLOBBER "r1", "r26", "r25", "r24", "r23", "r22", "r21", "r20", "r28", "r31", "memory"
-#define ASM_EAGAIN "11"
#if __ASSUME_LWS_CAS
-/* The only basic operation needed is compare and exchange. */
+/* The only basic operation needed is compare and exchange.
+ -11 corresponds to -EAGAIN, and -45 to -EDEADLOCK. The constants
+ must stay the same to avoid breaking backwards compatibility.
+
+ The check for -EDEADLOCK workarounds a kernel bug (debugging code
+ enabled by default). */
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
({ \
volatile int lws_errno = EFAULT; \
@@ -71,7 +75,10 @@
"copy %5, %%r24 \n\t" \
"ble " LWS "(%%sr2, %%r0) \n\t" \
"ldi " LWS_CAS ", %%r20 \n\t" \
- "cmpib,=,n " ASM_EAGAIN ",%%r21,0b \n\t" \
+ "cmpib,=,n -11,%%r21,0b \n\t" \
+ "nop \n\t" \
+ "ldi -45, %%r24 \n\t" \
+ "cmpb,=,n %%r24,%%r21,0b \n\t" \
"nop \n\t" \
"stw %%r28, %0 \n\t" \
"sub %%r0, %%r21, %%r21 \n\t" \
--
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73
: :' : Debian developer | Electrical Engineer
`. `' aurel32@debian.org | aurelien@aurel32.net
`- people.debian.org/~aurel32 | www.aurel32.net