From owner-freebsd-hackers@FreeBSD.ORG Sat Oct 27 17:39:01 2007 Return-Path: Delivered-To: FreeBSD-Hackers@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 742CC16A418 for ; Sat, 27 Oct 2007 17:39:01 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from harmony.bsdimp.com (bsdimp.com [199.45.160.85]) by mx1.freebsd.org (Postfix) with ESMTP id 249FC13C4A3 for ; Sat, 27 Oct 2007 17:39:01 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from localhost (localhost [127.0.0.1]) by harmony.bsdimp.com (8.14.1/8.14.1) with ESMTP id l9RHaAX1093387; Sat, 27 Oct 2007 11:36:11 -0600 (MDT) (envelope-from imp@bsdimp.com) Date: Sat, 27 Oct 2007 11:36:58 -0600 (MDT) Message-Id: <20071027.113658.-2014464451.imp@bsdimp.com> To: Danovitsch@vitsch.net From: "M. Warner Losh" In-Reply-To: <200710271853.44167.Danovitsch@vitsch.net> References: <200710222211.51590.Danovitsch@vitsch.net> <20071024.151513.-713548131.imp@bsdimp.com> <200710271853.44167.Danovitsch@vitsch.net> X-Mailer: Mew version 5.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: FreeBSD-Hackers@FreeBSD.org Subject: Re: Floating point in interrupt handler X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Oct 2007 17:39:01 -0000 In message: <200710271853.44167.Danovitsch@vitsch.net> "Daan Vreeken [PA4DAN]" writes: : Hi Warner, : : On Wednesday 24 October 2007 23:15:13 you wrote: : > In message: <200710222211.51590.Danovitsch@vitsch.net> : > : > "Daan Vreeken [PA4DAN]" writes: : > : But what I haven't found is a description of exactly what the kernel is : > : missing to allow floating point operations to be done there. : > : > FPU context is assumed to only change in user processes. You'd have : > to fix the FPU state saving code to cope with it changing everywhere, : > or you'd have to explicitly put the goo to save/restore it around the : > FP you want to do in the kernel. : : Issei Suzuki pointed me into the right direction in his reply. (The following : text is an exact copy of the reply I sent to Issei, but I'll just copy it : here to show the code) : If I understand the npx code correctly, there are 2 options when the kernel : arrives at hardclock() : : o The current process is using the FPU (fpcurthread != NULL) : o The current process hasn't used the FPU (yet) since it has been switched to : (fpcurthread == NULL) : In the first case, FPU instructions can be used and will not result in a trap, : but we should save/restore the FPU state before using them so userland : doesn't get confused. In the last case FPU instructions result in a trap, so : we need stop/start_emulating(), but as no one is using the FPU, there is no : need to save/restore it's state. : : With this in mind I've come up with the following code : : : At the start of the function : : // check FPU state on entry : if (PCPU_GET(fpcurthread) != NULL) { : // someone is using the FPU : // save it's state and remember to put it back later : restore = 1; : fpusave(&fpu_state); : } else { : // no one is using the FPU : // enable use of FPU instructions, no need to save it's state : restore = 0; : stop_emulating(); : } : // init FPU state every time we get here, as we don't know who has : // been playing with it in between calls : fninit(); : control = __INITIAL_NPXCW__; : fldcw(&control); : : Then we do some floating point arithmetic. : : And at the end of the function : : // restore FPU state before we leave : if (restore) { : // restore FPU registers to what they were : fpurstor(&fpu_state); : } else { : // no one was using the FPU, so re-enable the FPU trap : start_emulating(); : } : : With this code trap-22 has stopped to trigger within my function. The FPU : instructions still seem to be executed correctly in my function and when : adding a couple of printf()'s I can see it fpusave() and fpurstor() when : interrupting a userland process that uses the FPU. : Does this look reasonable to everyone? My concern here would be to make sure that your code doesn't migrate from one CPU to another. Other than that, I think it is OK. Warner