public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [rfc patch] i386: don't save eflags on task switch
@ 2006-11-04  6:56 Chuck Ebbert
  2006-11-04 19:09 ` Zachary Amsden
  0 siblings, 1 reply; 21+ messages in thread
From: Chuck Ebbert @ 2006-11-04  6:56 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Zachary Amsden, Andi Kleen, linux-kernel, Benjamin LaHaise

In-Reply-To: <Pine.LNX.4.64.0611031645141.25218@g5.osdl.org>

On Fri, 3 Nov 2006 16:46:25 -0800, Linus Torvalds wrote:

> On Fri, 3 Nov 2006, Chuck Ebbert wrote:
> >
> > There is no real need to save eflags in switch_to().  Instead,
> > we can keep a constant value in the thread_struct and always
> > restore that.
> 
> I don't really see the point. The "pushfl" isn't the expensive part, and 
> it gives sane and expected semantics.
> 
> The "popfl" is the expensive part, and that's the thing that can't really 
> even be removed.

Well that wasn't the impression I got:

  Date: Mon, 18 Sep 2006 12:12:51 -0400
  From: Benjamin LaHaise <bcrl@kvack.org>
  Subject: Re: Sysenter crash with Nested Task Bit set

  ...

  It's the pushfl that will be slow on any OoO CPU, as it has dependancies on 
  any previous instructions that modified the flags, which ends up bringing 
  all of the memory ordering dependancies into play.  Doing a popfl to set the 
  flags to some known value is much less expensive.


And benchmarks seem to support that, even on K8:

 lmbench context switch, 50 runs

        before  after
    avg  1.09   1.05
 stddev   .25    .18

But P4 is the real problem case and I can't test that.

-- 
Chuck
"Even supernovas have their duller moments."


^ permalink raw reply	[flat|nested] 21+ messages in thread
* [rfc patch] i386: don't save eflags on task switch
@ 2006-11-04  0:00 Chuck Ebbert
  2006-11-04  0:46 ` Linus Torvalds
  0 siblings, 1 reply; 21+ messages in thread
From: Chuck Ebbert @ 2006-11-04  0:00 UTC (permalink / raw)
  To: linux-kernel; +Cc: Andi Kleen, Linus Torvalds, Zachary Amsden

There is no real need to save eflags in switch_to().  Instead,
we can keep a constant value in the thread_struct and always
restore that.

This will cause a behavior change, though.  If a user sets
NT in eflags and then enters the kernel via sysenter, and
another task runs before the syscall returns:

        (1) If we return via the iret path then no fault
        will occur (currently the user gets a fault.)

        (2) If we return via sysexit, NT will be cleared
        (currently it remains set.)

Users shouldn't be setting NT anyway, so this shouldn't be a
problem.

On a K8 CPU, this patch didn't lower the minimum task-switch
time, but it did lower the average and removed most of the
variability.  It really needs testing on a P4, where it should
have much more effect.

Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
---

 arch/i386/kernel/ioport.c    |    7 ++++---
 include/asm-i386/processor.h |    5 +++--
 include/asm-i386/system.h    |    4 ++--
 3 files changed, 9 insertions(+), 7 deletions(-)

--- 2.6.19-rc4-32smp.orig/arch/i386/kernel/ioport.c	2006-08-27 11:30:50.000000000 -0400
+++ 2.6.19-rc4-32smp/arch/i386/kernel/ioport.c	2006-11-02 00:46:03.925570520 -0500
@@ -146,8 +146,9 @@ asmlinkage long sys_iopl(unsigned long u
 		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
 	}
-	t->iopl = level << 12;
-	regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
-	set_iopl_mask(t->iopl);
+	t->eflags = level << 12 | X86_EFLAGS_IF | 2;
+	regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) |
+		       (t->eflags & X86_EFLAGS_IOPL);
+	set_iopl_mask(t->eflags);
 	return 0;
 }
--- 2.6.19-rc4-32smp.orig/include/asm-i386/processor.h	2006-11-01 22:05:55.760728595 -0500
+++ 2.6.19-rc4-32smp/include/asm-i386/processor.h	2006-11-02 00:50:06.899235722 -0500
@@ -449,6 +449,7 @@ struct thread_struct {
 	unsigned long	sysenter_cs;
 	unsigned long	eip;
 	unsigned long	esp;
+ 	unsigned long	eflags;
 	unsigned long	fs;
 	unsigned long	gs;
 /* Hardware debugging registers */
@@ -464,7 +465,6 @@ struct thread_struct {
 	unsigned int		saved_fs, saved_gs;
 /* IO permissions */
 	unsigned long	*io_bitmap_ptr;
- 	unsigned long	iopl;
 /* max allowed port in the bitmap, in bytes: */
 	unsigned long	io_bitmap_max;
 };
@@ -534,7 +534,8 @@ static inline void set_iopl_mask(unsigne
 			      "pushl %0;"
 			      "popfl"
 				: "=&r" (reg)
-				: "i" (~X86_EFLAGS_IOPL), "r" (mask));
+				: "i" (~X86_EFLAGS_IOPL),
+				  "r" (mask & X86_EFLAGS_IOPL));
 }
 
 /* Forward declaration, a strange C thing */
--- 2.6.19-rc4-32smp.orig/include/asm-i386/system.h	2006-11-01 22:05:55.870730255 -0500
+++ 2.6.19-rc4-32smp/include/asm-i386/system.h	2006-11-02 00:54:54.863579599 -0500
@@ -17,7 +17,7 @@ extern struct task_struct * FASTCALL(__s
  */
 #define switch_to(prev,next,last) do {					\
 	unsigned long esi,edi;						\
-	asm volatile("pushfl\n\t"		/* Save flags */	\
+	asm volatile("pushl %9\n\t"		/* Save flags */	\
 		     "pushl %%ebp\n\t"					\
 		     "movl %%esp,%0\n\t"	/* save ESP */		\
 		     "movl %5,%%esp\n\t"	/* restore ESP */	\
@@ -30,7 +30,7 @@ extern struct task_struct * FASTCALL(__s
 		     :"=m" (prev->thread.esp),"=m" (prev->thread.eip),	\
 		      "=a" (last),"=S" (esi),"=D" (edi)			\
 		     :"m" (next->thread.esp),"m" (next->thread.eip),	\
-		      "2" (prev), "d" (next));				\
+		      "2" (prev), "d" (next), "m" (prev->thread.eflags));				\
 } while (0)
 
 #define _set_base(addr,base) do { unsigned long __pr; \
-- 
Chuck

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2006-11-05 22:48 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-04  6:56 [rfc patch] i386: don't save eflags on task switch Chuck Ebbert
2006-11-04 19:09 ` Zachary Amsden
2006-11-04 19:35   ` Linus Torvalds
2006-11-05  3:55   ` Benjamin LaHaise
2006-11-05  4:13     ` Linus Torvalds
2006-11-05  5:41       ` Andi Kleen
2006-11-05  8:01         ` Zachary Amsden
2006-11-05 17:01           ` Andi Kleen
2006-11-05 17:26             ` Linus Torvalds
2006-11-05 17:34               ` Arjan van de Ven
2006-11-05 17:51                 ` Linus Torvalds
2006-11-05 22:48                   ` Zachary Amsden
2006-11-05 18:52               ` Andi Kleen
2006-11-05 16:12         ` Linus Torvalds
2006-11-05 16:54           ` Andi Kleen
2006-11-05 17:20             ` Linus Torvalds
2006-11-05  4:17     ` Zachary Amsden
2006-11-05 20:10       ` H. Peter Anvin
  -- strict thread matches above, loose matches on Subject: below --
2006-11-04  0:00 Chuck Ebbert
2006-11-04  0:46 ` Linus Torvalds
2006-11-04  1:36   ` Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox