Skip site navigation (1)Skip section navigation (2)
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>