Messages in this thread | | | Date | Tue, 17 Nov 2015 12:39:45 +0100 | Subject | irq_fpu_usable() is irreliable | From | "Jason A. Donenfeld" <> |
| |
Hi folks,
The availability of the FPU in kernel space, as you know, is determined by this function:
bool irq_fpu_usable(void) { return !in_interrupt() || interrupted_user_mode() || interrupted_kernel_fpu_idle(); }
My understanding is that the first check is !in_interrupt(), because if `current` is valid - if we are in process context - then we have a place to store the existing FPU regs in kernel_fpu_begin, to be restored later in kernel_fpu_end. Recently I've been tracking down a problem in which irq_fpu_usable() returns false, yet a stack trace shows the first function is the syscall entry point. This leads me to believe that in_interrupt() is not an adequate way of testing for a valid `current`. In my particular problematic case, the reason in_interrupt() was returning false is because a number of rcu_read_lock_bh()s were being held; IOW this is occurring in the ndo_start_xmit path of a network driver.
I therefore propose changing the function to this:
bool irq_fpu_usable(void) { return (!in_irq() && !in_nmi()) || interrupted_user_mode() || interrupted_kernel_fpu_idle(); }
What would you think of that?
Thanks, Jason
| |