public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Benjamin LaHaise <bcrl@kvack.org>
Cc: Davide Libenzi <davidel@xmailserver.org>,
	Russell King <rmk+lkml@arm.linux.org.uk>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Arjan van de Ven <arjan@infradead.org>,
	Christoph Hellwig <hch@infradead.org>,
	Andrew Morton <akpm@zip.com.au>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>,
	Ulrich Drepper <drepper@redhat.com>,
	Zach Brown <zach.brown@oracle.com>,
	Evgeniy Polyakov <johnpol@2ka.mipt.ru>,
	"David S. Miller" <davem@davemloft.net>,
	Suparna Bhattacharya <suparna@in.ibm.com>,
	Thomas Gleixner <tglx@linutronix.de>
Subject: [patch] x86: split FPU state from task state
Date: Wed, 14 Feb 2007 22:49:44 +0100	[thread overview]
Message-ID: <20070214214944.GA1082@elte.hu> (raw)
In-Reply-To: <20070214203438.GL32271@kvack.org>


* Benjamin LaHaise <bcrl@kvack.org> wrote:

> On Wed, Feb 14, 2007 at 12:14:29PM -0800, Davide Libenzi wrote:
> > I think you may have mis-interpreted my words. *When* a schedule 
> > would block a synco execution try, then you do have a context 
> > switch. Noone argue that, and the code is clear. The sys_async_exec 
> > thread will block, and a newly woke up thread will re-emerge to 
> > sys_async_exec with a NULL returned to userspace. But in a 
> > "cachehit" case (no schedule happens during the syscall/*let 
> > execution), there is no context switch at all. That is the whole 
> > point of the optimization.
> 
> And I will repeat myself: that cannot be done.  Tell me how the 
> following what if scenario works: you're in an MMX optimized memory 
> copy and you take a page fault.  How does returning to the submittor 
> of the async operation get the correct MMX state restored?  It 
> doesn't.

this can very much be done, with a straightforward extension of how we 
handle FPU state. That makes sense independently of syslets/async as 
well, so find below the standalone patch from Arjan. It's in my current 
syslet queue and works great.

	Ingo

------------------------>
Subject: [patch] x86: split FPU state from task state
From: Arjan van de Ven <arjan@linux.intel.com>

Split the FPU save area from the task struct. This allows easy migration 
of FPU context, and it's generally cleaner. It also allows the following 
two (future) optimizations:

1) allocate the right size for the actual cpu rather than 512 bytes always
2) only allocate when the application actually uses FPU, so in the first 
   lazy FPU trap. This could save memory for non-fpu using apps.

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 arch/i386/kernel/i387.c        |   96 ++++++++++++++++++++---------------------
 arch/i386/kernel/process.c     |   56 +++++++++++++++++++++++
 arch/i386/kernel/traps.c       |   10 ----
 include/asm-i386/i387.h        |    6 +-
 include/asm-i386/processor.h   |    6 ++
 include/asm-i386/thread_info.h |    6 ++
 kernel/fork.c                  |    7 ++
 7 files changed, 123 insertions(+), 64 deletions(-)

Index: linux/arch/i386/kernel/i387.c
===================================================================
--- linux.orig/arch/i386/kernel/i387.c
+++ linux/arch/i386/kernel/i387.c
@@ -31,9 +31,9 @@ void mxcsr_feature_mask_init(void)
 	unsigned long mask = 0;
 	clts();
 	if (cpu_has_fxsr) {
-		memset(&current->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
-		asm volatile("fxsave %0" : : "m" (current->thread.i387.fxsave)); 
-		mask = current->thread.i387.fxsave.mxcsr_mask;
+		memset(&current->thread.i387->fxsave, 0, sizeof(struct i387_fxsave_struct));
+		asm volatile("fxsave %0" : : "m" (current->thread.i387->fxsave));
+		mask = current->thread.i387->fxsave.mxcsr_mask;
 		if (mask == 0) mask = 0x0000ffbf;
 	} 
 	mxcsr_feature_mask &= mask;
@@ -49,16 +49,16 @@ void mxcsr_feature_mask_init(void)
 void init_fpu(struct task_struct *tsk)
 {
 	if (cpu_has_fxsr) {
-		memset(&tsk->thread.i387.fxsave, 0, sizeof(struct i387_fxsave_struct));
-		tsk->thread.i387.fxsave.cwd = 0x37f;
+		memset(&tsk->thread.i387->fxsave, 0, sizeof(struct i387_fxsave_struct));
+		tsk->thread.i387->fxsave.cwd = 0x37f;
 		if (cpu_has_xmm)
-			tsk->thread.i387.fxsave.mxcsr = 0x1f80;
+			tsk->thread.i387->fxsave.mxcsr = 0x1f80;
 	} else {
-		memset(&tsk->thread.i387.fsave, 0, sizeof(struct i387_fsave_struct));
-		tsk->thread.i387.fsave.cwd = 0xffff037fu;
-		tsk->thread.i387.fsave.swd = 0xffff0000u;
-		tsk->thread.i387.fsave.twd = 0xffffffffu;
-		tsk->thread.i387.fsave.fos = 0xffff0000u;
+		memset(&tsk->thread.i387->fsave, 0, sizeof(struct i387_fsave_struct));
+		tsk->thread.i387->fsave.cwd = 0xffff037fu;
+		tsk->thread.i387->fsave.swd = 0xffff0000u;
+		tsk->thread.i387->fsave.twd = 0xffffffffu;
+		tsk->thread.i387->fsave.fos = 0xffff0000u;
 	}
 	/* only the device not available exception or ptrace can call init_fpu */
 	set_stopped_child_used_math(tsk);
@@ -152,18 +152,18 @@ static inline unsigned long twd_fxsr_to_
 unsigned short get_fpu_cwd( struct task_struct *tsk )
 {
 	if ( cpu_has_fxsr ) {
-		return tsk->thread.i387.fxsave.cwd;
+		return tsk->thread.i387->fxsave.cwd;
 	} else {
-		return (unsigned short)tsk->thread.i387.fsave.cwd;
+		return (unsigned short)tsk->thread.i387->fsave.cwd;
 	}
 }
 
 unsigned short get_fpu_swd( struct task_struct *tsk )
 {
 	if ( cpu_has_fxsr ) {
-		return tsk->thread.i387.fxsave.swd;
+		return tsk->thread.i387->fxsave.swd;
 	} else {
-		return (unsigned short)tsk->thread.i387.fsave.swd;
+		return (unsigned short)tsk->thread.i387->fsave.swd;
 	}
 }
 
@@ -171,9 +171,9 @@ unsigned short get_fpu_swd( struct task_
 unsigned short get_fpu_twd( struct task_struct *tsk )
 {
 	if ( cpu_has_fxsr ) {
-		return tsk->thread.i387.fxsave.twd;
+		return tsk->thread.i387->fxsave.twd;
 	} else {
-		return (unsigned short)tsk->thread.i387.fsave.twd;
+		return (unsigned short)tsk->thread.i387->fsave.twd;
 	}
 }
 #endif  /*  0  */
@@ -181,7 +181,7 @@ unsigned short get_fpu_twd( struct task_
 unsigned short get_fpu_mxcsr( struct task_struct *tsk )
 {
 	if ( cpu_has_xmm ) {
-		return tsk->thread.i387.fxsave.mxcsr;
+		return tsk->thread.i387->fxsave.mxcsr;
 	} else {
 		return 0x1f80;
 	}
@@ -192,27 +192,27 @@ unsigned short get_fpu_mxcsr( struct tas
 void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd )
 {
 	if ( cpu_has_fxsr ) {
-		tsk->thread.i387.fxsave.cwd = cwd;
+		tsk->thread.i387->fxsave.cwd = cwd;
 	} else {
-		tsk->thread.i387.fsave.cwd = ((long)cwd | 0xffff0000u);
+		tsk->thread.i387->fsave.cwd = ((long)cwd | 0xffff0000u);
 	}
 }
 
 void set_fpu_swd( struct task_struct *tsk, unsigned short swd )
 {
 	if ( cpu_has_fxsr ) {
-		tsk->thread.i387.fxsave.swd = swd;
+		tsk->thread.i387->fxsave.swd = swd;
 	} else {
-		tsk->thread.i387.fsave.swd = ((long)swd | 0xffff0000u);
+		tsk->thread.i387->fsave.swd = ((long)swd | 0xffff0000u);
 	}
 }
 
 void set_fpu_twd( struct task_struct *tsk, unsigned short twd )
 {
 	if ( cpu_has_fxsr ) {
-		tsk->thread.i387.fxsave.twd = twd_i387_to_fxsr(twd);
+		tsk->thread.i387->fxsave.twd = twd_i387_to_fxsr(twd);
 	} else {
-		tsk->thread.i387.fsave.twd = ((long)twd | 0xffff0000u);
+		tsk->thread.i387->fsave.twd = ((long)twd | 0xffff0000u);
 	}
 }
 
@@ -298,8 +298,8 @@ static inline int save_i387_fsave( struc
 	struct task_struct *tsk = current;
 
 	unlazy_fpu( tsk );
-	tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd;
-	if ( __copy_to_user( buf, &tsk->thread.i387.fsave,
+	tsk->thread.i387->fsave.status = tsk->thread.i387->fsave.swd;
+	if ( __copy_to_user( buf, &tsk->thread.i387->fsave,
 			     sizeof(struct i387_fsave_struct) ) )
 		return -1;
 	return 1;
@@ -312,15 +312,15 @@ static int save_i387_fxsave( struct _fps
 
 	unlazy_fpu( tsk );
 
-	if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) )
+	if ( convert_fxsr_to_user( buf, &tsk->thread.i387->fxsave ) )
 		return -1;
 
-	err |= __put_user( tsk->thread.i387.fxsave.swd, &buf->status );
+	err |= __put_user( tsk->thread.i387->fxsave.swd, &buf->status );
 	err |= __put_user( X86_FXSR_MAGIC, &buf->magic );
 	if ( err )
 		return -1;
 
-	if ( __copy_to_user( &buf->_fxsr_env[0], &tsk->thread.i387.fxsave,
+	if ( __copy_to_user( &buf->_fxsr_env[0], &tsk->thread.i387->fxsave,
 			     sizeof(struct i387_fxsave_struct) ) )
 		return -1;
 	return 1;
@@ -343,7 +343,7 @@ int save_i387( struct _fpstate __user *b
 			return save_i387_fsave( buf );
 		}
 	} else {
-		return save_i387_soft( &current->thread.i387.soft, buf );
+		return save_i387_soft( &current->thread.i387->soft, buf );
 	}
 }
 
@@ -351,7 +351,7 @@ static inline int restore_i387_fsave( st
 {
 	struct task_struct *tsk = current;
 	clear_fpu( tsk );
-	return __copy_from_user( &tsk->thread.i387.fsave, buf,
+	return __copy_from_user( &tsk->thread.i387->fsave, buf,
 				 sizeof(struct i387_fsave_struct) );
 }
 
@@ -360,11 +360,11 @@ static int restore_i387_fxsave( struct _
 	int err;
 	struct task_struct *tsk = current;
 	clear_fpu( tsk );
-	err = __copy_from_user( &tsk->thread.i387.fxsave, &buf->_fxsr_env[0],
+	err = __copy_from_user( &tsk->thread.i387->fxsave, &buf->_fxsr_env[0],
 				sizeof(struct i387_fxsave_struct) );
 	/* mxcsr reserved bits must be masked to zero for security reasons */
-	tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
-	return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387.fxsave, buf );
+	tsk->thread.i387->fxsave.mxcsr &= mxcsr_feature_mask;
+	return err ? 1 : convert_fxsr_from_user( &tsk->thread.i387->fxsave, buf );
 }
 
 int restore_i387( struct _fpstate __user *buf )
@@ -378,7 +378,7 @@ int restore_i387( struct _fpstate __user
 			err = restore_i387_fsave( buf );
 		}
 	} else {
-		err = restore_i387_soft( &current->thread.i387.soft, buf );
+		err = restore_i387_soft( &current->thread.i387->soft, buf );
 	}
 	set_used_math();
 	return err;
@@ -391,7 +391,7 @@ int restore_i387( struct _fpstate __user
 static inline int get_fpregs_fsave( struct user_i387_struct __user *buf,
 				    struct task_struct *tsk )
 {
-	return __copy_to_user( buf, &tsk->thread.i387.fsave,
+	return __copy_to_user( buf, &tsk->thread.i387->fsave,
 			       sizeof(struct user_i387_struct) );
 }
 
@@ -399,7 +399,7 @@ static inline int get_fpregs_fxsave( str
 				     struct task_struct *tsk )
 {
 	return convert_fxsr_to_user( (struct _fpstate __user *)buf,
-				     &tsk->thread.i387.fxsave );
+				     &tsk->thread.i387->fxsave );
 }
 
 int get_fpregs( struct user_i387_struct __user *buf, struct task_struct *tsk )
@@ -411,7 +411,7 @@ int get_fpregs( struct user_i387_struct 
 			return get_fpregs_fsave( buf, tsk );
 		}
 	} else {
-		return save_i387_soft( &tsk->thread.i387.soft,
+		return save_i387_soft( &tsk->thread.i387->soft,
 				       (struct _fpstate __user *)buf );
 	}
 }
@@ -419,14 +419,14 @@ int get_fpregs( struct user_i387_struct 
 static inline int set_fpregs_fsave( struct task_struct *tsk,
 				    struct user_i387_struct __user *buf )
 {
-	return __copy_from_user( &tsk->thread.i387.fsave, buf,
+	return __copy_from_user( &tsk->thread.i387->fsave, buf,
 				 sizeof(struct user_i387_struct) );
 }
 
 static inline int set_fpregs_fxsave( struct task_struct *tsk,
 				     struct user_i387_struct __user *buf )
 {
-	return convert_fxsr_from_user( &tsk->thread.i387.fxsave,
+	return convert_fxsr_from_user( &tsk->thread.i387->fxsave,
 				       (struct _fpstate __user *)buf );
 }
 
@@ -439,7 +439,7 @@ int set_fpregs( struct task_struct *tsk,
 			return set_fpregs_fsave( tsk, buf );
 		}
 	} else {
-		return restore_i387_soft( &tsk->thread.i387.soft,
+		return restore_i387_soft( &tsk->thread.i387->soft,
 					  (struct _fpstate __user *)buf );
 	}
 }
@@ -447,7 +447,7 @@ int set_fpregs( struct task_struct *tsk,
 int get_fpxregs( struct user_fxsr_struct __user *buf, struct task_struct *tsk )
 {
 	if ( cpu_has_fxsr ) {
-		if (__copy_to_user( buf, &tsk->thread.i387.fxsave,
+		if (__copy_to_user( buf, &tsk->thread.i387->fxsave,
 				    sizeof(struct user_fxsr_struct) ))
 			return -EFAULT;
 		return 0;
@@ -461,11 +461,11 @@ int set_fpxregs( struct task_struct *tsk
 	int ret = 0;
 
 	if ( cpu_has_fxsr ) {
-		if (__copy_from_user( &tsk->thread.i387.fxsave, buf,
+		if (__copy_from_user( &tsk->thread.i387->fxsave, buf,
 				  sizeof(struct user_fxsr_struct) ))
 			ret = -EFAULT;
 		/* mxcsr reserved bits must be masked to zero for security reasons */
-		tsk->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
+		tsk->thread.i387->fxsave.mxcsr &= mxcsr_feature_mask;
 	} else {
 		ret = -EIO;
 	}
@@ -479,7 +479,7 @@ int set_fpxregs( struct task_struct *tsk
 static inline void copy_fpu_fsave( struct task_struct *tsk,
 				   struct user_i387_struct *fpu )
 {
-	memcpy( fpu, &tsk->thread.i387.fsave,
+	memcpy( fpu, &tsk->thread.i387->fsave,
 		sizeof(struct user_i387_struct) );
 }
 
@@ -490,10 +490,10 @@ static inline void copy_fpu_fxsave( stru
 	unsigned short *from;
 	int i;
 
-	memcpy( fpu, &tsk->thread.i387.fxsave, 7 * sizeof(long) );
+	memcpy( fpu, &tsk->thread.i387->fxsave, 7 * sizeof(long) );
 
 	to = (unsigned short *)&fpu->st_space[0];
-	from = (unsigned short *)&tsk->thread.i387.fxsave.st_space[0];
+	from = (unsigned short *)&tsk->thread.i387->fxsave.st_space[0];
 	for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
 		memcpy( to, from, 5 * sizeof(unsigned short) );
 	}
@@ -540,7 +540,7 @@ int dump_task_extended_fpu(struct task_s
 	if (fpvalid) {
 		if (tsk == current)
 		       unlazy_fpu(tsk);
-		memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(*fpu));
+		memcpy(fpu, &tsk->thread.i387->fxsave, sizeof(*fpu));
 	}
 	return fpvalid;
 }
Index: linux/arch/i386/kernel/process.c
===================================================================
--- linux.orig/arch/i386/kernel/process.c
+++ linux/arch/i386/kernel/process.c
@@ -645,7 +645,7 @@ struct task_struct fastcall * __switch_t
 
 	/* we're going to use this soon, after a few expensive things */
 	if (next_p->fpu_counter > 5)
-		prefetch(&next->i387.fxsave);
+		prefetch(&next->i387->fxsave);
 
 	/*
 	 * Reload esp0.
@@ -908,3 +908,57 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+
+
+struct kmem_cache *task_struct_cachep;
+struct kmem_cache *task_i387_cachep;
+
+struct task_struct * alloc_task_struct(void)
+{
+	struct task_struct *tsk;
+	tsk = kmem_cache_alloc(task_struct_cachep, GFP_KERNEL);
+	if (!tsk)
+		return NULL;
+	tsk->thread.i387 = kmem_cache_alloc(task_i387_cachep, GFP_KERNEL);
+	if (!tsk->thread.i387)
+		goto error;
+	WARN_ON((unsigned long)tsk->thread.i387 & 15);
+	return tsk;
+
+error:
+	kfree(tsk);
+	return NULL;
+}
+
+void memcpy_task_struct(struct task_struct *dst, struct task_struct *src)
+{
+	union i387_union *ptr;
+	ptr = dst->thread.i387;
+	*dst = *src;
+	dst->thread.i387 = ptr;
+	memcpy(dst->thread.i387, src->thread.i387, sizeof(union i387_union));
+}
+
+void free_task_struct(struct task_struct *tsk)
+{
+	kmem_cache_free(task_i387_cachep, tsk->thread.i387);
+	tsk->thread.i387=NULL;
+	kmem_cache_free(task_struct_cachep, tsk);
+}
+
+
+void task_struct_slab_init(void)
+{
+ 	/* create a slab on which task_structs can be allocated */
+        task_struct_cachep =
+        	kmem_cache_create("task_struct", sizeof(struct task_struct),
+        		ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL, NULL);
+        task_i387_cachep =
+        	kmem_cache_create("task_i387", sizeof(union i387_union), 32,
+        	    SLAB_PANIC | SLAB_MUST_HWCACHE_ALIGN, NULL, NULL);
+}
+
+
+/* the very init task needs a static allocated i387 area */
+union i387_union init_i387_context;
Index: linux/arch/i386/kernel/traps.c
===================================================================
--- linux.orig/arch/i386/kernel/traps.c
+++ linux/arch/i386/kernel/traps.c
@@ -1154,16 +1154,6 @@ void __init trap_init(void)
 	set_trap_gate(19,&simd_coprocessor_error);
 
 	if (cpu_has_fxsr) {
-		/*
-		 * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
-		 * Generates a compile-time "error: zero width for bit-field" if
-		 * the alignment is wrong.
-		 */
-		struct fxsrAlignAssert {
-			int _:!(offsetof(struct task_struct,
-					thread.i387.fxsave) & 15);
-		};
-
 		printk(KERN_INFO "Enabling fast FPU save and restore... ");
 		set_in_cr4(X86_CR4_OSFXSR);
 		printk("done.\n");
Index: linux/include/asm-i386/i387.h
===================================================================
--- linux.orig/include/asm-i386/i387.h
+++ linux/include/asm-i386/i387.h
@@ -34,7 +34,7 @@ extern void init_fpu(struct task_struct 
 		"nop ; frstor %1",		\
 		"fxrstor %1",			\
 		X86_FEATURE_FXSR,		\
-		"m" ((tsk)->thread.i387.fxsave))
+		"m" ((tsk)->thread.i387->fxsave))
 
 extern void kernel_fpu_begin(void);
 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
@@ -60,8 +60,8 @@ static inline void __save_init_fpu( stru
 		"fxsave %[fx]\n"
 		"bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
 		X86_FEATURE_FXSR,
-		[fx] "m" (tsk->thread.i387.fxsave),
-		[fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
+		[fx] "m" (tsk->thread.i387->fxsave),
+		[fsw] "m" (tsk->thread.i387->fxsave.swd) : "memory");
 	/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
 	   is pending.  Clear the x87 state here by setting it to fixed
    	   values. safe_address is a random variable that should be in L1 */
Index: linux/include/asm-i386/processor.h
===================================================================
--- linux.orig/include/asm-i386/processor.h
+++ linux/include/asm-i386/processor.h
@@ -407,7 +407,7 @@ struct thread_struct {
 /* fault info */
 	unsigned long	cr2, trap_no, error_code;
 /* floating point info */
-	union i387_union	i387;
+	union i387_union	*i387;
 /* virtual 86 mode info */
 	struct vm86_struct __user * vm86_info;
 	unsigned long		screen_bitmap;
@@ -420,11 +420,15 @@ struct thread_struct {
 	unsigned long	io_bitmap_max;
 };
 
+
+extern union i387_union init_i387_context;
+
 #define INIT_THREAD  {							\
 	.vm86_info = NULL,						\
 	.sysenter_cs = __KERNEL_CS,					\
 	.io_bitmap_ptr = NULL,						\
 	.gs = __KERNEL_PDA,						\
+	.i387 = &init_i387_context,					\
 }
 
 /*
Index: linux/include/asm-i386/thread_info.h
===================================================================
--- linux.orig/include/asm-i386/thread_info.h
+++ linux/include/asm-i386/thread_info.h
@@ -102,6 +102,12 @@ static inline struct thread_info *curren
 
 #define free_thread_info(info)	kfree(info)
 
+#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
+extern struct task_struct * alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *tsk);
+extern void memcpy_task_struct(struct task_struct *dst, struct task_struct *src);
+extern void task_struct_slab_init(void);
+
 #else /* !__ASSEMBLY__ */
 
 /* how to get the thread information struct from ASM */
Index: linux/kernel/fork.c
===================================================================
--- linux.orig/kernel/fork.c
+++ linux/kernel/fork.c
@@ -83,6 +83,8 @@ int nr_processes(void)
 #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
 # define alloc_task_struct()	kmem_cache_alloc(task_struct_cachep, GFP_KERNEL)
 # define free_task_struct(tsk)	kmem_cache_free(task_struct_cachep, (tsk))
+# define memcpy_task_struct(dst, src) *dst = *src;
+
 static struct kmem_cache *task_struct_cachep;
 #endif
 
@@ -137,6 +139,8 @@ void __init fork_init(unsigned long memp
 	task_struct_cachep =
 		kmem_cache_create("task_struct", sizeof(struct task_struct),
 			ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL, NULL);
+#else
+	task_struct_slab_init();
 #endif
 
 	/*
@@ -175,7 +179,8 @@ static struct task_struct *dup_task_stru
 		return NULL;
 	}
 
-	*tsk = *orig;
+	memcpy_task_struct(tsk, orig);
+
 	tsk->thread_info = ti;
 	setup_thread_stack(tsk, orig);
 

  parent reply	other threads:[~2007-02-14 21:52 UTC|newest]

Thread overview: 319+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-29 21:21 [patch 00/61] ANNOUNCE: lock validator -V1 Ingo Molnar
2006-05-29 21:22 ` [patch 01/61] lock validator: floppy.c irq-release fix Ingo Molnar
2006-05-30  1:32   ` Andrew Morton
2006-05-29 21:23 ` [patch 02/61] lock validator: forcedeth.c fix Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-31  5:40     ` Manfred Spraul
2006-05-29 21:23 ` [patch 03/61] lock validator: sound/oss/emu10k1/midi.c cleanup Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-30 10:51     ` Takashi Iwai
2006-05-30 11:03       ` Alexey Dobriyan
2006-05-29 21:23 ` [patch 04/61] lock validator: mutex section binutils workaround Ingo Molnar
2006-05-29 21:23 ` [patch 05/61] lock validator: introduce WARN_ON_ONCE(cond) Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-30 17:38     ` Steven Rostedt
2006-06-03 18:09       ` Steven Rostedt
2006-06-04  9:18         ` Arjan van de Ven
2006-06-04 13:43           ` Steven Rostedt
2006-05-29 21:23 ` [patch 06/61] lock validator: add __module_address() method Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-30 17:45     ` Steven Rostedt
2006-06-23  8:38     ` Ingo Molnar
2006-05-29 21:23 ` [patch 07/61] lock validator: better lock debugging Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-06-23 10:25     ` Ingo Molnar
2006-06-23 11:06       ` Andrew Morton
2006-06-23 11:04         ` Ingo Molnar
2006-05-29 21:23 ` [patch 08/61] lock validator: locking API self-tests Ingo Molnar
2006-05-29 21:23 ` [patch 09/61] lock validator: spin/rwlock init cleanups Ingo Molnar
2006-05-29 21:23 ` [patch 10/61] lock validator: locking init debugging improvement Ingo Molnar
2006-05-29 21:23 ` [patch 11/61] lock validator: lockdep: small xfs init_rwsem() cleanup Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-30  1:32     ` Nathan Scott
2006-05-29 21:24 ` [patch 12/61] lock validator: beautify x86_64 stacktraces Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-29 21:24 ` [patch 13/61] lock validator: x86_64: document stack frame internals Ingo Molnar
2006-05-29 21:24 ` [patch 14/61] lock validator: stacktrace Ingo Molnar
2006-05-29 21:24 ` [patch 15/61] lock validator: x86_64: use stacktrace to generate backtraces Ingo Molnar
2006-05-30  1:33   ` Andrew Morton
2006-05-29 21:24 ` [patch 16/61] lock validator: fown locking workaround Ingo Molnar
2006-05-30  1:34   ` Andrew Morton
2006-06-23  9:10     ` Ingo Molnar
2006-05-29 21:24 ` [patch 17/61] lock validator: sk_callback_lock workaround Ingo Molnar
2006-05-30  1:34   ` Andrew Morton
2006-06-23  9:19     ` Ingo Molnar
2006-05-29 21:24 ` [patch 18/61] lock validator: irqtrace: core Ingo Molnar
2006-05-30  1:34   ` Andrew Morton
2006-06-23 10:42     ` Ingo Molnar
2006-05-29 21:24 ` [patch 19/61] lock validator: irqtrace: cleanup: include/asm-i386/irqflags.h Ingo Molnar
2006-05-29 21:24 ` [patch 20/61] lock validator: irqtrace: cleanup: include/asm-x86_64/irqflags.h Ingo Molnar
2006-05-29 21:24 ` [patch 21/61] lock validator: lockdep: add local_irq_enable_in_hardirq() API Ingo Molnar
2006-05-30  1:34   ` Andrew Morton
2006-06-23  9:28     ` Ingo Molnar
2006-06-23  9:52       ` Andrew Morton
2006-06-23 10:20         ` Ingo Molnar
2006-05-29 21:24 ` [patch 22/61] lock validator: add per_cpu_offset() Ingo Molnar
2006-05-30  1:34   ` Andrew Morton
2006-06-23  9:30     ` Ingo Molnar
2006-05-29 21:25 ` [patch 23/61] lock validator: core Ingo Molnar
2006-05-29 21:25 ` [patch 24/61] lock validator: procfs Ingo Molnar
2006-05-29 21:25 ` [patch 25/61] lock validator: design docs Ingo Molnar
2006-05-30  9:07   ` Nikita Danilov
2006-05-29 21:25 ` [patch 26/61] lock validator: prove rwsem locking correctness Ingo Molnar
2006-05-29 21:25 ` [patch 27/61] lock validator: prove spinlock/rwlock " Ingo Molnar
2006-05-30  1:35   ` Andrew Morton
2006-06-23 10:44     ` Ingo Molnar
2006-05-29 21:25 ` [patch 28/61] lock validator: prove mutex " Ingo Molnar
2006-05-29 21:25 ` [patch 29/61] lock validator: print all lock-types on SysRq-D Ingo Molnar
2006-05-29 21:25 ` [patch 30/61] lock validator: x86_64 early init Ingo Molnar
2006-05-29 21:25 ` [patch 31/61] lock validator: SMP alternatives workaround Ingo Molnar
2006-05-29 21:25 ` [patch 32/61] lock validator: do not recurse in printk() Ingo Molnar
2006-05-29 21:25 ` [patch 33/61] lock validator: disable NMI watchdog if CONFIG_LOCKDEP Ingo Molnar
2006-05-29 22:49   ` Keith Owens
2006-05-29 21:25 ` [patch 34/61] lock validator: special locking: bdev Ingo Molnar
2006-05-30  1:35   ` Andrew Morton
2006-05-30  5:13     ` Arjan van de Ven
2006-05-30  9:58     ` Al Viro
2006-05-30 10:45     ` Arjan van de Ven
2006-05-29 21:25 ` [patch 35/61] lock validator: special locking: direct-IO Ingo Molnar
2006-05-29 21:26 ` [patch 36/61] lock validator: special locking: serial Ingo Molnar
2006-05-30  1:35   ` Andrew Morton
2006-06-23  9:49     ` Ingo Molnar
2006-06-23 10:04       ` Andrew Morton
2006-06-23 10:18         ` Ingo Molnar
2006-05-29 21:26 ` [patch 37/61] lock validator: special locking: dcache Ingo Molnar
2006-05-30  1:35   ` Andrew Morton
2006-05-30 20:51     ` Steven Rostedt
2006-05-30 21:01       ` Ingo Molnar
2006-06-23  9:51       ` Ingo Molnar
2006-05-29 21:26 ` [patch 38/61] lock validator: special locking: i_mutex Ingo Molnar
2006-05-30 20:53   ` Steven Rostedt
2006-05-30 21:06     ` Ingo Molnar
2006-05-29 21:26 ` [patch 39/61] lock validator: special locking: s_lock Ingo Molnar
2006-05-29 21:26 ` [patch 40/61] lock validator: special locking: futex Ingo Molnar
2006-05-29 21:26 ` [patch 41/61] lock validator: special locking: genirq Ingo Molnar
2006-05-29 21:26 ` [patch 42/61] lock validator: special locking: kgdb Ingo Molnar
2006-05-29 21:26 ` [patch 43/61] lock validator: special locking: completions Ingo Molnar
2006-05-29 21:26 ` [patch 44/61] lock validator: special locking: waitqueues Ingo Molnar
2006-05-29 21:26 ` [patch 45/61] lock validator: special locking: mm Ingo Molnar
2006-05-29 21:26 ` [patch 46/61] lock validator: special locking: slab Ingo Molnar
2006-05-30  1:35   ` Andrew Morton
2006-06-23  9:54     ` Ingo Molnar
2006-05-29 21:26 ` [patch 47/61] lock validator: special locking: skb_queue_head_init() Ingo Molnar
2006-05-29 21:26 ` [patch 48/61] lock validator: special locking: timer.c Ingo Molnar
2006-05-29 21:27 ` [patch 49/61] lock validator: special locking: sched.c Ingo Molnar
2006-05-29 21:27 ` [patch 50/61] lock validator: special locking: hrtimer.c Ingo Molnar
2006-05-30  1:35   ` Andrew Morton
2006-06-23 10:04     ` Ingo Molnar
2006-06-23 10:38       ` Andrew Morton
2006-06-23 10:52         ` Ingo Molnar
2006-06-23 11:52           ` Ingo Molnar
2006-06-23 12:06             ` Andrew Morton
2006-05-29 21:27 ` [patch 51/61] lock validator: special locking: sock_lock_init() Ingo Molnar
2006-05-30  1:36   ` Andrew Morton
2006-06-23 10:06     ` Ingo Molnar
2006-05-29 21:27 ` [patch 52/61] lock validator: special locking: af_unix Ingo Molnar
2006-05-30  1:36   ` Andrew Morton
2006-06-23 10:07     ` Ingo Molnar
2006-05-29 21:27 ` [patch 53/61] lock validator: special locking: bh_lock_sock() Ingo Molnar
2006-05-29 21:27 ` [patch 54/61] lock validator: special locking: mmap_sem Ingo Molnar
2006-05-29 21:27 ` [patch 55/61] lock validator: special locking: sb->s_umount Ingo Molnar
2006-05-30  1:36   ` Andrew Morton
2006-06-23 10:55     ` Ingo Molnar
2006-05-29 21:27 ` [patch 56/61] lock validator: special locking: jbd Ingo Molnar
2006-05-29 21:27 ` [patch 57/61] lock validator: special locking: posix-timers Ingo Molnar
2006-05-29 21:27 ` [patch 58/61] lock validator: special locking: sch_generic.c Ingo Molnar
2006-05-29 21:27 ` [patch 59/61] lock validator: special locking: xfrm Ingo Molnar
2006-05-30  1:36   ` Andrew Morton
2006-05-29 21:27 ` [patch 60/61] lock validator: special locking: sound/core/seq/seq_ports.c Ingo Molnar
2006-05-29 21:28 ` [patch 61/61] lock validator: enable lock validator in Kconfig Ingo Molnar
2006-05-30  1:36   ` Andrew Morton
2006-05-30 13:33   ` Roman Zippel
2006-06-23 11:01     ` Ingo Molnar
2006-06-26 11:37       ` Roman Zippel
2006-05-29 22:28 ` [patch 00/61] ANNOUNCE: lock validator -V1 Michal Piotrowski
2006-05-29 22:41   ` Ingo Molnar
2006-05-29 23:09     ` Dave Jones
2006-05-30  5:45       ` Arjan van de Ven
2006-05-30  6:07         ` Michal Piotrowski
2006-05-30 14:10         ` Dave Jones
2006-05-30 14:19           ` Arjan van de Ven
2006-05-30 14:58             ` Dave Jones
2006-05-30 17:11               ` Dominik Brodowski
2006-05-30 19:02                 ` Dave Jones
2006-05-30 19:25                   ` Roland Dreier
2006-05-30 19:34                     ` Dave Jones
2006-05-30 20:41                     ` Ingo Molnar
2006-05-30 20:44                       ` Ingo Molnar
2006-05-30 21:58                       ` Paolo Ciarrocchi
2006-05-31  8:40                         ` Ingo Molnar
2006-05-30 19:39                 ` Dave Jones
2006-05-30 19:53                   ` Ashok Raj
2006-06-01  5:50                     ` Nathan Lynch
2006-05-30 20:54         ` [patch, -rc5-mm1] lock validator: select KALLSYMS_ALL Ingo Molnar
2006-05-30  5:52       ` [patch 00/61] ANNOUNCE: lock validator -V1 Michal Piotrowski
2006-05-30  5:20   ` Arjan van de Ven
2006-05-30  1:35 ` Andrew Morton
2006-06-23  9:41   ` Ingo Molnar
2006-05-30  4:52 ` Mike Galbraith
2006-05-30  6:20   ` Arjan van de Ven
2006-05-30  6:35   ` Arjan van de Ven
2006-05-30  7:47     ` Ingo Molnar
2006-05-30  6:37   ` Ingo Molnar
2006-05-30  9:25     ` Mike Galbraith
2006-05-30 10:57       ` Ingo Molnar
2006-05-30  9:14 ` Benoit Boissinot
2006-05-30 10:26   ` Arjan van de Ven
2006-05-30 11:42     ` Benoit Boissinot
2006-05-30 12:13       ` Ingo Molnar
2006-06-01 14:42   ` [patch mm1-rc2] lock validator: netlink.c netlink_table_grab fix Frederik Deweerdt
2006-06-02  3:10     ` Zhu Yi
2006-06-02  9:53       ` Frederik Deweerdt
2006-06-05  3:40         ` Zhu Yi
2007-02-13 14:20 ` [patch 00/11] ANNOUNCE: "Syslets", generic asynchronous system call support Ingo Molnar
2007-02-13 15:00   ` Alan
2007-02-13 14:58     ` Benjamin LaHaise
2007-02-13 15:09       ` Arjan van de Ven
2007-02-13 16:24       ` bert hubert
2007-02-13 16:56       ` Ingo Molnar
2007-02-13 18:56         ` Evgeniy Polyakov
2007-02-13 19:12           ` Evgeniy Polyakov
2007-02-13 22:19             ` Ingo Molnar
2007-02-13 22:18           ` Ingo Molnar
2007-02-14  8:59             ` Evgeniy Polyakov
2007-02-14 10:37               ` Ingo Molnar
2007-02-14 11:10                 ` Evgeniy Polyakov
2007-02-14 17:17                 ` Davide Libenzi
2007-02-13 20:34       ` Ingo Molnar
2007-02-13 15:46     ` Dmitry Torokhov
2007-02-13 20:39       ` Ingo Molnar
2007-02-13 22:36         ` Dmitry Torokhov
2007-02-14 11:07         ` Alan
2007-02-13 16:39     ` Andi Kleen
2007-02-13 16:26       ` Linus Torvalds
2007-02-13 17:03         ` Ingo Molnar
2007-02-13 20:26         ` Davide Libenzi
2007-02-13 16:49       ` Ingo Molnar
2007-02-13 16:42     ` Ingo Molnar
2007-02-13 20:22   ` Davide Libenzi
2007-02-13 21:24     ` Davide Libenzi
2007-02-13 22:10       ` Ingo Molnar
2007-02-13 23:28         ` Davide Libenzi
2007-02-13 21:57     ` Ingo Molnar
2007-02-13 22:50       ` Olivier Galibert
2007-02-13 22:59       ` Ulrich Drepper
2007-02-13 23:24       ` Davide Libenzi
2007-02-13 23:25       ` Andi Kleen
2007-02-13 22:26         ` Ingo Molnar
2007-02-13 22:32           ` Andi Kleen
2007-02-13 22:43             ` Ingo Molnar
2007-02-13 22:47               ` Andi Kleen
2007-02-14  3:28   ` Davide Libenzi
2007-02-14  4:49     ` Davide Libenzi
2007-02-14  8:26       ` Ingo Molnar
2007-02-14  4:42   ` Willy Tarreau
2007-02-14 12:37   ` Pavel Machek
2007-02-14 17:14     ` Linus Torvalds
2007-02-14 20:52   ` Jeremy Fitzhardinge
2007-02-14 21:36     ` Davide Libenzi
2007-02-15  0:08       ` Jeremy Fitzhardinge
2007-02-15  2:07         ` Davide Libenzi
2007-02-15  2:44   ` Zach Brown
2007-02-13 14:20 ` [patch 01/11] syslets: add async.h include file, kernel-side API definitions Ingo Molnar
2007-02-13 14:20 ` [patch 02/11] syslets: add syslet.h include file, user API/ABI definitions Ingo Molnar
2007-02-13 20:17   ` Indan Zupancic
2007-02-13 21:43     ` Ingo Molnar
2007-02-13 22:24       ` Indan Zupancic
2007-02-13 22:32         ` Ingo Molnar
2007-02-19  0:22   ` Paul Mackerras
2007-02-13 14:20 ` [patch 03/11] syslets: generic kernel bits Ingo Molnar
2007-02-13 14:20 ` [patch 04/11] syslets: core, data structures Ingo Molnar
2007-02-13 14:20 ` [patch 05/11] syslets: core code Ingo Molnar
2007-02-13 23:15   ` Andi Kleen
2007-02-13 22:24     ` Ingo Molnar
2007-02-13 22:30       ` Andi Kleen
2007-02-13 22:41         ` Ingo Molnar
2007-02-14  9:13           ` Evgeniy Polyakov
2007-02-14  9:46             ` Ingo Molnar
2007-02-14 10:09               ` Evgeniy Polyakov
2007-02-14 10:30                 ` Arjan van de Ven
2007-02-14 10:41                   ` Evgeniy Polyakov
2007-02-13 22:57       ` Andrew Morton
2007-02-14 12:43   ` Guillaume Chazarain
2007-02-14 13:17   ` Stephen Rothwell
2007-02-14 20:38   ` Linus Torvalds
2007-02-14 21:02     ` Ingo Molnar
2007-02-14 21:12       ` Ingo Molnar
2007-02-14 21:26       ` Linus Torvalds
2007-02-14 21:35         ` Ingo Molnar
2007-02-15  2:52           ` Zach Brown
2007-02-14 21:44         ` Ingo Molnar
2007-02-14 21:56         ` Alan
2007-02-14 22:32           ` Ingo Molnar
2007-02-15  1:01             ` Davide Libenzi
2007-02-15  1:28               ` Davide Libenzi
2007-02-18 20:01                 ` Pavel Machek
2007-02-18 20:37                   ` Davide Libenzi
2007-02-18 21:04                     ` Michael K. Edwards
2007-02-14 21:09     ` Davide Libenzi
2007-02-14 22:09     ` Ingo Molnar
2007-02-14 23:13       ` Linus Torvalds
2007-02-14 23:44         ` Ingo Molnar
2007-02-15  0:04           ` Ingo Molnar
2007-02-15 13:35     ` Evgeniy Polyakov
2007-02-15 16:09       ` Linus Torvalds
2007-02-15 16:37         ` Evgeniy Polyakov
2007-02-15 17:42           ` Linus Torvalds
2007-02-15 18:11             ` Evgeniy Polyakov
2007-02-15 18:25               ` Linus Torvalds
2007-02-15 19:04                 ` Evgeniy Polyakov
2007-02-15 19:28                   ` Linus Torvalds
2007-02-15 20:07                     ` Linus Torvalds
2007-02-15 21:17                       ` Davide Libenzi
2007-02-15 22:34                       ` Michael K. Edwards
2007-02-16 12:28                       ` Ingo Molnar
2007-02-16 13:28                         ` Evgeniy Polyakov
2007-02-16  8:57                     ` Evgeniy Polyakov
2007-02-16 15:54                       ` Linus Torvalds
2007-02-16 16:05                         ` Evgeniy Polyakov
2007-02-16 16:53                           ` Ray Lee
2007-02-16 16:58                             ` Evgeniy Polyakov
2007-02-16 20:20                               ` Cyrill V. Gorcunov
2007-02-17 10:02                                 ` Evgeniy Polyakov
2007-02-17 17:59                                   ` Cyrill V. Gorcunov
2007-02-17  4:54                               ` Ray Lee
2007-02-17 10:15                                 ` Evgeniy Polyakov
2007-02-15 18:46             ` bert hubert
2007-02-15 19:10               ` Evgeniy Polyakov
2007-02-15 19:16               ` Zach Brown
2007-02-15 19:26               ` Eric Dumazet
2007-02-15 17:05         ` Davide Libenzi
2007-02-15 17:17           ` Evgeniy Polyakov
2007-02-15 17:39             ` Davide Libenzi
2007-02-15 18:01               ` Evgeniy Polyakov
2007-02-15 17:17         ` Ulrich Drepper
2007-02-13 14:20 ` [patch 06/11] syslets: core, documentation Ingo Molnar
2007-02-13 20:18   ` Davide Libenzi
2007-02-13 21:34     ` Ingo Molnar
2007-02-13 23:21       ` Davide Libenzi
2007-02-14  0:18         ` Davide Libenzi
2007-02-14 10:36   ` Russell King
2007-02-14 10:50     ` Ingo Molnar
2007-02-14 11:04       ` Russell King
2007-02-14 17:52         ` Davide Libenzi
2007-02-14 18:03           ` Benjamin LaHaise
2007-02-14 19:45             ` Davide Libenzi
2007-02-14 20:03               ` Benjamin LaHaise
2007-02-14 20:14                 ` Davide Libenzi
2007-02-14 20:34                   ` Benjamin LaHaise
2007-02-14 21:06                     ` Davide Libenzi
2007-02-14 21:44                       ` Benjamin LaHaise
2007-02-14 23:17                         ` Davide Libenzi
2007-02-14 23:40                           ` Benjamin LaHaise
2007-02-15  0:35                             ` Davide Libenzi
2007-02-15  1:32                         ` Michael K. Edwards
2007-02-14 21:49                     ` Ingo Molnar [this message]
2007-02-14 22:04                       ` [patch] x86: split FPU state from task state Benjamin LaHaise
2007-02-14 22:10                         ` Arjan van de Ven
2007-02-13 14:20 ` [patch 07/11] syslets: x86, add create_async_thread() method Ingo Molnar
     [not found] ` <20061213130211.GT21847@elte.hu>
2007-02-15 10:13   ` [patch 19/31] clockevents: i386 drivers Andrew Morton

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=20070214214944.GA1082@elte.hu \
    --to=mingo@elte.hu \
    --cc=akpm@zip.com.au \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=arjan@infradead.org \
    --cc=bcrl@kvack.org \
    --cc=davem@davemloft.net \
    --cc=davidel@xmailserver.org \
    --cc=drepper@redhat.com \
    --cc=hch@infradead.org \
    --cc=johnpol@2ka.mipt.ru \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rmk+lkml@arm.linux.org.uk \
    --cc=suparna@in.ibm.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=zach.brown@oracle.com \
    /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