Messages in this thread | | | Date | Tue, 17 Nov 2015 15:51:21 +0100 | Subject | Re: irq_fpu_usable() is irreliable | From | "Jason A. Donenfeld" <> |
| |
Hi Thomas,
On Tue, Nov 17, 2015 at 3:06 PM, Thomas Gleixner <tglx@linutronix.de> wrote: > The real question in your case is WHY interrupted_kernel_fpu_idle() > returns false. We know for sure that in a syscall with BH disabled the > first two checks are false.
Blurg, indeed. I've been trying to track that down in a different thread with the netdev folks. After not getting anywhere, I sort of felt, "dammit! can't this not be the issue, and can't I just get rid of that in_interrupt() condition?" But, as you've explained above, no, we can't get rid of that. So yes: the question is why interrupted_kernel_fpu_idle() is false. Mysteriously it happens to be the case in UDP mode but not TCP mode (the topic of the other thread), and so I should resume trying to determine why this is so. I don't entirely understand the function though:
static bool interrupted_kernel_fpu_idle(void) { if (kernel_fpu_disabled()) return false;
if (use_eager_fpu()) return true;
return !current->thread.fpu.fpregs_active && (read_cr0() & X86_CR0_TS); }
From my tests, when irq_fpu_usable() is false, the expression `!current->thread.fpu.fpregs_active && (read_cr0() & X86_CR0_TS);` is false, for both of it. What, then, is leading to the call of fpregs_activate()? I can't find anything along the syscall path that would result in this. I admit I do not have a deep understanding of how the FPU is implemented in Linux. Is it possible that this means that userspace is using the FPU? Is this what user_fpu_begin() is all about?
(If so, why is that state not stored on syscall entry? If the reason is "because it would be expensive to do it everytime", then is there a way to selectively do that only when it's necessary?)
Or, must this imply that the kernel is actually using it elsewhere, and I need to just keep digging diligently?
Thanks, Jason
| |