Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Feb 2003 17:32:11 -0500
From:      Jake Burkholder <jake@locore.ca>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        FreeBSD current users <current@FreeBSD.ORG>
Subject:   Re: question on profiling code
Message-ID:  <20030217173211.G81102@locore.ca>
In-Reply-To: <20030218075519.Y7132-100000@gamplex.bde.org>; from bde@zeta.org.au on Tue, Feb 18, 2003 at 08:54:59AM %2B1100
References:  <20030217021512.O63597@locore.ca> <20030218075519.Y7132-100000@gamplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> 
> Can you explain how fuswintr() and suswintr() work on sparc64's?  They
> seem to cause traps if the user counter is not mapped, and I can't see
> where the traps are handled.  ia64/trap.c has a comment about where these
> traps are handled, but has dummies for fuswintr() and suswintr() so the
> traps never occur.  Depending on traps in fast interrupt handlers is
> a bug IMO.  It extends the scope of the fast interrupt handler to the
> trap handler, and it is difficult to limit this scope and verify the
> locking for it.

Ok.  Sparc64 uses "lazy trap handling", similar to how I saw you'd done
in your sys.dif.  The functions that access user space are delimited by
labels, and in trap and trap_pfault we check to see if the pc is inside
of the labels.  fuswintr and suswintr and bracketed by fs_nofault_intr_begin
and fs_nofault_intr_end, which trap_pfault checks for specifically before
doing much of anything:

        if (ctx != TLB_CTX_KERNEL) {
                if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
                    (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
                     tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
                        tf->tf_tpc = (u_long)fs_fault;
                        tf->tf_tnpc = tf->tf_tpc + 4;
                        return (0);
                }
		... handle fault

ctx != TLB_CTX_KERNEL is akin to va < VM_MAXUSER_ADDRESS (the address spaces
overlap on sparc64 so we can only rely on tlb context numbers).  Note that
the range bracketed by the fs_nofault_intr_* is included in the fs_nofault
range, which handles alignment or data access exception faults.

It does take some special care in trap() and trap_pfault() not to access
important data, or acquire any locks before this test.  Non-trivial
interrupts are still masked here, which buys us something.  Probably the
vmspace pointer should not be counted on in this context, but I don't think
it will ever be invalid for the current process, especially since the original
interrupt occured in usermode.

The only locking that's required that I can see is that PS_PROFIL not be
set when the profiling buffer is invalid.  But all that will happen is that
attempts to update the profiling buffer will be ignored.  Technically the
process should get a signal but addupc_task doesn't check the return value
of copyin/out (oops).

Jake

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030217173211.G81102>