Subject: Re: sleep sleeps forever (again)
To: None <port-sparc64@netbsd.org>
From: Steve Woodford <scw@netbsd.org>
List: port-sparc64
Date: 09/23/2004 22:00:18
--Boundary-00=_ilzUBhaUE0GDlZw
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Thursday 23 September 2004 08:43, matthew green wrote:
> my ultra10/440 experienced the sleep forever bug twice a couple of
> weeks ago.  it happens on any sparc64 box.  it seems to be more
> likely to occur if the disk and network are busy (eg, both the
> above happened when i started writing and read heavily over NFS
> at the same time.)

Just on a whim, can someone try out the attached patch to 
sys/arch/sparc64/include/psl.h to see if it cures the sleep forever 
bug?

There's a chance that gcc is reordering instructions around some spl* 
calls. The patch should address this.

Cheers, Steve

--Boundary-00=_ilzUBhaUE0GDlZw
Content-Type: text/x-diff;
  charset="us-ascii";
  name="psl.h.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="psl.h.diff"

Index: psl.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/include/psl.h,v
retrieving revision 1.26
diff -u -r1.26 psl.h
--- psl.h	14 Mar 2004 18:18:54 -0000	1.26
+++ psl.h	23 Sep 2004 20:52:31 -0000
@@ -303,6 +303,7 @@
 {
 	int pstate = getpstate();
 
+	__insn_barrier();
 	setpstate(pstate & ~PSTATE_IE);
 	return (pstate);
 }
@@ -311,6 +312,7 @@
 intr_restore(int pstate)
 {
 	setpstate(pstate);
+	__insn_barrier();
 }
 
 /*
@@ -334,9 +336,11 @@
 static __inline int name##X(const char* file, int line) \
 { \
 	int oldpil; \
+	__insn_barrier(); \
 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
 	SPLPRINT(("{%s:%d %d=>%d}", file, line, oldpil, newpil)); \
 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
+	__insn_barrier(); \
 	return (oldpil); \
 }
 /* A non-priority-decreasing version of SPL */
@@ -345,11 +349,13 @@
 static __inline int name##X(const char* file, int line) \
 { \
 	int oldpil; \
+	__insn_barrier(); \
 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
-	if (newpil <= oldpil) \
-		return oldpil; \
-	SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \
-	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
+	if (newpil > oldpil) {\
+		SPLPRINT(("{%s:%d %d->!d}", file, line, oldpil, newpil)); \
+		__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
+	} \
+	__insn_barrier(); \
 	return (oldpil); \
 }
 
@@ -360,8 +366,10 @@
 static __inline int name() \
 { \
 	int oldpil; \
+	__insn_barrier(); \
 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
+	__insn_barrier(); \
 	return (oldpil); \
 }
 /* A non-priority-decreasing version of SPL */
@@ -370,10 +378,11 @@
 static __inline int name() \
 { \
 	int oldpil; \
+	__insn_barrier(); \
 	__asm __volatile("rdpr %%pil,%0" : "=r" (oldpil)); \
-	if (newpil <= oldpil) \
-		return oldpil; \
-	__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
+	if (newpil > oldpil) \
+		__asm __volatile("wrpr %%g0,%0,%%pil" : : "n" (newpil)); \
+	__insn_barrier(); \
 	return (oldpil); \
 }
 #endif
@@ -474,7 +483,9 @@
 	__asm __volatile("rdpr %%pil,%0" : "=r" (pil));
 	SPLPRINT(("{%d->%d}", pil, newpil));
 #endif
+	__insn_barrier();
 	__asm __volatile("wrpr %%g0,%0,%%pil" : : "rn" (newpil));
+	__insn_barrier();
 }
 #endif /* KERNEL && !_LOCORE */
 

--Boundary-00=_ilzUBhaUE0GDlZw--