diff options
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 687a15d56243..9f9b296fa6df 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -112,32 +112,67 @@ int nr_processes(void) | |||
112 | return total; | 112 | return total; |
113 | } | 113 | } |
114 | 114 | ||
115 | #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR | 115 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
116 | # define alloc_task_struct_node(node) \ | ||
117 | kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node) | ||
118 | # define free_task_struct(tsk) \ | ||
119 | kmem_cache_free(task_struct_cachep, (tsk)) | ||
120 | static struct kmem_cache *task_struct_cachep; | 116 | static struct kmem_cache *task_struct_cachep; |
117 | |||
118 | static inline struct task_struct *alloc_task_struct_node(int node) | ||
119 | { | ||
120 | return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node); | ||
121 | } | ||
122 | |||
123 | void __weak arch_release_task_struct(struct task_struct *tsk) { } | ||
124 | |||
125 | static inline void free_task_struct(struct task_struct *tsk) | ||
126 | { | ||
127 | arch_release_task_struct(tsk); | ||
128 | kmem_cache_free(task_struct_cachep, tsk); | ||
129 | } | ||
121 | #endif | 130 | #endif |
122 | 131 | ||
123 | #ifndef __HAVE_ARCH_THREAD_INFO_ALLOCATOR | 132 | #ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR |
133 | void __weak arch_release_thread_info(struct thread_info *ti) { } | ||
134 | |||
135 | /* | ||
136 | * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a | ||
137 | * kmemcache based allocator. | ||
138 | */ | ||
139 | # if THREAD_SIZE >= PAGE_SIZE | ||
124 | static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, | 140 | static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, |
125 | int node) | 141 | int node) |
126 | { | 142 | { |
127 | #ifdef CONFIG_DEBUG_STACK_USAGE | 143 | struct page *page = alloc_pages_node(node, THREADINFO_GFP, |
128 | gfp_t mask = GFP_KERNEL | __GFP_ZERO; | 144 | THREAD_SIZE_ORDER); |
129 | #else | ||
130 | gfp_t mask = GFP_KERNEL; | ||
131 | #endif | ||
132 | struct page *page = alloc_pages_node(node, mask, THREAD_SIZE_ORDER); | ||
133 | 145 | ||
134 | return page ? page_address(page) : NULL; | 146 | return page ? page_address(page) : NULL; |
135 | } | 147 | } |
136 | 148 | ||
137 | static inline void free_thread_info(struct thread_info *ti) | 149 | static inline void free_thread_info(struct thread_info *ti) |
138 | { | 150 | { |
151 | arch_release_thread_info(ti); | ||
139 | free_pages((unsigned long)ti, THREAD_SIZE_ORDER); | 152 | free_pages((unsigned long)ti, THREAD_SIZE_ORDER); |
140 | } | 153 | } |
154 | # else | ||
155 | static struct kmem_cache *thread_info_cache; | ||
156 | |||
157 | static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, | ||
158 | int node) | ||
159 | { | ||
160 | return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node); | ||
161 | } | ||
162 | |||
163 | static void free_thread_info(struct thread_info *ti) | ||
164 | { | ||
165 | arch_release_thread_info(ti); | ||
166 | kmem_cache_free(thread_info_cache, ti); | ||
167 | } | ||
168 | |||
169 | void thread_info_cache_init(void) | ||
170 | { | ||
171 | thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, | ||
172 | THREAD_SIZE, 0, NULL); | ||
173 | BUG_ON(thread_info_cache == NULL); | ||
174 | } | ||
175 | # endif | ||
141 | #endif | 176 | #endif |
142 | 177 | ||
143 | /* SLAB cache for signal_struct structures (tsk->signal) */ | 178 | /* SLAB cache for signal_struct structures (tsk->signal) */ |
@@ -204,17 +239,11 @@ void __put_task_struct(struct task_struct *tsk) | |||
204 | } | 239 | } |
205 | EXPORT_SYMBOL_GPL(__put_task_struct); | 240 | EXPORT_SYMBOL_GPL(__put_task_struct); |
206 | 241 | ||
207 | /* | 242 | void __init __weak arch_task_cache_init(void) { } |
208 | * macro override instead of weak attribute alias, to workaround | ||
209 | * gcc 4.1.0 and 4.1.1 bugs with weak attribute and empty functions. | ||
210 | */ | ||
211 | #ifndef arch_task_cache_init | ||
212 | #define arch_task_cache_init() | ||
213 | #endif | ||
214 | 243 | ||
215 | void __init fork_init(unsigned long mempages) | 244 | void __init fork_init(unsigned long mempages) |
216 | { | 245 | { |
217 | #ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR | 246 | #ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR |
218 | #ifndef ARCH_MIN_TASKALIGN | 247 | #ifndef ARCH_MIN_TASKALIGN |
219 | #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES | 248 | #define ARCH_MIN_TASKALIGN L1_CACHE_BYTES |
220 | #endif | 249 | #endif |