Messages in this thread | | | Date | Thu, 29 Jan 2015 15:52:43 -0500 | From | Rik van Riel <> | Subject | Re: question about save_xstate_sig() - WHY DOES THIS WORK? |
| |
On 01/29/2015 03:45 PM, Oleg Nesterov wrote: > On 01/27, Rik van Riel wrote: >> >> On 01/27/2015 02:40 PM, Oleg Nesterov wrote: >>>>> >>>>> - Is unlazy_fpu()->__save_init_fpu() safe wrt >>>>> __kernel_fpu_begin() from irq? >> >> It looks like it should be safe, as long as __save_init_fpu() >> knows that the task no longer has the FPU after __kernel_fpu_end(), >> so it does not try to save the kernel FPU state to the user's >> task->thread.fpu.state->xstate > > Not sure this is enough, but... > >> The caveat here is that __kernel_fpu_begin()/__kernel_fpu_end() >> needs to be kept from running during unlazy_fpu(). > > Yes, > >> This means interrupted_kernel_fpu_idle and/or irq_fpu_usable >> need to check whether preemption is disabled, and lock out >> __kernel_fpu_begin() when preemption is disabled. > > But we already have kernel_fpu_disable/enable. unlazy_cpu() can use > it to avoid the race ?
I suspect this will be fine, if __kernel_fpu_end() from IRQ context always restores the FPU context, or calls stts, so things like save_init_fpu() will either continue where they left off, or trap and then continue where they left off.
__kernel_fpu_end() from process context can be lazier, something I can work on in my next version of the "defer FPU loading to kernel -> user space boundary" patch series.
>> I can certainly merge unlazy_fpu() and save_init_fpu() into the >> same function, but I am not sure whether or not it should call >> __thread_fpu_end() - it looks like that would be desirable in some >> cases, but not in others... > > I _think_ that we never actually want __thread_fpu_end(), although it > doesn't really hurt if !eager. Probably ulazy/save should do > > if (!__save_init_fpu()) > __thread_fpu_end();
There is at least one case where we want __thread_fpu_end(), and that is xstateregs_set. I got this by moving the __thread_fpu_end() call from save_init_fpu() into init_fpu().
I am not sure about __math_error. I suspect we may need __thread_fpu_end() in there so the math state can be re-initialized if the task catches SIGFPE and continues.
On the other hand, I do not see code in there that actually does that at the moment...
Let me send my RFC patch to clean up & merge unlazy_fpu and save_init_fpu() in the next email.
| |