[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 01/15] coroutine-ucontext: mmap stack memory
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH 01/15] coroutine-ucontext: mmap stack memory |
Date: |
Tue, 28 Jun 2016 11:02:11 +0100 |
On 28 June 2016 at 10:01, Peter Lieven <address@hidden> wrote:
> coroutine-ucontext currently allocates stack memory from heap as on most
> systems the
> stack size lays below the threshold for mmapping memory. This patch forces
> mmaping
> of stacks to avoid large holes on the heap when a coroutine is deleted. It
> additionally
> allows us for adding a guard page at the bottom of the stack to avoid
> overflows.
>
> Suggested-by: Peter Maydell <address@hidden>
> Signed-off-by: Peter Lieven <address@hidden>
> ---
> util/coroutine-ucontext.c | 26 +++++++++++++++++++++++---
> 1 file changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
> index 2bb7e10..841e7db 100644
> --- a/util/coroutine-ucontext.c
> +++ b/util/coroutine-ucontext.c
> @@ -80,9 +80,10 @@ static void coroutine_trampoline(int i0, int i1)
> }
> }
>
> +#define COROUTINE_STACK_SIZE (1 << 20)
> +
> Coroutine *qemu_coroutine_new(void)
> {
> - const size_t stack_size = 1 << 20;
> CoroutineUContext *co;
> ucontext_t old_uc, uc;
> sigjmp_buf old_env;
> @@ -101,17 +102,32 @@ Coroutine *qemu_coroutine_new(void)
> }
>
> co = g_malloc0(sizeof(*co));
> +
> +#ifdef MAP_GROWSDOWN
> + co->stack = mmap(NULL, COROUTINE_STACK_SIZE, PROT_READ | PROT_WRITE,
> + MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
> + if (co->stack == MAP_FAILED) {
> + abort();
> + }
> + /* add a guard page at bottom of the stack */
> + if (mmap(co->stack, getpagesize(), PROT_NONE,
> + MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0) == MAP_FAILED) {
> + abort();
> + }
> +#else
> co->stack = g_malloc(stack_size);
I would just mmap() always; then we get the benefit of the
guard page even if there's no MAP_GROWSDOWN.
Also, does MAP_GROWSDOWN help with the RSS issues? I
noticed that glibc itself doesn't use it for pthread
stacks as far as I can tell, so maybe it's obsolete?
(Ulrich Drepper apparently thought so in 2008:
https://lwn.net/Articles/294001/ )
> +#endif
Can we abstract this out into an alloc/dealloc function, please?
/**
* qemu_alloc_stack:
* @sz: size of required stack in bytes
*
* Allocate memory that can be used as a stack, for instance for
* coroutines. If the memory cannot be allocated, this function
* will abort (like g_malloc()). The allocated stack should be
* freed with qemu_free_stack().
*
* Returns: pointer to (the lowest address of) the stack memory.
*/
void *qemu_alloc_stack(size_t sz);
/**
* qemu_free_stack:
* @stack: stack to free
*
* Free a stack allocated via qemu_alloc_stack().
*/
void qemu_free_stack(void *stack);
util/coroutine-sigaltstack.c can then use the same function
for stack allocation.
I would put the implementation in util/oslib-posix.c and the
header in include/sysemu/os-posix.h, unless somebody has a
better idea.
> +
> co->base.entry_arg = &old_env; /* stash away our jmp_buf */
>
> uc.uc_link = &old_uc;
> uc.uc_stack.ss_sp = co->stack;
> - uc.uc_stack.ss_size = stack_size;
> + uc.uc_stack.ss_size = COROUTINE_STACK_SIZE;
Because of the guard page, your code above isn't actually
allocating this much stack.
> uc.uc_stack.ss_flags = 0;
>
> #ifdef CONFIG_VALGRIND_H
> co->valgrind_stack_id =
> - VALGRIND_STACK_REGISTER(co->stack, co->stack + stack_size);
> + VALGRIND_STACK_REGISTER(co->stack, co->stack + COROUTINE_STACK_SIZE);
> #endif
>
> arg.p = co;
> @@ -149,7 +165,11 @@ void qemu_coroutine_delete(Coroutine *co_)
> valgrind_stack_deregister(co);
> #endif
>
> +#ifdef MAP_GROWSDOWN
> + munmap(co->stack, COROUTINE_STACK_SIZE);
> +#else
> g_free(co->stack);
> +#endif
> g_free(co);
> }
>
> --
> 1.9.1
thanks
-- PMM
- [Qemu-devel] [PATCH 00/15] optimize Qemu RSS usage, Peter Lieven, 2016/06/28
- [Qemu-devel] [PATCH 01/15] coroutine-ucontext: mmap stack memory, Peter Lieven, 2016/06/28
- [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Peter Lieven, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Paolo Bonzini, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Dr. David Alan Gilbert, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Peter Lieven, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Dr. David Alan Gilbert, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Peter Lieven, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Dr. David Alan Gilbert, 2016/06/28
- Re: [Qemu-devel] [PATCH 03/15] coroutine-ucontext: reduce stack size to 64kB, Peter Lieven, 2016/06/30