aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c70
1 files changed, 34 insertions, 36 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 5c2c355aa97f..52e725d4a866 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -148,57 +148,49 @@ static inline void free_task_struct(struct task_struct *tsk)
148} 148}
149#endif 149#endif
150 150
151void __weak arch_release_thread_info(struct thread_info *ti) 151void __weak arch_release_thread_stack(unsigned long *stack)
152{ 152{
153} 153}
154 154
155#ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR 155#ifndef CONFIG_ARCH_THREAD_STACK_ALLOCATOR
156 156
157/* 157/*
158 * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a 158 * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a
159 * kmemcache based allocator. 159 * kmemcache based allocator.
160 */ 160 */
161# if THREAD_SIZE >= PAGE_SIZE 161# if THREAD_SIZE >= PAGE_SIZE
162static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, 162static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,
163 int node) 163 int node)
164{ 164{
165 struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP, 165 struct page *page = alloc_pages_node(node, THREADINFO_GFP,
166 THREAD_SIZE_ORDER); 166 THREAD_SIZE_ORDER);
167
168 if (page)
169 memcg_kmem_update_page_stat(page, MEMCG_KERNEL_STACK,
170 1 << THREAD_SIZE_ORDER);
171 167
172 return page ? page_address(page) : NULL; 168 return page ? page_address(page) : NULL;
173} 169}
174 170
175static inline void free_thread_info(struct thread_info *ti) 171static inline void free_thread_stack(unsigned long *stack)
176{ 172{
177 struct page *page = virt_to_page(ti); 173 __free_pages(virt_to_page(stack), THREAD_SIZE_ORDER);
178
179 memcg_kmem_update_page_stat(page, MEMCG_KERNEL_STACK,
180 -(1 << THREAD_SIZE_ORDER));
181 __free_kmem_pages(page, THREAD_SIZE_ORDER);
182} 174}
183# else 175# else
184static struct kmem_cache *thread_info_cache; 176static struct kmem_cache *thread_stack_cache;
185 177
186static struct thread_info *alloc_thread_info_node(struct task_struct *tsk, 178static unsigned long *alloc_thread_stack_node(struct task_struct *tsk,
187 int node) 179 int node)
188{ 180{
189 return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node); 181 return kmem_cache_alloc_node(thread_stack_cache, THREADINFO_GFP, node);
190} 182}
191 183
192static void free_thread_info(struct thread_info *ti) 184static void free_thread_stack(unsigned long *stack)
193{ 185{
194 kmem_cache_free(thread_info_cache, ti); 186 kmem_cache_free(thread_stack_cache, stack);
195} 187}
196 188
197void thread_info_cache_init(void) 189void thread_stack_cache_init(void)
198{ 190{
199 thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE, 191 thread_stack_cache = kmem_cache_create("thread_stack", THREAD_SIZE,
200 THREAD_SIZE, 0, NULL); 192 THREAD_SIZE, 0, NULL);
201 BUG_ON(thread_info_cache == NULL); 193 BUG_ON(thread_stack_cache == NULL);
202} 194}
203# endif 195# endif
204#endif 196#endif
@@ -221,18 +213,24 @@ struct kmem_cache *vm_area_cachep;
221/* SLAB cache for mm_struct structures (tsk->mm) */ 213/* SLAB cache for mm_struct structures (tsk->mm) */
222static struct kmem_cache *mm_cachep; 214static struct kmem_cache *mm_cachep;
223 215
224static void account_kernel_stack(struct thread_info *ti, int account) 216static void account_kernel_stack(unsigned long *stack, int account)
225{ 217{
226 struct zone *zone = page_zone(virt_to_page(ti)); 218 /* All stack pages are in the same zone and belong to the same memcg. */
219 struct page *first_page = virt_to_page(stack);
220
221 mod_zone_page_state(page_zone(first_page), NR_KERNEL_STACK_KB,
222 THREAD_SIZE / 1024 * account);
227 223
228 mod_zone_page_state(zone, NR_KERNEL_STACK, account); 224 memcg_kmem_update_page_stat(
225 first_page, MEMCG_KERNEL_STACK_KB,
226 account * (THREAD_SIZE / 1024));
229} 227}
230 228
231void free_task(struct task_struct *tsk) 229void free_task(struct task_struct *tsk)
232{ 230{
233 account_kernel_stack(tsk->stack, -1); 231 account_kernel_stack(tsk->stack, -1);
234 arch_release_thread_info(tsk->stack); 232 arch_release_thread_stack(tsk->stack);
235 free_thread_info(tsk->stack); 233 free_thread_stack(tsk->stack);
236 rt_mutex_debug_task_free(tsk); 234 rt_mutex_debug_task_free(tsk);
237 ftrace_graph_exit_task(tsk); 235 ftrace_graph_exit_task(tsk);
238 put_seccomp_filter(tsk); 236 put_seccomp_filter(tsk);
@@ -343,7 +341,7 @@ void set_task_stack_end_magic(struct task_struct *tsk)
343static struct task_struct *dup_task_struct(struct task_struct *orig, int node) 341static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
344{ 342{
345 struct task_struct *tsk; 343 struct task_struct *tsk;
346 struct thread_info *ti; 344 unsigned long *stack;
347 int err; 345 int err;
348 346
349 if (node == NUMA_NO_NODE) 347 if (node == NUMA_NO_NODE)
@@ -352,15 +350,15 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
352 if (!tsk) 350 if (!tsk)
353 return NULL; 351 return NULL;
354 352
355 ti = alloc_thread_info_node(tsk, node); 353 stack = alloc_thread_stack_node(tsk, node);
356 if (!ti) 354 if (!stack)
357 goto free_tsk; 355 goto free_tsk;
358 356
359 err = arch_dup_task_struct(tsk, orig); 357 err = arch_dup_task_struct(tsk, orig);
360 if (err) 358 if (err)
361 goto free_ti; 359 goto free_stack;
362 360
363 tsk->stack = ti; 361 tsk->stack = stack;
364#ifdef CONFIG_SECCOMP 362#ifdef CONFIG_SECCOMP
365 /* 363 /*
366 * We must handle setting up seccomp filters once we're under 364 * We must handle setting up seccomp filters once we're under
@@ -392,14 +390,14 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
392 tsk->task_frag.page = NULL; 390 tsk->task_frag.page = NULL;
393 tsk->wake_q.next = NULL; 391 tsk->wake_q.next = NULL;
394 392
395 account_kernel_stack(ti, 1); 393 account_kernel_stack(stack, 1);
396 394
397 kcov_task_init(tsk); 395 kcov_task_init(tsk);
398 396
399 return tsk; 397 return tsk;
400 398
401free_ti: 399free_stack:
402 free_thread_info(ti); 400 free_thread_stack(stack);
403free_tsk: 401free_tsk:
404 free_task_struct(tsk); 402 free_task_struct(tsk);
405 return NULL; 403 return NULL;