musl: pick stacksize-related improvements, increase default size
Also supports setting default thread stack size via linker, making it possible to fix programs without modifying source.
This commit is contained in:
parent
dcd5e4558f
commit
f38218a756
@ -72,6 +72,11 @@ stdenv.mkDerivation rec {
|
|||||||
# name_to_handle_at
|
# name_to_handle_at
|
||||||
./name-to-handle-at.patch
|
./name-to-handle-at.patch
|
||||||
./max-handle-sz-for-name-to-handle-at.patch
|
./max-handle-sz-for-name-to-handle-at.patch
|
||||||
|
# Upstream improvements regarding stack size, incl size increase
|
||||||
|
./stacksize-0001.patch
|
||||||
|
./stacksize-0002.patch
|
||||||
|
./stacksize-0003.patch
|
||||||
|
./stacksize-0004.patch
|
||||||
];
|
];
|
||||||
preConfigure = ''
|
preConfigure = ''
|
||||||
configureFlagsArray+=("--syslibdir=$out/lib")
|
configureFlagsArray+=("--syslibdir=$out/lib")
|
||||||
|
56
pkgs/os-specific/linux/musl/stacksize-0001.patch
Normal file
56
pkgs/os-specific/linux/musl/stacksize-0001.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
From c7ed3e909a69d34a7821f7db644c2fa590a1a690 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rich Felker <dalias@aerifal.cx>
|
||||||
|
Date: Tue, 18 Sep 2018 19:43:52 -0400
|
||||||
|
Subject: [PATCH 1/4] remove redundant declarations of __default_stacksize,
|
||||||
|
__default_guardsize
|
||||||
|
|
||||||
|
these are now declared in pthread_impl.h.
|
||||||
|
---
|
||||||
|
src/thread/pthread_attr_init.c | 3 ---
|
||||||
|
src/thread/pthread_create.c | 2 --
|
||||||
|
src/thread/pthread_setattr_default_np.c | 3 ---
|
||||||
|
3 files changed, 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/thread/pthread_attr_init.c b/src/thread/pthread_attr_init.c
|
||||||
|
index 398990d1..463a8d20 100644
|
||||||
|
--- a/src/thread/pthread_attr_init.c
|
||||||
|
+++ b/src/thread/pthread_attr_init.c
|
||||||
|
@@ -1,8 +1,5 @@
|
||||||
|
#include "pthread_impl.h"
|
||||||
|
|
||||||
|
-extern size_t __default_stacksize;
|
||||||
|
-extern size_t __default_guardsize;
|
||||||
|
-
|
||||||
|
int pthread_attr_init(pthread_attr_t *a)
|
||||||
|
{
|
||||||
|
*a = (pthread_attr_t){0};
|
||||||
|
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
|
||||||
|
index 3293dcd5..3da7db14 100644
|
||||||
|
--- a/src/thread/pthread_create.c
|
||||||
|
+++ b/src/thread/pthread_create.c
|
||||||
|
@@ -162,8 +162,6 @@ static void *dummy_tsd[1] = { 0 };
|
||||||
|
weak_alias(dummy_tsd, __pthread_tsd_main);
|
||||||
|
|
||||||
|
volatile int __block_new_threads = 0;
|
||||||
|
-extern size_t __default_stacksize;
|
||||||
|
-extern size_t __default_guardsize;
|
||||||
|
|
||||||
|
static FILE *volatile dummy_file = 0;
|
||||||
|
weak_alias(dummy_file, __stdin_used);
|
||||||
|
diff --git a/src/thread/pthread_setattr_default_np.c b/src/thread/pthread_setattr_default_np.c
|
||||||
|
index 88503e34..256f0685 100644
|
||||||
|
--- a/src/thread/pthread_setattr_default_np.c
|
||||||
|
+++ b/src/thread/pthread_setattr_default_np.c
|
||||||
|
@@ -2,9 +2,6 @@
|
||||||
|
#include "pthread_impl.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
-extern size_t __default_stacksize;
|
||||||
|
-extern size_t __default_guardsize;
|
||||||
|
-
|
||||||
|
int pthread_setattr_default_np(const pthread_attr_t *attrp)
|
||||||
|
{
|
||||||
|
/* Reject anything in the attr object other than stack/guard size. */
|
||||||
|
--
|
||||||
|
2.19.0
|
||||||
|
|
86
pkgs/os-specific/linux/musl/stacksize-0002.patch
Normal file
86
pkgs/os-specific/linux/musl/stacksize-0002.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
From 792f32772e64a32527cd455ebfa087ef434a6f4f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rich Felker <dalias@aerifal.cx>
|
||||||
|
Date: Tue, 18 Sep 2018 23:06:50 -0400
|
||||||
|
Subject: [PATCH 2/4] limit the configurable default stack/guard size for
|
||||||
|
threads
|
||||||
|
|
||||||
|
limit to 8MB/1MB, repectively. since the defaults cannot be reduced
|
||||||
|
once increased, excessively large settings would lead to an
|
||||||
|
unrecoverably broken state. this change is in preparation to allow
|
||||||
|
defaults to be increased via program headers at the linker level.
|
||||||
|
|
||||||
|
creation of threads that really need larger sizes needs to be done
|
||||||
|
with an explicit attribute.
|
||||||
|
---
|
||||||
|
src/internal/pthread_impl.h | 7 +++++--
|
||||||
|
src/thread/default_attr.c | 4 ++--
|
||||||
|
src/thread/pthread_setattr_default_np.c | 12 ++++++++----
|
||||||
|
3 files changed, 15 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
|
||||||
|
index 26e6e1df..e73a251f 100644
|
||||||
|
--- a/src/internal/pthread_impl.h
|
||||||
|
+++ b/src/internal/pthread_impl.h
|
||||||
|
@@ -182,12 +182,15 @@ hidden void __acquire_ptc(void);
|
||||||
|
hidden void __release_ptc(void);
|
||||||
|
hidden void __inhibit_ptc(void);
|
||||||
|
|
||||||
|
-extern hidden size_t __default_stacksize;
|
||||||
|
-extern hidden size_t __default_guardsize;
|
||||||
|
+extern hidden unsigned __default_stacksize;
|
||||||
|
+extern hidden unsigned __default_guardsize;
|
||||||
|
|
||||||
|
#define DEFAULT_STACK_SIZE 81920
|
||||||
|
#define DEFAULT_GUARD_SIZE 4096
|
||||||
|
|
||||||
|
+#define DEFAULT_STACK_MAX (8<<20)
|
||||||
|
+#define DEFAULT_GUARD_MAX (1<<20)
|
||||||
|
+
|
||||||
|
#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
diff --git a/src/thread/default_attr.c b/src/thread/default_attr.c
|
||||||
|
index 46fe98ee..dce96409 100644
|
||||||
|
--- a/src/thread/default_attr.c
|
||||||
|
+++ b/src/thread/default_attr.c
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
#include "pthread_impl.h"
|
||||||
|
|
||||||
|
-size_t __default_stacksize = DEFAULT_STACK_SIZE;
|
||||||
|
-size_t __default_guardsize = DEFAULT_GUARD_SIZE;
|
||||||
|
+unsigned __default_stacksize = DEFAULT_STACK_SIZE;
|
||||||
|
+unsigned __default_guardsize = DEFAULT_GUARD_SIZE;
|
||||||
|
diff --git a/src/thread/pthread_setattr_default_np.c b/src/thread/pthread_setattr_default_np.c
|
||||||
|
index 256f0685..58486220 100644
|
||||||
|
--- a/src/thread/pthread_setattr_default_np.c
|
||||||
|
+++ b/src/thread/pthread_setattr_default_np.c
|
||||||
|
@@ -2,6 +2,9 @@
|
||||||
|
#include "pthread_impl.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
|
||||||
|
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
|
||||||
|
+
|
||||||
|
int pthread_setattr_default_np(const pthread_attr_t *attrp)
|
||||||
|
{
|
||||||
|
/* Reject anything in the attr object other than stack/guard size. */
|
||||||
|
@@ -11,11 +14,12 @@ int pthread_setattr_default_np(const pthread_attr_t *attrp)
|
||||||
|
if (memcmp(&tmp, &zero, sizeof tmp))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
+ unsigned stack = MIN(attrp->_a_stacksize, DEFAULT_STACK_MAX);
|
||||||
|
+ unsigned guard = MIN(attrp->_a_guardsize, DEFAULT_GUARD_MAX);
|
||||||
|
+
|
||||||
|
__inhibit_ptc();
|
||||||
|
- if (attrp->_a_stacksize >= __default_stacksize)
|
||||||
|
- __default_stacksize = attrp->_a_stacksize;
|
||||||
|
- if (attrp->_a_guardsize >= __default_guardsize)
|
||||||
|
- __default_guardsize = attrp->_a_guardsize;
|
||||||
|
+ __default_stacksize = MAX(__default_stacksize, stack);
|
||||||
|
+ __default_guardsize = MAX(__default_guardsize, guard);
|
||||||
|
__release_ptc();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
--
|
||||||
|
2.19.0
|
||||||
|
|
36
pkgs/os-specific/linux/musl/stacksize-0003.patch
Normal file
36
pkgs/os-specific/linux/musl/stacksize-0003.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From c0058ab465e950c2c3302d2b62e21cc0b494224b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rich Felker <dalias@aerifal.cx>
|
||||||
|
Date: Tue, 18 Sep 2018 23:11:49 -0400
|
||||||
|
Subject: [PATCH 3/4] increase default thread stack/guard size
|
||||||
|
|
||||||
|
stack size default is increased from 80k to 128k. this coincides with
|
||||||
|
Linux's hard-coded default stack for the main thread (128k is
|
||||||
|
initially committed; growth beyond that up to ulimit is contingent on
|
||||||
|
additional allocation succeeding) and GNU ld's default PT_GNU_STACK
|
||||||
|
size for FDPIC, at least on sh.
|
||||||
|
|
||||||
|
guard size default is increased from 4k to 8k to reduce the risk of
|
||||||
|
guard page jumping on overflow, since use of just over 4k of stack is
|
||||||
|
common (PATH_MAX buffers, etc.).
|
||||||
|
---
|
||||||
|
src/internal/pthread_impl.h | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
|
||||||
|
index e73a251f..d491f975 100644
|
||||||
|
--- a/src/internal/pthread_impl.h
|
||||||
|
+++ b/src/internal/pthread_impl.h
|
||||||
|
@@ -185,8 +185,8 @@ hidden void __inhibit_ptc(void);
|
||||||
|
extern hidden unsigned __default_stacksize;
|
||||||
|
extern hidden unsigned __default_guardsize;
|
||||||
|
|
||||||
|
-#define DEFAULT_STACK_SIZE 81920
|
||||||
|
-#define DEFAULT_GUARD_SIZE 4096
|
||||||
|
+#define DEFAULT_STACK_SIZE 131072
|
||||||
|
+#define DEFAULT_GUARD_SIZE 8192
|
||||||
|
|
||||||
|
#define DEFAULT_STACK_MAX (8<<20)
|
||||||
|
#define DEFAULT_GUARD_MAX (1<<20)
|
||||||
|
--
|
||||||
|
2.19.0
|
||||||
|
|
81
pkgs/os-specific/linux/musl/stacksize-0004.patch
Normal file
81
pkgs/os-specific/linux/musl/stacksize-0004.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
From 7b3348a98c139b4b4238384e52d4b0eb237e4833 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rich Felker <dalias@aerifal.cx>
|
||||||
|
Date: Tue, 18 Sep 2018 23:54:18 -0400
|
||||||
|
Subject: [PATCH 4/4] support setting of default thread stack size via
|
||||||
|
PT_GNU_STACK header
|
||||||
|
|
||||||
|
this facilitates building software that assumes a large default stack
|
||||||
|
size without any patching to call pthread_setattr_default_np or
|
||||||
|
pthread_attr_setstacksize at each thread creation site, using just
|
||||||
|
LDFLAGS.
|
||||||
|
|
||||||
|
normally the PT_GNU_STACK header is used only to reflect whether
|
||||||
|
executable stack is desired, but with GNU ld at least, passing
|
||||||
|
-Wl,-z,stack-size=N will set a size on the program header. with this
|
||||||
|
patch, that size will be incorporated into the default stack size
|
||||||
|
(subject to increase-only rule and DEFAULT_STACK_MAX limit).
|
||||||
|
|
||||||
|
both static and dynamic linking honor the program header. for dynamic
|
||||||
|
linking, all libraries loaded at program start, including preloaded
|
||||||
|
ones, are considered. dlopened libraries are not considered, for
|
||||||
|
several reasons. extra logic would be needed to defer processing until
|
||||||
|
the load of the new library is commited, synchronization woud be
|
||||||
|
needed since other threads may be running concurrently, and the
|
||||||
|
effectiveness woud be limited since the larger size would not apply to
|
||||||
|
threads that already existed at the time of dlopen. programs that will
|
||||||
|
dlopen code expecting a large stack need to declare the requirement
|
||||||
|
themselves, or pthread_setattr_default_np can be used.
|
||||||
|
---
|
||||||
|
ldso/dynlink.c | 12 ++++++++++++
|
||||||
|
src/env/__init_tls.c | 5 +++++
|
||||||
|
2 files changed, 17 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
|
||||||
|
index e4829c3a..3ecbddfa 100644
|
||||||
|
--- a/ldso/dynlink.c
|
||||||
|
+++ b/ldso/dynlink.c
|
||||||
|
@@ -609,6 +609,12 @@ static void *map_library(int fd, struct dso *dso)
|
||||||
|
} else if (ph->p_type == PT_GNU_RELRO) {
|
||||||
|
dso->relro_start = ph->p_vaddr & -PAGE_SIZE;
|
||||||
|
dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
|
||||||
|
+ } else if (ph->p_type == PT_GNU_STACK) {
|
||||||
|
+ if (!runtime && ph->p_memsz > __default_stacksize) {
|
||||||
|
+ __default_stacksize =
|
||||||
|
+ ph->p_memsz < DEFAULT_STACK_MAX ?
|
||||||
|
+ ph->p_memsz : DEFAULT_STACK_MAX;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (ph->p_type != PT_LOAD) continue;
|
||||||
|
nsegs++;
|
||||||
|
@@ -1238,6 +1244,12 @@ static void kernel_mapped_dso(struct dso *p)
|
||||||
|
} else if (ph->p_type == PT_GNU_RELRO) {
|
||||||
|
p->relro_start = ph->p_vaddr & -PAGE_SIZE;
|
||||||
|
p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE;
|
||||||
|
+ } else if (ph->p_type == PT_GNU_STACK) {
|
||||||
|
+ if (!runtime && ph->p_memsz > __default_stacksize) {
|
||||||
|
+ __default_stacksize =
|
||||||
|
+ ph->p_memsz < DEFAULT_STACK_MAX ?
|
||||||
|
+ ph->p_memsz : DEFAULT_STACK_MAX;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (ph->p_type != PT_LOAD) continue;
|
||||||
|
if (ph->p_vaddr < min_addr)
|
||||||
|
diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
|
||||||
|
index e0224243..96d0e284 100644
|
||||||
|
--- a/src/env/__init_tls.c
|
||||||
|
+++ b/src/env/__init_tls.c
|
||||||
|
@@ -90,6 +90,11 @@ static void static_init_tls(size_t *aux)
|
||||||
|
base = (size_t)_DYNAMIC - phdr->p_vaddr;
|
||||||
|
if (phdr->p_type == PT_TLS)
|
||||||
|
tls_phdr = phdr;
|
||||||
|
+ if (phdr->p_type == PT_GNU_STACK &&
|
||||||
|
+ phdr->p_memsz > __default_stacksize)
|
||||||
|
+ __default_stacksize =
|
||||||
|
+ phdr->p_memsz < DEFAULT_STACK_MAX ?
|
||||||
|
+ phdr->p_memsz : DEFAULT_STACK_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tls_phdr) {
|
||||||
|
--
|
||||||
|
2.19.0
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user