On Tue, Aug 30, 2016 at 03:01:51PM -0700, Andy Lutomirski wrote: > On Wed, Aug 24, 2016 at 9:51 AM, Josh Cartwright wrote: [..] > >> diff --git a/kernel/fork.c b/kernel/fork.c > >> index 52e725d4a866..05f7ef796fb4 100644 > >> --- a/kernel/fork.c > >> +++ b/kernel/fork.c > >> @@ -158,19 +158,39 @@ void __weak arch_release_thread_stack(unsigned long *stack) > >> * Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a > >> * kmemcache based allocator. > >> */ > >> -# if THREAD_SIZE >= PAGE_SIZE > >> -static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, > >> - int node) > >> +# if THREAD_SIZE >= PAGE_SIZE || defined(CONFIG_VMAP_STACK) > >> +static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) > >> { > >> +#ifdef CONFIG_VMAP_STACK > >> + void *stack = __vmalloc_node_range(THREAD_SIZE, THREAD_SIZE, > >> + VMALLOC_START, VMALLOC_END, > >> + THREADINFO_GFP | __GFP_HIGHMEM, > >> + PAGE_KERNEL, > >> + 0, node, > >> + __builtin_return_address(0)); > >> + > >> + /* > >> + * We can't call find_vm_area() in interrupt context, and > >> + * free_thread_stack can be called in interrupt context, so cache > >> + * the vm_struct. > >> + */ > >> + if (stack) > >> + tsk->stack_vm_area = find_vm_area(stack); > > > > This is annoying, we end up having to walk the vm_area tree twice (once > > for the allocation, then here to get a handle on area). > > > > Perhaps it's time the vmalloc code learned an allocation API that > > returned the vm_area handle as well. > > Agreed. I may do this once everything else lands. There are at least a few other places that could benefit from this, doing a quick scan of find_vm_area() callers: vmalloc_{32_,}_user() and kasan_module_alloc(). Josh