Date: Thu, 14 Feb 2008 10:38:20 -0500 From: John Baldwin <jhb@freebsd.org> To: Warner Losh <imp@freebsd.org> Cc: Perforce Change Reviews <perforce@freebsd.org> Subject: Re: PERFORCE change 135027 for review Message-ID: <200802141038.20967.jhb@freebsd.org> In-Reply-To: <200802080917.m189HF0o016528@repoman.freebsd.org> References: <200802080917.m189HF0o016528@repoman.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Friday 08 February 2008 04:17:15 am Warner Losh wrote: > http://perforce.freebsd.org/chv.cgi?CH=135027 > > Change 135027 by imp@imp_lighthouse on 2008/02/08 09:16:43 > > First cut at implementing gonzo's suggestions for AST handling. > > Affected files ... > > .. //depot/projects/mips2-jnpr/src/sys/mips/include/asm.h#10 edit > .. //depot/projects/mips2-jnpr/src/sys/mips/mips/exception.S#12 edit > .. //depot/projects/mips2-jnpr/src/sys/mips/mips/genassym.c#6 edit > .. //depot/projects/mips2-jnpr/src/sys/mips/mips/swtch.S#13 edit > .. //depot/projects/mips2-jnpr/src/sys/mips/mips/trap.c#10 edit > > Differences ... > > ==== //depot/projects/mips2-jnpr/src/sys/mips/include/asm.h#10 (text+ko) ==== > > @@ -304,6 +304,26 @@ > .align 3 > > /* > + * Call ast if required > + */ > +#define DO_AST \ > + GET_CPU_PCPU(k1) \ > + lw k1, PC_CURTHREAD(k1); \ > + lw t0, TD_FLAGS(k1); \ > + and t0, t0, (TDF_ASTPENDING|TDF_NEEDRESCHED); \ > + beq t0, zero, 27f; \ > + nop; \ > + lw k1, TD_FRAME(k1); \ > + lw t0, TF_REG_SR(k1); \ > + and t0, t0, SR_KSU_USER; \ > + beq t0, zero, 27f; \ > + nop; \ > + move a0, k1; \ > + jal ast; \ > + nop; \ > +27: > + > +/* > * XXX retain dialects XXX I'm not a MIPS asm expert, but I don't think you are disabling interrupts here like you need to do. Specifically, an interrupt might set an AST (e.g. hardclock() can set one for a pending SIGPROF or SIGALRM, or you can get an IPI to forward a signal sent from another CPU in SMP) so you have to do the check like this (psuedo-code): intr_disable(); while (td->td_flags & (TDF_ASTPENDING|TDF_NEEDRESCHED)) { intr_enable(); ast(); intr_disable(); } eret/reti/iret, etc. It also seems you are missing the loop above as well so that after ast returns you branch back up and check the flags again in case you got an interrupt that set an AST while you were in ast() with interrupts enabled. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802141038.20967.jhb>