aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-04-24 11:26:50 -0400
committerSteve French <sfrench@us.ibm.com>2008-04-24 11:26:50 -0400
commit36d99df2fb474222ab47fbe8ae7385661033223b (patch)
tree962e068491b752a944f61c454fad3f8619a1ea3f /kernel/fork.c
parent076d8423a98659a92837b07aa494cb74bfefe77c (diff)
parent3dc5063786b273f1aee545844f6bd4e9651ebffe (diff)
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 9c042f901570..89fe414645e9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -132,6 +132,14 @@ void __put_task_struct(struct task_struct *tsk)
132 free_task(tsk); 132 free_task(tsk);
133} 133}
134 134
135/*
136 * macro override instead of weak attribute alias, to workaround
137 * gcc 4.1.0 and 4.1.1 bugs with weak attribute and empty functions.
138 */
139#ifndef arch_task_cache_init
140#define arch_task_cache_init()
141#endif
142
135void __init fork_init(unsigned long mempages) 143void __init fork_init(unsigned long mempages)
136{ 144{
137#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR 145#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
@@ -144,6 +152,9 @@ void __init fork_init(unsigned long mempages)
144 ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL); 152 ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL);
145#endif 153#endif
146 154
155 /* do the arch specific task caches init */
156 arch_task_cache_init();
157
147 /* 158 /*
148 * The default maximum number of threads is set to a safe 159 * The default maximum number of threads is set to a safe
149 * value: the thread structures can take up at most half 160 * value: the thread structures can take up at most half
@@ -163,6 +174,13 @@ void __init fork_init(unsigned long mempages)
163 init_task.signal->rlim[RLIMIT_NPROC]; 174 init_task.signal->rlim[RLIMIT_NPROC];
164} 175}
165 176
177int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst,
178 struct task_struct *src)
179{
180 *dst = *src;
181 return 0;
182}
183
166static struct task_struct *dup_task_struct(struct task_struct *orig) 184static struct task_struct *dup_task_struct(struct task_struct *orig)
167{ 185{
168 struct task_struct *tsk; 186 struct task_struct *tsk;
@@ -181,15 +199,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
181 return NULL; 199 return NULL;
182 } 200 }
183 201
184 *tsk = *orig; 202 err = arch_dup_task_struct(tsk, orig);
203 if (err)
204 goto out;
205
185 tsk->stack = ti; 206 tsk->stack = ti;
186 207
187 err = prop_local_init_single(&tsk->dirties); 208 err = prop_local_init_single(&tsk->dirties);
188 if (err) { 209 if (err)
189 free_thread_info(ti); 210 goto out;
190 free_task_struct(tsk);
191 return NULL;
192 }
193 211
194 setup_thread_stack(tsk, orig); 212 setup_thread_stack(tsk, orig);
195 213
@@ -205,6 +223,11 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
205#endif 223#endif
206 tsk->splice_pipe = NULL; 224 tsk->splice_pipe = NULL;
207 return tsk; 225 return tsk;
226
227out:
228 free_thread_info(ti);
229 free_task_struct(tsk);
230 return NULL;
208} 231}
209 232
210#ifdef CONFIG_MMU 233#ifdef CONFIG_MMU