All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Wesley Hershberger <wesley.hershberger@canonical.com>
Cc: qemu-devel@nongnu.org, Stefan Hajnoczi <stefanha@redhat.com>,
	Kevin Wolf <kwolf@redhat.com>,
	Hector Cao <hector.cao@canonical.com>,
	alex.ramirez@canonical.com
Subject: Re: [PATCH v3 2/2] util/coroutine: Reduce default idle pool max size
Date: Wed, 14 Oct 2026 08:50:34 +0100	[thread overview]
Message-ID: <as80SlXCcNDoLHLj@redhat.com> (raw)
In-Reply-To: <20261013-set-default-pool-size-v3-2-d36e8c31f9a6@canonical.com>

On Tue, Oct 13, 2026 at 05:01:01PM -0500, Wesley Hershberger wrote:
> If g_file_get_contents fails (AppArmor, etc), use a more conservative
> default max size for the idle coroutine pool.
> 
> This avoids any possibility of the failure described in 86a637e48104
> unless the host kernel is configured with a lower-than-default
> vm.max_map_count.
> 
> This change is motivated by a discussion of backport risk:
> https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/2168803/comments/8
> 
> Fixes: 86a637e48104 ("coroutine: cap per-thread local pool size")
> Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
> Signed-off-by: Wesley Hershberger <wesley.hershberger@canonical.com>
> ---
>  util/qemu-coroutine.c | 75 ++++++++++++++++++++++++++++++++-------------------
>  1 file changed, 48 insertions(+), 27 deletions(-)
> 
> diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
> index 5af61995437..8ced93144fa 100644
> --- a/util/qemu-coroutine.c
> +++ b/util/qemu-coroutine.c
> @@ -361,42 +361,63 @@ void qemu_coroutine_dec_pool_size(unsigned int removing_pool_size)
>      global_pool_max_size -= removing_pool_size;
>  }
>  
> -static unsigned int get_global_pool_hard_max_size(void)
> -{
>  #ifdef __linux__
> -    g_autofree char *contents = NULL;
> -    int max_map_count;
> +/*
> + * include/linux/mm.h
> + */
> +#define DEFAULT_MAX_MAP_COUNT 65530
>  
> -    /*
> -     * Linux processes can have up to max_map_count virtual memory areas
> -     * (VMAs). mmap(2), mprotect(2), etc fail with ENOMEM beyond this limit. We
> -     * must limit the coroutine pool to a safe size to avoid running out of
> -     * VMAs.
> -     */
> -    if (g_file_get_contents("/proc/sys/vm/max_map_count", &contents, NULL,
> -                            NULL)) {
> +static unsigned int get_max_map_count(void)
> +{
> +    g_autofree char *contents = NULL;
> +    int max_map_count = 0;
> +    if (g_file_get_contents("/proc/sys/vm/max_map_count", &contents,
> +                            NULL, NULL)) {
>          /* contents has trailing newline, remove it before conversion */
>          g_strchomp(contents);
> -        if (qemu_strtoi(contents, NULL, 10, &max_map_count) != 0) {
> -            return UINT_MAX;
> -        }
> -        /*
> -         * This is an upper bound that avoids exceeding max_map_count. Leave a
> -         * fixed amount for non-coroutine users like library dependencies,
> -         * vhost-user, etc. Each coroutine takes up 2 VMAs so halve the
> -         * remaining amount.
> -         */
> -        if (max_map_count > 5000) {
> -            return (max_map_count - 5000) / 2;
> -        } else {
> -            /* Disable the global pool but threads still have local pools */
> -            return 0;
> +        if (qemu_strtoi(contents, NULL, 10, &max_map_count) == 0) {
> +            return max_map_count;
>          }
>      }
> -#endif
> +    return 0;
> +}

I'm now realizing we could just return DEFAULT_MAX_MAP_COUNT
here and removed the conditional in the caller.

>  
> +/*
> + * Linux processes can have up to max_map_count virtual memory areas
> + * (VMAs). mmap(2), mprotect(2), etc fail with ENOMEM beyond this limit. We
> + * must limit the coroutine pool to a safe size to avoid running out of
> + * VMAs.
> + */
> +static unsigned int get_global_pool_hard_max_size(void)
> +{
> +    /*
> +     * Read from /proc might fail due to mandatory access control (AppArmor,
> +     * SELinux, etc). Use the kernel's default in that case.
> +     */
> +    int max_map_count = get_max_map_count();
> +    if (!max_map_count) {
> +        max_map_count = DEFAULT_MAX_MAP_COUNT;
> +    }
> +
> +    /*
> +     * This is an upper bound that avoids exceeding max_map_count. Leave a
> +     * fixed amount for non-coroutine users like library dependencies,
> +     * vhost-user, etc. Each coroutine takes up 2 VMAs so halve the
> +     * remaining amount.
> +     */
> +    if (max_map_count > 5000) {
> +        return (max_map_count - 5000) / 2;
> +    } else {
> +        /* Disable the global pool but threads still have local pools */
> +        return 0;
> +    }
> +}
> +#else
> +static unsigned int get_global_pool_hard_max_size(void)
> +{
>      return UINT_MAX;
>  }
> +#endif
>  
>  static void __attribute__((constructor)) qemu_coroutine_init(void)
>  {
> 
> -- 
> 2.53.0
> 

With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|



      reply	other threads:[~2026-10-14  7:51 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 22:00 [PATCH v3 0/2] util/coroutine: Reduce default idle pool max size Wesley Hershberger
2026-10-13 22:01 ` [PATCH v3 1/2] util/coroutine: trim sysctl's max_map_count newline before parsing Wesley Hershberger
2026-10-13 22:01 ` [PATCH v3 2/2] util/coroutine: Reduce default idle pool max size Wesley Hershberger
2026-10-14  7:50   ` Daniel P. Berrangé [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=as80SlXCcNDoLHLj@redhat.com \
    --to=berrange@redhat.com \
    --cc=alex.ramirez@canonical.com \
    --cc=hector.cao@canonical.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=wesley.hershberger@canonical.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.