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