diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2008-03-10 18:28:05 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-19 13:19:55 -0400 |
commit | aa283f49276e7d840a40fb01eee6de97eaa7e012 (patch) | |
tree | b17b134b174666e482b1a8ad486436a3d5cdb83e /arch/x86/kernel/process.c | |
parent | 61c4628b538608c1a85211ed8438136adfeb9a95 (diff) |
x86, fpu: lazy allocation of FPU area - v5
Only allocate the FPU area when the application actually uses FPU, i.e., in the
first lazy FPU trap. This could save memory for non-fpu using apps.
for example: on my system after boot, there are around 300 processes, with
only 17 using FPU.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ead24efbcba0..0e613e7e7b5e 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -5,24 +5,34 @@ | |||
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | 7 | ||
8 | static struct kmem_cache *task_xstate_cachep; | 8 | struct kmem_cache *task_xstate_cachep; |
9 | 9 | ||
10 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | 10 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
11 | { | 11 | { |
12 | *dst = *src; | 12 | *dst = *src; |
13 | dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, GFP_KERNEL); | 13 | if (src->thread.xstate) { |
14 | if (!dst->thread.xstate) | 14 | dst->thread.xstate = kmem_cache_alloc(task_xstate_cachep, |
15 | return -ENOMEM; | 15 | GFP_KERNEL); |
16 | WARN_ON((unsigned long)dst->thread.xstate & 15); | 16 | if (!dst->thread.xstate) |
17 | memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); | 17 | return -ENOMEM; |
18 | WARN_ON((unsigned long)dst->thread.xstate & 15); | ||
19 | memcpy(dst->thread.xstate, src->thread.xstate, xstate_size); | ||
20 | } | ||
18 | return 0; | 21 | return 0; |
19 | } | 22 | } |
20 | 23 | ||
21 | void free_thread_info(struct thread_info *ti) | 24 | void free_thread_xstate(struct task_struct *tsk) |
22 | { | 25 | { |
23 | kmem_cache_free(task_xstate_cachep, ti->task->thread.xstate); | 26 | if (tsk->thread.xstate) { |
24 | ti->task->thread.xstate = NULL; | 27 | kmem_cache_free(task_xstate_cachep, tsk->thread.xstate); |
28 | tsk->thread.xstate = NULL; | ||
29 | } | ||
30 | } | ||
31 | |||
25 | 32 | ||
33 | void free_thread_info(struct thread_info *ti) | ||
34 | { | ||
35 | free_thread_xstate(ti->task); | ||
26 | free_pages((unsigned long)(ti), get_order(THREAD_SIZE)); | 36 | free_pages((unsigned long)(ti), get_order(THREAD_SIZE)); |
27 | } | 37 | } |
28 | 38 | ||