diff options
author | Steve French <sfrench@us.ibm.com> | 2008-04-24 11:26:50 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2008-04-24 11:26:50 -0400 |
commit | 36d99df2fb474222ab47fbe8ae7385661033223b (patch) | |
tree | 962e068491b752a944f61c454fad3f8619a1ea3f /kernel/fork.c | |
parent | 076d8423a98659a92837b07aa494cb74bfefe77c (diff) | |
parent | 3dc5063786b273f1aee545844f6bd4e9651ebffe (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.c | 35 |
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 | |||
135 | void __init fork_init(unsigned long mempages) | 143 | void __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 | ||
177 | int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst, | ||
178 | struct task_struct *src) | ||
179 | { | ||
180 | *dst = *src; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
166 | static struct task_struct *dup_task_struct(struct task_struct *orig) | 184 | static 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 | |||
227 | out: | ||
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 |