Skip to content

Commit 8e02b1b

Browse files
linuswakpm00
authored andcommitted
fork: define a local GFP_VMAP_STACK
The current allocation of VMAP stack memory is using (THREADINFO_GFP & ~__GFP_ACCOUNT) which is a complicated way of saying (GFP_KERNEL | __GFP_ZERO): <linux/thread_info.h>: define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO) <linux/gfp_types.h>: define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT) This is an unfortunate side-effect of independent changes blurring the picture: commit 19809c2 changed (THREADINFO_GFP | __GFP_HIGHMEM) to just THREADINFO_GFP since highmem became implicit. commit 9b6f7e1 then added stack caching and rewrote the allocation to (THREADINFO_GFP & ~__GFP_ACCOUNT) as cached stacks need to be accounted separately. However that code, when it eventually accounts the memory does this: ret = memcg_kmem_charge(vm->pages[i], GFP_KERNEL, 0) so the memory is charged as a GFP_KERNEL allocation. Define a unique GFP_VMAP_STACK to use GFP_KERNEL | __GFP_ZERO and move the comment there. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Walleij <[email protected]> Reported-by: Mateusz Guzik <[email protected]> Cc: Pasha Tatashin <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent d82893c commit 8e02b1b

File tree

1 file changed

+45
-43
lines changed

1 file changed

+45
-43
lines changed

kernel/fork.c

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,13 @@ static inline void free_task_struct(struct task_struct *tsk)
185185
kmem_cache_free(task_struct_cachep, tsk);
186186
}
187187

188-
#ifdef CONFIG_VMAP_STACK
188+
/*
189+
* Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a
190+
* kmemcache based allocator.
191+
*/
192+
# if THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK)
193+
194+
# ifdef CONFIG_VMAP_STACK
189195
/*
190196
* vmalloc() is a bit slow, and calling vfree() enough times will force a TLB
191197
* flush. Try to minimize the number of calls by caching stacks.
@@ -198,14 +204,14 @@ struct vm_stack {
198204
struct vm_struct *stack_vm_area;
199205
};
200206

201-
static bool try_release_thread_stack_to_cache(struct vm_struct *vm_area)
207+
static bool try_release_thread_stack_to_cache(struct vm_struct *vm)
202208
{
203209
unsigned int i;
204210

205211
for (i = 0; i < NR_CACHED_STACKS; i++) {
206212
struct vm_struct *tmp = NULL;
207213

208-
if (this_cpu_try_cmpxchg(cached_stacks[i], &tmp, vm_area))
214+
if (this_cpu_try_cmpxchg(cached_stacks[i], &tmp, vm))
209215
return true;
210216
}
211217
return false;
@@ -214,12 +220,11 @@ static bool try_release_thread_stack_to_cache(struct vm_struct *vm_area)
214220
static void thread_stack_free_rcu(struct rcu_head *rh)
215221
{
216222
struct vm_stack *vm_stack = container_of(rh, struct vm_stack, rcu);
217-
struct vm_struct *vm_area = vm_stack->stack_vm_area;
218223

219224
if (try_release_thread_stack_to_cache(vm_stack->stack_vm_area))
220225
return;
221226

222-
vfree(vm_area->addr);
227+
vfree(vm_stack);
223228
}
224229

225230
static void thread_stack_delayed_free(struct task_struct *tsk)
@@ -232,68 +237,71 @@ static void thread_stack_delayed_free(struct task_struct *tsk)
232237

233238
static int free_vm_stack_cache(unsigned int cpu)
234239
{
235-
struct vm_struct **cached_vm_stack_areas = per_cpu_ptr(cached_stacks, cpu);
240+
struct vm_struct **cached_vm_stacks = per_cpu_ptr(cached_stacks, cpu);
236241
int i;
237242

238243
for (i = 0; i < NR_CACHED_STACKS; i++) {
239-
struct vm_struct *vm_area = cached_vm_stack_areas[i];
244+
struct vm_struct *vm_stack = cached_vm_stacks[i];
240245

241-
if (!vm_area)
246+
if (!vm_stack)
242247
continue;
243248

244-
vfree(vm_area->addr);
245-
cached_vm_stack_areas[i] = NULL;
249+
vfree(vm_stack->addr);
250+
cached_vm_stacks[i] = NULL;
246251
}
247252

248253
return 0;
249254
}
250255

251-
static int memcg_charge_kernel_stack(struct vm_struct *vm_area)
256+
static int memcg_charge_kernel_stack(struct vm_struct *vm)
252257
{
253258
int i;
254259
int ret;
255260
int nr_charged = 0;
256261

257-
BUG_ON(vm_area->nr_pages != THREAD_SIZE / PAGE_SIZE);
262+
BUG_ON(vm->nr_pages != THREAD_SIZE / PAGE_SIZE);
258263

259264
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++) {
260-
ret = memcg_kmem_charge_page(vm_area->pages[i], GFP_KERNEL, 0);
265+
ret = memcg_kmem_charge_page(vm->pages[i], GFP_KERNEL, 0);
261266
if (ret)
262267
goto err;
263268
nr_charged++;
264269
}
265270
return 0;
266271
err:
267272
for (i = 0; i < nr_charged; i++)
268-
memcg_kmem_uncharge_page(vm_area->pages[i], 0);
273+
memcg_kmem_uncharge_page(vm->pages[i], 0);
269274
return ret;
270275
}
271276

272277
static int alloc_thread_stack_node(struct task_struct *tsk, int node)
273278
{
274-
struct vm_struct *vm_area;
279+
struct vm_struct *vm;
275280
void *stack;
276281
int i;
277282

278283
for (i = 0; i < NR_CACHED_STACKS; i++) {
279-
vm_area = this_cpu_xchg(cached_stacks[i], NULL);
280-
if (!vm_area)
281-
continue;
284+
struct vm_struct *s;
282285

283-
if (memcg_charge_kernel_stack(vm_area)) {
284-
vfree(vm_area->addr);
285-
return -ENOMEM;
286-
}
286+
s = this_cpu_xchg(cached_stacks[i], NULL);
287+
288+
if (!s)
289+
continue;
287290

288291
/* Reset stack metadata. */
289-
kasan_unpoison_range(vm_area->addr, THREAD_SIZE);
292+
kasan_unpoison_range(s->addr, THREAD_SIZE);
290293

291-
stack = kasan_reset_tag(vm_area->addr);
294+
stack = kasan_reset_tag(s->addr);
292295

293296
/* Clear stale pointers from reused stack. */
294297
memset(stack, 0, THREAD_SIZE);
295298

296-
tsk->stack_vm_area = vm_area;
299+
if (memcg_charge_kernel_stack(s)) {
300+
vfree(s->addr);
301+
return -ENOMEM;
302+
}
303+
304+
tsk->stack_vm_area = s;
297305
tsk->stack = stack;
298306
return 0;
299307
}
@@ -309,8 +317,8 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node)
309317
if (!stack)
310318
return -ENOMEM;
311319

312-
vm_area = find_vm_area(stack);
313-
if (memcg_charge_kernel_stack(vm_area)) {
320+
vm = find_vm_area(stack);
321+
if (memcg_charge_kernel_stack(vm)) {
314322
vfree(stack);
315323
return -ENOMEM;
316324
}
@@ -319,7 +327,7 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node)
319327
* free_thread_stack() can be called in interrupt context,
320328
* so cache the vm_struct.
321329
*/
322-
tsk->stack_vm_area = vm_area;
330+
tsk->stack_vm_area = vm;
323331
stack = kasan_reset_tag(stack);
324332
tsk->stack = stack;
325333
return 0;
@@ -334,13 +342,7 @@ static void free_thread_stack(struct task_struct *tsk)
334342
tsk->stack_vm_area = NULL;
335343
}
336344

337-
#else /* !CONFIG_VMAP_STACK */
338-
339-
/*
340-
* Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a
341-
* kmemcache based allocator.
342-
*/
343-
#if THREAD_SIZE >= PAGE_SIZE
345+
# else /* !CONFIG_VMAP_STACK */
344346

345347
static void thread_stack_free_rcu(struct rcu_head *rh)
346348
{
@@ -372,7 +374,8 @@ static void free_thread_stack(struct task_struct *tsk)
372374
tsk->stack = NULL;
373375
}
374376

375-
#else /* !(THREAD_SIZE >= PAGE_SIZE) */
377+
# endif /* CONFIG_VMAP_STACK */
378+
# else /* !(THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK)) */
376379

377380
static struct kmem_cache *thread_stack_cache;
378381

@@ -411,8 +414,7 @@ void thread_stack_cache_init(void)
411414
BUG_ON(thread_stack_cache == NULL);
412415
}
413416

414-
#endif /* THREAD_SIZE >= PAGE_SIZE */
415-
#endif /* CONFIG_VMAP_STACK */
417+
# endif /* THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK) */
416418

417419
/* SLAB cache for signal_struct structures (tsk->signal) */
418420
static struct kmem_cache *signal_cachep;
@@ -515,11 +517,11 @@ void vm_area_free(struct vm_area_struct *vma)
515517
static void account_kernel_stack(struct task_struct *tsk, int account)
516518
{
517519
if (IS_ENABLED(CONFIG_VMAP_STACK)) {
518-
struct vm_struct *vm_area = task_stack_vm_area(tsk);
520+
struct vm_struct *vm = task_stack_vm_area(tsk);
519521
int i;
520522

521523
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++)
522-
mod_lruvec_page_state(vm_area->pages[i], NR_KERNEL_STACK_KB,
524+
mod_lruvec_page_state(vm->pages[i], NR_KERNEL_STACK_KB,
523525
account * (PAGE_SIZE / 1024));
524526
} else {
525527
void *stack = task_stack_page(tsk);
@@ -535,12 +537,12 @@ void exit_task_stack_account(struct task_struct *tsk)
535537
account_kernel_stack(tsk, -1);
536538

537539
if (IS_ENABLED(CONFIG_VMAP_STACK)) {
538-
struct vm_struct *vm_area;
540+
struct vm_struct *vm;
539541
int i;
540542

541-
vm_area = task_stack_vm_area(tsk);
543+
vm = task_stack_vm_area(tsk);
542544
for (i = 0; i < THREAD_SIZE / PAGE_SIZE; i++)
543-
memcg_kmem_uncharge_page(vm_area->pages[i], 0);
545+
memcg_kmem_uncharge_page(vm->pages[i], 0);
544546
}
545547
}
546548

0 commit comments

Comments
 (0)