From: Oleg Nesterov <oleg@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
Andrew Morton <akpm@linux-foundation.org>,
Fenghua Yu <fenghua.yu@intel.com>,
Suresh Siddha <sbsiddha@gmail.com>,
Bean Anderson <bean@azulsystems.com>,
"H. Peter Anvin" <hpa@zytor.com>, Ingo Molnar <mingo@redhat.com>,
Thomas Gleixner <tglx@linutronix.de>,
the arch/x86 maintainers <x86@kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH 4/4] x86, fpu: irq_fpu_usable: kill all checks except !in_kernel_fpu
Date: Fri, 29 Aug 2014 20:17:29 +0200 [thread overview]
Message-ID: <20140829181729.GE30659@redhat.com> (raw)
In-Reply-To: <20140829181533.GA30659@redhat.com>
ONCE AGAIN, THIS IS MORE THE QUESTION THAN THE PATCH.
interrupted_kernel_fpu_idle() does:
if (use_eager_fpu())
return true;
return !__thread_has_fpu(current) &&
(read_cr0() & X86_CR0_TS);
and it is absolutely not clear why these 2 cases differ so much.
To remind, the use_eager_fpu() case is buggy; __save_init_fpu() in
__kernel_fpu_begin() can race with math_state_restore() which does
__thread_fpu_begin() + restore_fpu_checking(). So we should fix this
race anyway and we can't require __thread_has_fpu() == F likes the
!use_eager_fpu() case does, in this case kernel_fpu_begin() will not
work if it interrupts the idle thread (this will reintroduce the
performance regression fixed by 5187b28f).
Probably math_state_restore() can use kernel_fpu_disable/end() which
sets/clears in_kernel_fpu, or it can disable irqs. Doesn't matter, we
should fix this bug anyway.
And if we fix this bug, why else !use_eager_fpu() case needs the much
more strict check? Why we can't handle the __thread_has_fpu(current)
case the same way?
The comment deleted by this change says:
and TS must be set so that the clts/stts pair does nothing
and can explain the difference, but I can not understand this (again,
assuming that we fix the race(s) mentoined above).
Say, user_fpu_begin(). Yes, kernel_fpu_begin/end() can restore X86_CR0_TS.
But this should be fine? A context switch before restore_user_xstate()
can equally set it back? And device_not_available() should be fine even
in kernel context?
I'll appreciate any comment.
---
arch/x86/kernel/i387.c | 44 +-------------------------------------------
1 files changed, 1 insertions(+), 43 deletions(-)
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index 9fb2899..ef60f33 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -22,54 +22,12 @@
static DEFINE_PER_CPU(bool, in_kernel_fpu);
/*
- * Were we in an interrupt that interrupted kernel mode?
- *
- * On others, we can do a kernel_fpu_begin/end() pair *ONLY* if that
- * pair does nothing at all: the thread must not have fpu (so
- * that we don't try to save the FPU state), and TS must
- * be set (so that the clts/stts pair does nothing that is
- * visible in the interrupted kernel thread).
- *
- * Except for the eagerfpu case when we return 1.
- */
-static inline bool interrupted_kernel_fpu_idle(void)
-{
- if (this_cpu_read(in_kernel_fpu))
- return false;
-
- if (use_eager_fpu())
- return true;
-
- return !__thread_has_fpu(current) &&
- (read_cr0() & X86_CR0_TS);
-}
-
-/*
- * Were we in user mode (or vm86 mode) when we were
- * interrupted?
- *
- * Doing kernel_fpu_begin/end() is ok if we are running
- * in an interrupt context from user mode - we'll just
- * save the FPU state as required.
- */
-static inline bool interrupted_user_mode(void)
-{
- struct pt_regs *regs = get_irq_regs();
- return regs && user_mode_vm(regs);
-}
-
-/*
* Can we use the FPU in kernel mode with the
* whole "kernel_fpu_begin/end()" sequence?
- *
- * It's always ok in process context (ie "not interrupt")
- * but it is sometimes ok even from an irq.
*/
bool irq_fpu_usable(void)
{
- return !in_interrupt() ||
- interrupted_user_mode() ||
- interrupted_kernel_fpu_idle();
+ return !this_cpu_read(in_kernel_fpu);
}
EXPORT_SYMBOL(irq_fpu_usable);
--
1.5.5.1
next prev parent reply other threads:[~2014-08-29 18:19 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-27 18:51 [PATCH 0/4] x86, fpu: copy_process's FPU paths cleanups Oleg Nesterov
2014-08-27 18:51 ` [PATCH 1/4] x86, fpu: change __thread_fpu_begin() to use use_eager_fpu() Oleg Nesterov
2014-08-27 18:51 ` [PATCH 2/4] x86, fpu: copy_process: avoid fpu_alloc/copy if !used_math() Oleg Nesterov
2014-08-27 18:52 ` [PATCH 3/4] x86, fpu: copy_process: sanitize fpu->last_cpu initialization Oleg Nesterov
2014-08-27 18:52 ` [PATCH 4/4] x86, fpu: shift "fpu_counter = 0" from copy_thread() to arch_dup_task_struct() Oleg Nesterov
2014-08-27 20:43 ` [PATCH 0/4] x86, fpu: copy_process's FPU paths cleanups H. Peter Anvin
2014-08-28 6:50 ` Ingo Molnar
2014-08-28 12:25 ` Oleg Nesterov
2014-08-28 10:38 ` Oleg Nesterov
2014-08-28 1:17 ` Linus Torvalds
2014-08-28 11:16 ` Oleg Nesterov
2014-08-29 18:15 ` [PATCH 0/4] x86, fpu: kernel_fpu_begin/end cleanups Oleg Nesterov
2014-08-29 18:16 ` [PATCH 1/4] x86, fpu: introduce per-cpu "bool in_kernel_fpu" Oleg Nesterov
2014-09-02 6:43 ` Suresh Siddha
2014-08-29 18:16 ` [PATCH 2/4] x86, fpu: don't abuse ->has_fpu in __kernel_fpu_begin/end Oleg Nesterov
2014-08-29 18:17 ` [PATCH 3/4] x86, fpu: irq_fpu_usable: always return true if use_eager_fpu() Oleg Nesterov
2014-08-29 18:17 ` Oleg Nesterov [this message]
2014-09-02 7:04 ` [PATCH 4/4] x86, fpu: irq_fpu_usable: kill all checks except !in_kernel_fpu Suresh Siddha
2014-09-02 12:58 ` Oleg Nesterov
2014-09-02 14:13 ` Oleg Nesterov
2014-09-02 5:04 ` [PATCH 0/4] x86, fpu: copy_process's FPU paths cleanups Suresh Siddha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140829181729.GE30659@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=bean@azulsystems.com \
--cc=fenghua.yu@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=sbsiddha@gmail.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.