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>