Subject: enlightenment on zs overruns
To: None <port-sparc@NetBSD.ORG>
From: Chuck Silvers <chuq@chuq.com>
List: port-sparc
Date: 11/14/1997 04:12:20
ok, after yet more thought, I've really got it figured out now.
(no really! :-)
the code that takes forever and causes the zs overruns is ctx_alloc().
long ago this wasn't a problem, since the splpmap() inside ctx_alloc()
would lower IPL to PIL_CLOCK, thus allowing zs interrupts thru.
once splpmap() was changed to be raising-only, IPL inside ctx_alloc()
remains at splhigh() (since it's called from cpu_switch(), called from
mi_switch()). since cpu_switch() is already changing IPL all over the place
(it does the equivalent of "spl0(); splhigh();" right at the top,
which should have been a tip-off), we simply need to make cpu_switch()
lower IPL to PIL_CLOCK right before it calls ctx_alloc().
(PIL_CLOCK is for both splclock() and splpmap().)
alternatively, splpmap() could be changed back to raising-or-lowering,
but I'm sure there was a reason for changing it in the first place.
here's a diff...
*** locore.s.orig Tue Sep 23 04:33:29 1997
--- locore.s Fri Nov 14 03:46:26 1997
***************
*** 4408,4415 ****
rd %psr, %g1 ! oldpsr = %psr;
sethi %hi(_curproc), %g7
ld [%g7 + %lo(_curproc)], %g4 ! lastproc = curproc;
- st %g1, [%o0 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
/*
* In all the fiddling we did to get this far, the thing we are
--- 4408,4415 ----
rd %psr, %g1 ! oldpsr = %psr;
sethi %hi(_curproc), %g7
ld [%g7 + %lo(_curproc)], %g4 ! lastproc = curproc;
andn %g1, PSR_PIL, %g1 ! oldpsr &= ~PSR_PIL;
+ st %g1, [%o0 + PCB_PSR] ! cpcb->pcb_psr = oldpsr;
/*
* In all the fiddling we did to get this far, the thing we are
***************
*** 4588,4595 ****
SET_SP_REDZONE(%o0, %o1)
CHECK_SP_REDZONE(%o0, %o1)
#endif
! /* finally, enable traps */
! wr %g2, 0, %psr ! psr = newpsr;
/*
* Now running p. Make sure it has a context so that it
--- 4588,4595 ----
SET_SP_REDZONE(%o0, %o1)
CHECK_SP_REDZONE(%o0, %o1)
#endif
! /* finally, enable traps (but at PIL_CLOCK instead of the saved IPL) */
! wr %g2, (PIL_CLOCK << 8), %psr
/*
* Now running p. Make sure it has a context so that it
whew. sorry about all the flailing around...
-Chuck