Patchwork linux-user: Use RLIMIT_STACK for default stack size.

login
register
mail settings
Submitter Richard Henderson
Date March 19, 2010, 9:21 p.m.
Message ID <20100319212255.E3B04A48@are.twiddle.net>
Download mbox | patch
Permalink /patch/48193/
State New
Headers show

Comments

Richard Henderson - March 19, 2010, 9:21 p.m.
The current default stack limit of 512kB is far too small; a fair
number of gcc testsuite failures (for all guests) are directly
attributable to this.  Using the -s option in every invocation of
the emulator is annoying to say the least.

A reasonable compromise seems to be to honor the system rlimit.
At least on two Linux distributions, this is set to 8MB and 10MB
respectively.  If the system does not limit the stack, then we're
no worse off than before.

At the same time, rename the variable from x86_stack_size and
change the ultimate fallback size from 512kB to 8MB.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/elfload.c |    2 +-
 linux-user/main.c    |   23 +++++++++++++++++------
 linux-user/qemu.h    |    2 +-
 3 files changed, 19 insertions(+), 8 deletions(-)
Aurelien Jarno - March 27, 2010, 1:22 p.m.
On Fri, Mar 19, 2010 at 02:21:13PM -0700, Richard Henderson wrote:
> The current default stack limit of 512kB is far too small; a fair
> number of gcc testsuite failures (for all guests) are directly
> attributable to this.  Using the -s option in every invocation of
> the emulator is annoying to say the least.
> 
> A reasonable compromise seems to be to honor the system rlimit.
> At least on two Linux distributions, this is set to 8MB and 10MB
> respectively.  If the system does not limit the stack, then we're
> no worse off than before.
> 
> At the same time, rename the variable from x86_stack_size and
> change the ultimate fallback size from 512kB to 8MB.

Thanks, applied.

> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  linux-user/elfload.c |    2 +-
>  linux-user/main.c    |   23 +++++++++++++++++------
>  linux-user/qemu.h    |    2 +-
>  3 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index 91eea62..b721b10 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -1004,7 +1004,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
>      /* Create enough stack to hold everything.  If we don't use
>       * it for args, we'll use it for something else...
>       */
> -    size = x86_stack_size;
> +    size = guest_stack_size;
>      if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
>          size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
>      error = target_mmap(0,
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 4614e3c..e5ff8a9 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -24,6 +24,7 @@
>  #include <unistd.h>
>  #include <sys/mman.h>
>  #include <sys/syscall.h>
> +#include <sys/resource.h>
>  
>  #include "qemu.h"
>  #include "qemu-common.h"
> @@ -51,7 +52,7 @@ const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
>  /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
>     we allocate a bigger stack. Need a better solution, for example
>     by remapping the process stack directly at the right place */
> -unsigned long x86_stack_size = 512 * 1024;
> +unsigned long guest_stack_size = 8 * 1024 * 1024UL;
>  
>  void gemu_log(const char *fmt, ...)
>  {
> @@ -2560,7 +2561,7 @@ static void usage(void)
>             ,
>             TARGET_ARCH,
>             interp_prefix,
> -           x86_stack_size,
> +           guest_stack_size,
>             DEBUG_LOGFILE);
>      exit(1);
>  }
> @@ -2639,6 +2640,16 @@ int main(int argc, char **argv, char **envp)
>          (void) envlist_setenv(envlist, *wrk);
>      }
>  
> +    /* Read the stack limit from the kernel.  If it's "unlimited",
> +       then we can do little else besides use the default.  */
> +    {
> +        struct rlimit lim;
> +        if (getrlimit(RLIMIT_STACK, &lim) == 0
> +            && lim.rlim_cur != RLIM_INFINITY) {
> +            guest_stack_size = lim.rlim_cur;
> +        }
> +    }
> +
>      cpu_model = NULL;
>  #if defined(cpudef_setup)
>      cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
> @@ -2687,13 +2698,13 @@ int main(int argc, char **argv, char **envp)
>              if (optind >= argc)
>                  break;
>              r = argv[optind++];
> -            x86_stack_size = strtol(r, (char **)&r, 0);
> -            if (x86_stack_size <= 0)
> +            guest_stack_size = strtoul(r, (char **)&r, 0);
> +            if (guest_stack_size == 0)
>                  usage();
>              if (*r == 'M')
> -                x86_stack_size *= 1024 * 1024;
> +                guest_stack_size *= 1024 * 1024;
>              else if (*r == 'k' || *r == 'K')
> -                x86_stack_size *= 1024;
> +                guest_stack_size *= 1024;
>          } else if (!strcmp(r, "L")) {
>              interp_prefix = argv[optind++];
>          } else if (!strcmp(r, "p")) {
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 6ab9517..47fc686 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -246,7 +246,7 @@ void mmap_fork_end(int child);
>  #endif
>  
>  /* main.c */
> -extern unsigned long x86_stack_size;
> +extern unsigned long guest_stack_size;
>  
>  /* user access */
>  
> -- 
> 1.6.6.1
> 
> 
> 
>

Patch

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 91eea62..b721b10 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1004,7 +1004,7 @@  static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
     /* Create enough stack to hold everything.  If we don't use
      * it for args, we'll use it for something else...
      */
-    size = x86_stack_size;
+    size = guest_stack_size;
     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
     error = target_mmap(0,
diff --git a/linux-user/main.c b/linux-user/main.c
index 4614e3c..e5ff8a9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -24,6 +24,7 @@ 
 #include <unistd.h>
 #include <sys/mman.h>
 #include <sys/syscall.h>
+#include <sys/resource.h>
 
 #include "qemu.h"
 #include "qemu-common.h"
@@ -51,7 +52,7 @@  const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
 /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
    we allocate a bigger stack. Need a better solution, for example
    by remapping the process stack directly at the right place */
-unsigned long x86_stack_size = 512 * 1024;
+unsigned long guest_stack_size = 8 * 1024 * 1024UL;
 
 void gemu_log(const char *fmt, ...)
 {
@@ -2560,7 +2561,7 @@  static void usage(void)
            ,
            TARGET_ARCH,
            interp_prefix,
-           x86_stack_size,
+           guest_stack_size,
            DEBUG_LOGFILE);
     exit(1);
 }
@@ -2639,6 +2640,16 @@  int main(int argc, char **argv, char **envp)
         (void) envlist_setenv(envlist, *wrk);
     }
 
+    /* Read the stack limit from the kernel.  If it's "unlimited",
+       then we can do little else besides use the default.  */
+    {
+        struct rlimit lim;
+        if (getrlimit(RLIMIT_STACK, &lim) == 0
+            && lim.rlim_cur != RLIM_INFINITY) {
+            guest_stack_size = lim.rlim_cur;
+        }
+    }
+
     cpu_model = NULL;
 #if defined(cpudef_setup)
     cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
@@ -2687,13 +2698,13 @@  int main(int argc, char **argv, char **envp)
             if (optind >= argc)
                 break;
             r = argv[optind++];
-            x86_stack_size = strtol(r, (char **)&r, 0);
-            if (x86_stack_size <= 0)
+            guest_stack_size = strtoul(r, (char **)&r, 0);
+            if (guest_stack_size == 0)
                 usage();
             if (*r == 'M')
-                x86_stack_size *= 1024 * 1024;
+                guest_stack_size *= 1024 * 1024;
             else if (*r == 'k' || *r == 'K')
-                x86_stack_size *= 1024;
+                guest_stack_size *= 1024;
         } else if (!strcmp(r, "L")) {
             interp_prefix = argv[optind++];
         } else if (!strcmp(r, "p")) {
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 6ab9517..47fc686 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -246,7 +246,7 @@  void mmap_fork_end(int child);
 #endif
 
 /* main.c */
-extern unsigned long x86_stack_size;
+extern unsigned long guest_stack_size;
 
 /* user access */