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