Re: Re: [PATCH] Fix the atomic compare and swap function on hppa

Aurelien Jarno <[email protected]>
Newsgroups gmane.linux.ports.hppa
Message-ID <[email protected]>
On Tue, May 22, 2007 at 10:05:11AM -0400, Carlos O'Donell wrote:
> On 5/22/07, Aurelien Jarno <[email protected]> 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  <[email protected]>

	* 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
 `. `'   [email protected]         | [email protected]
   `-    people.debian.org/~aurel32 | www.aurel32.net
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.