linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Suresh Siddha <sbsiddha@gmail.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nate Eldredge <nate@thatsmathematics.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
	the arch/x86 maintainers <x86@kernel.org>,
	stable <stable@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Maarten Baert <maarten-baert@hotmail.com>,
	Jan Kara <jack@suse.cz>, George Spelvin <linux@horizon.com>,
	Pekka Riikonen <priikone@iki.fi>
Subject: Re: [PATCH] Make math_state_restore() save and restore the interrupt flag
Date: Sat, 01 Feb 2014 23:19:59 -0800	[thread overview]
Message-ID: <1391325599.6481.5.camel@europa> (raw)
In-Reply-To: <CALmL7E9j5Rv8ZqUZXZh-dfNu_-7XWK_EoNjZHpuAwtG7jpk9+g@mail.gmail.com>

On Sat, 2014-02-01 at 17:06 -0800, Suresh Siddha wrote:
> Meanwhile I have the patch removing the delayed dynamic allocation for
> non-eager fpu. will post it after some testing.

Appended the patch for this. Tested for last 4-5 hours on my laptop.

The real fix for Nate's problem will be coming from Linus, with a
slightly modified option-b that Linus proposed. Linus, please let me
know if you want me to spin it. I can do it sunday night.

thanks,
suresh
---
From: Suresh Siddha <sbsiddha@gmail.com>
Subject: x86, fpu: remove the logic of non-eager fpu mem allocation at the first usage

For non-eager fpu mode, thread's fpu state is allocated during the first
fpu usage (in the context of device not available exception). This can be
a blocking call and hence we enable interrupts (which were originally
disabled when the exception happened), allocate memory and disable
interrupts etc. While this saves 512 bytes or so per-thread, there
are some issues in general.

a.  Most of the future cases will be anyway using eager
FPU (because of processor features like xsaveopt, LWP, MPX etc) and
they do the allocation at the thread creation itself. Nice to have
one common mechanism as all the state save/restore code is
shared. Avoids the confusion and minimizes the subtle bugs
in the core piece involved with context-switch.

b. If a parent thread uses FPU, during fork() we allocate
the FPU state in the child and copy the state etc. Shortly after this,
during exec() we free it up, so that we can later allocate during
the first usage of FPU. So this free/allocate might be slower
for some workloads.

c. math_state_restore() is called from multiple places
and it is error pone if the caller expects interrupts to be disabled
throughout the execution of math_state_restore(). Can lead to subtle
bugs like Ubuntu bug #1265841.

Memory savings will be small anyways and the code complexity
introducing subtle bugs is not worth it. So remove
the logic of non-eager fpu mem allocation at the first usage.

Signed-off-by: Suresh Siddha <sbsiddha@gmail.com>
---
 arch/x86/kernel/i387.c    | 14 +++++---------
 arch/x86/kernel/process.c |  6 ------
 arch/x86/kernel/traps.c   | 16 ++--------------
 arch/x86/kernel/xsave.c   |  2 --
 4 files changed, 7 insertions(+), 31 deletions(-)

diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
index e8368c6..4e5f770 100644
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -5,6 +5,7 @@
  *  General FPU state handling cleanups
  *	Gareth Hughes <gareth@valinux.com>, May 2000
  */
+#include <linux/bootmem.h>
 #include <linux/module.h>
 #include <linux/regset.h>
 #include <linux/sched.h>
@@ -186,6 +187,10 @@ void fpu_init(void)
 	if (xstate_size == 0)
 		init_thread_xstate();
 
+	if (!current->thread.fpu.state)
+		current->thread.fpu.state =
+			alloc_bootmem_align(xstate_size, __alignof__(struct xsave_struct));
+
 	mxcsr_feature_mask_init();
 	xsave_init();
 	eager_fpu_init();
@@ -219,8 +224,6 @@ EXPORT_SYMBOL_GPL(fpu_finit);
  */
 int init_fpu(struct task_struct *tsk)
 {
-	int ret;
-
 	if (tsk_used_math(tsk)) {
 		if (cpu_has_fpu && tsk == current)
 			unlazy_fpu(tsk);
@@ -228,13 +231,6 @@ int init_fpu(struct task_struct *tsk)
 		return 0;
 	}
 
-	/*
-	 * Memory allocation at the first usage of the FPU and other state.
-	 */
-	ret = fpu_alloc(&tsk->thread.fpu);
-	if (ret)
-		return ret;
-
 	fpu_finit(&tsk->thread.fpu);
 
 	set_stopped_child_used_math(tsk);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 3fb8d95..cd9c190 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -128,12 +128,6 @@ void flush_thread(void)
 	flush_ptrace_hw_breakpoint(tsk);
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
 	drop_init_fpu(tsk);
-	/*
-	 * Free the FPU state for non xsave platforms. They get reallocated
-	 * lazily at the first use.
-	 */
-	if (!use_eager_fpu())
-		free_thread_xstate(tsk);
 }
 
 static void hard_disable_TSC(void)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 57409f6..3265429 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -623,20 +623,8 @@ void math_state_restore(void)
 {
 	struct task_struct *tsk = current;
 
-	if (!tsk_used_math(tsk)) {
-		local_irq_enable();
-		/*
-		 * does a slab alloc which can sleep
-		 */
-		if (init_fpu(tsk)) {
-			/*
-			 * ran out of memory!
-			 */
-			do_group_exit(SIGKILL);
-			return;
-		}
-		local_irq_disable();
-	}
+	if (!tsk_used_math(tsk))
+		init_fpu(tsk);
 
 	__thread_fpu_begin(tsk);
 
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
index a4b451c..46f6266 100644
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -598,8 +598,6 @@ void xsave_init(void)
 
 static inline void __init eager_fpu_init_bp(void)
 {
-	current->thread.fpu.state =
-	    alloc_bootmem_align(xstate_size, __alignof__(struct xsave_struct));
 	if (!init_xstate_buf)
 		setup_init_fpu_buf();
 }



  parent reply	other threads:[~2014-02-02  7:20 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-30 22:01 [PATCH] Make math_state_restore() save and restore the interrupt flag Nate Eldredge
2014-01-30 22:24 ` Linus Torvalds
2014-01-31  7:33   ` Suresh Siddha
2014-02-01 19:27     ` Linus Torvalds
2014-02-01 19:35       ` H. Peter Anvin
2014-02-01 19:46         ` Linus Torvalds
2014-02-01 20:00           ` H. Peter Anvin
2014-02-01 20:16             ` Linus Torvalds
2014-02-01 20:16           ` H. Peter Anvin
2014-02-01 21:17           ` George Spelvin
2014-02-01 21:36             ` H. Peter Anvin
2014-02-01 23:40             ` H. Peter Anvin
2014-02-02  0:17               ` Linus Torvalds
2014-02-02  1:19               ` George Spelvin
2014-02-02  1:25                 ` H. Peter Anvin
2014-02-02  8:45           ` Pekka Riikonen
2014-02-02  1:06       ` Suresh Siddha
2014-02-02  1:26         ` H. Peter Anvin
2014-02-02  1:35           ` Suresh Siddha
2014-02-02  1:38             ` Linus Torvalds
2014-02-02  1:47               ` Suresh Siddha
2014-02-02  1:51                 ` Linus Torvalds
2014-02-02  1:57                   ` H. Peter Anvin
2014-02-02  2:05                     ` Linus Torvalds
2014-02-02  2:12                       ` H. Peter Anvin
2014-02-02  1:59                   ` Suresh Siddha
2014-02-02  1:43             ` H. Peter Anvin
2014-02-02  1:47               ` Linus Torvalds
2014-02-02  7:19         ` Suresh Siddha [this message]
2014-02-02 19:15           ` Linus Torvalds
2014-02-03  6:56             ` Suresh Siddha
2014-02-03 18:20               ` Linus Torvalds
2014-02-04  6:03                 ` Suresh Siddha
2014-02-06  5:26               ` Nate Eldredge
2014-02-06  5:34                 ` George Spelvin
2014-02-13 15:45               ` Maarten Baert
2014-02-13 20:00                 ` George Spelvin
2014-03-11 19:36               ` [tip:x86/urgent] x86, fpu: Check tsk_used_math() in kernel_fpu_end() for eager FPU tip-bot for Suresh Siddha
2014-02-27 23:44           ` [PATCH] Make math_state_restore() save and restore the interrupt flag H. Peter Anvin
2014-03-07 23:18             ` H. Peter Anvin
2014-03-08  6:18               ` 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=1391325599.6481.5.camel@europa \
    --to=sbsiddha@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jack@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@horizon.com \
    --cc=maarten-baert@hotmail.com \
    --cc=mingo@kernel.org \
    --cc=nate@thatsmathematics.com \
    --cc=priikone@iki.fi \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).