summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-09 18:20:35 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2003-03-09 18:20:35 -0800
commit450b4497e37d77eb6ab44b9001c50e68de38afde (patch)
tree53843cc42acbb8d928b53afd4a453b8ce202d82f /include
parent36f0619922472bf8e5ecf83ac420114952a87bf3 (diff)
Move "used FPU status" into new non-atomic thread_info->status field.
This allows us to avoid having to use atomic updates for the lazy FP status setting, since we don't have to worry about other CPU's racing on the fields. Also, fix x86 FP state after fork() by making sure the FP is unlazied _before_ we copy the state information. Otherwise, if a process did a fork() while holding the FP state lazily in the registers, the child would incorrectly unlazy bogus state.
Diffstat (limited to 'include')
-rw-r--r--include/asm-alpha/processor.h3
-rw-r--r--include/asm-arm/processor.h3
-rw-r--r--include/asm-cris/processor.h3
-rw-r--r--include/asm-i386/i387.h8
-rw-r--r--include/asm-i386/processor.h4
-rw-r--r--include/asm-i386/thread_info.h23
-rw-r--r--include/asm-ia64/processor.h3
-rw-r--r--include/asm-m68k/processor.h3
-rw-r--r--include/asm-m68knommu/processor.h3
-rw-r--r--include/asm-mips/processor.h3
-rw-r--r--include/asm-mips64/processor.h3
-rw-r--r--include/asm-parisc/processor.h3
-rw-r--r--include/asm-ppc/processor.h3
-rw-r--r--include/asm-ppc64/processor.h3
-rw-r--r--include/asm-s390/processor.h3
-rw-r--r--include/asm-s390x/processor.h3
-rw-r--r--include/asm-sh/processor.h4
-rw-r--r--include/asm-sparc/processor.h3
-rw-r--r--include/asm-sparc64/processor.h3
-rw-r--r--include/asm-v850/processor.h3
-rw-r--r--include/asm-x86_64/processor.h4
21 files changed, 80 insertions, 11 deletions
diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
index 0ba43172df9c..830d6f73bea1 100644
--- a/include/asm-alpha/processor.h
+++ b/include/asm-alpha/processor.h
@@ -51,6 +51,9 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/* Create a kernel thread without removing it from tasklists. */
extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h
index 7f1cd371e0d0..7fa77f0c4248 100644
--- a/include/asm-arm/processor.h
+++ b/include/asm-arm/processor.h
@@ -62,6 +62,9 @@ struct task_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
unsigned long get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h
index 61c75282ac43..0a8c08fa93b5 100644
--- a/include/asm-cris/processor.h
+++ b/include/asm-cris/processor.h
@@ -123,6 +123,9 @@ static inline void release_thread(struct task_struct *dead_task)
/* Nothing needs to be done. */
}
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* Return saved PC of a blocked thread.
*/
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 080aceb7e03d..805f297e0514 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -36,7 +36,7 @@ static inline void __save_init_fpu( struct task_struct *tsk )
asm volatile( "fnsave %0 ; fwait"
: "=m" (tsk->thread.i387.fsave) );
}
- tsk->thread_info->flags &= ~_TIF_USEDFPU;
+ tsk->thread_info->status &= ~TS_USEDFPU;
}
static inline void save_init_fpu( struct task_struct *tsk )
@@ -47,15 +47,15 @@ static inline void save_init_fpu( struct task_struct *tsk )
#define unlazy_fpu( tsk ) do { \
- if ((tsk)->thread_info->flags & _TIF_USEDFPU) \
+ if ((tsk)->thread_info->status & TS_USEDFPU) \
save_init_fpu( tsk ); \
} while (0)
#define clear_fpu( tsk ) \
do { \
- if ((tsk)->thread_info->flags & _TIF_USEDFPU) { \
+ if ((tsk)->thread_info->status & TS_USEDFPU) { \
asm volatile("fwait"); \
- (tsk)->thread_info->flags &= ~_TIF_USEDFPU; \
+ (tsk)->thread_info->status &= ~TS_USEDFPU; \
stts(); \
} \
} while (0)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 00014406c6ac..02dd0857088a 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -446,6 +446,10 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+extern void prepare_to_copy(struct task_struct *tsk);
+
/*
* create a kernel thread without removing it from tasklists
*/
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index adcd9a41c7d2..0bf7210b8a85 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -25,6 +25,7 @@ struct thread_info {
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
unsigned long flags; /* low level flags */
+ unsigned long status; /* thread-synchronous flags */
__u32 cpu; /* current CPU */
__s32 preempt_count; /* 0 => preemptable, <0 => BUG */
@@ -43,10 +44,11 @@ struct thread_info {
#define TI_TASK 0x00000000
#define TI_EXEC_DOMAIN 0x00000004
#define TI_FLAGS 0x00000008
-#define TI_CPU 0x0000000C
-#define TI_PRE_COUNT 0x00000010
-#define TI_ADDR_LIMIT 0x00000014
-#define TI_RESTART_BLOCK 0x0000018
+#define TI_STATUS 0x0000000C
+#define TI_CPU 0x00000010
+#define TI_PRE_COUNT 0x00000014
+#define TI_ADDR_LIMIT 0x00000018
+#define TI_RESTART_BLOCK 0x000001C
#endif
@@ -111,8 +113,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
#define TIF_IRET 5 /* return with iret */
-#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -120,12 +121,20 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
#define _TIF_IRET (1<<TIF_IRET)
-#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_USEDFPU 0x0001 /* FPU was used by this task this quantum (SMP) */
+
#endif /* __KERNEL__ */
#endif /* _ASM_THREAD_INFO_H */
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
index 74a567885ffe..4c4e06dddd62 100644
--- a/include/asm-ia64/processor.h
+++ b/include/asm-ia64/processor.h
@@ -344,6 +344,9 @@ struct task_struct;
# define release_thread(dead_task)
#endif
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* This is the mechanism for creating a new kernel thread.
*
diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h
index 4e6df0c1d84c..fb463bda10de 100644
--- a/include/asm-m68k/processor.h
+++ b/include/asm-m68k/processor.h
@@ -112,6 +112,9 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
diff --git a/include/asm-m68knommu/processor.h b/include/asm-m68knommu/processor.h
index 4f975625f12a..547a96604b46 100644
--- a/include/asm-m68knommu/processor.h
+++ b/include/asm-m68knommu/processor.h
@@ -108,6 +108,9 @@ static inline void release_thread(struct task_struct *dead_task)
{
}
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h
index a2df351da263..5b06f8081a62 100644
--- a/include/asm-mips/processor.h
+++ b/include/asm-mips/processor.h
@@ -208,6 +208,9 @@ struct thread_struct {
/* Free all resources held by a thread. */
#define release_thread(thread) do { } while(0)
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
diff --git a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h
index e9eabd0347c0..2b4a40e0fdc7 100644
--- a/include/asm-mips64/processor.h
+++ b/include/asm-mips64/processor.h
@@ -231,6 +231,9 @@ struct thread_struct {
/* Free all resources held by a thread. */
#define release_thread(thread) do { } while(0)
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/*
diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h
index 2feb19370ed8..30bdf987b3a5 100644
--- a/include/asm-parisc/processor.h
+++ b/include/asm-parisc/processor.h
@@ -290,6 +290,9 @@ struct mm_struct;
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern void map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm);
static inline unsigned long get_wchan(struct task_struct *p)
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index 8692d5cb2c6c..18d3995bc586 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -608,6 +608,9 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
void release_thread(struct task_struct *);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* Create a new kernel thread.
*/
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index c6c686a151d5..3700f3eb0430 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -601,6 +601,9 @@ struct task_struct;
void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
void release_thread(struct task_struct *);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* Create a new kernel thread.
*/
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 8b4d6679712e..dcac9d8ad5b2 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -114,6 +114,9 @@ struct mm_struct;
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* Return saved PC of a blocked thread.
*/
diff --git a/include/asm-s390x/processor.h b/include/asm-s390x/processor.h
index d90e535a0e74..4e4283b8fd0d 100644
--- a/include/asm-s390x/processor.h
+++ b/include/asm-s390x/processor.h
@@ -129,6 +129,9 @@ struct mm_struct;
extern void release_thread(struct task_struct *);
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* Return saved PC of a blocked thread.
*/
diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h
index b3fd05c8cfd8..673ae9035bb9 100644
--- a/include/asm-sh/processor.h
+++ b/include/asm-sh/processor.h
@@ -134,6 +134,10 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* create a kernel thread without removing it from tasklists
*/
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
index d6ef337682f4..f9612e0d4213 100644
--- a/include/asm-sparc/processor.h
+++ b/include/asm-sparc/processor.h
@@ -139,6 +139,9 @@ extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
#define release_thread(tsk) do { } while(0)
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern unsigned long get_wchan(struct task_struct *);
#define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc)
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
index af72b9e39911..4adc999066f8 100644
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -186,6 +186,9 @@ do { \
/* Free all resources held by a thread. */
#define release_thread(tsk) do { } while (0)
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern unsigned long get_wchan(struct task_struct *task);
diff --git a/include/asm-v850/processor.h b/include/asm-v850/processor.h
index 978a1e1720f2..180ae0548473 100644
--- a/include/asm-v850/processor.h
+++ b/include/asm-v850/processor.h
@@ -81,6 +81,9 @@ extern inline void release_thread (struct task_struct *dead_task)
{
}
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
extern int kernel_thread (int (*fn)(void *), void * arg, unsigned long flags);
/* Free current thread data structures etc. */
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index d4193bce6b42..705ccf54580c 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -267,6 +267,10 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
/*
* create a kernel thread without removing it from tasklists
*/