Module Name:    src
Committed By:   joerg
Date:           Sun Jul  2 16:41:33 UTC 2017

Modified Files:
        src/lib/libpthread: TODO pthread.c pthread_attr.c
            pthread_attr_getguardsize.3 pthread_int.h
        src/sys/kern: exec_subr.c
        src/sys/uvm: uvm_meter.c uvm_param.h
        src/tests/lib/libpthread: t_join.c

Log Message:
Export the guard size of the main thread via vm.guard_size. Add a
complementary writable sysctl for the initial guard size of threads
created via pthread_create. Let the existing attribut accessors do the
right thing. Raise the default guard size for threads to 64KB.


To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/lib/libpthread/TODO
cvs rdiff -u -r1.147 -r1.148 src/lib/libpthread/pthread.c
cvs rdiff -u -r1.16 -r1.17 src/lib/libpthread/pthread_attr.c
cvs rdiff -u -r1.3 -r1.4 src/lib/libpthread/pthread_attr_getguardsize.3
cvs rdiff -u -r1.93 -r1.94 src/lib/libpthread/pthread_int.h
cvs rdiff -u -r1.81 -r1.82 src/sys/kern/exec_subr.c
cvs rdiff -u -r1.65 -r1.66 src/sys/uvm/uvm_meter.c
cvs rdiff -u -r1.36 -r1.37 src/sys/uvm/uvm_param.h
cvs rdiff -u -r1.8 -r1.9 src/tests/lib/libpthread/t_join.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libpthread/TODO
diff -u src/lib/libpthread/TODO:1.18 src/lib/libpthread/TODO:1.19
--- src/lib/libpthread/TODO:1.18	Wed Feb  8 03:44:41 2017
+++ src/lib/libpthread/TODO	Sun Jul  2 16:41:32 2017
@@ -1,13 +1,9 @@
-$NetBSD: TODO,v 1.18 2017/02/08 03:44:41 kamil Exp $
+$NetBSD: TODO,v 1.19 2017/07/02 16:41:32 joerg Exp $
 
 Interfaces/features to implement:
 
 - Realtime extensions: priority inheritance.
 
-- Allow threads to change their stack size.
-
-- Allow threads to modify the red zone size; cf. pthread_attr_setguardsize(3).
-
 - Keep a pool of dead LWPs so that we do not have take the full hit of
   _lwp_create() every time pthread_create() is called.
 

Index: src/lib/libpthread/pthread.c
diff -u src/lib/libpthread/pthread.c:1.147 src/lib/libpthread/pthread.c:1.148
--- src/lib/libpthread/pthread.c:1.147	Fri May 29 16:05:13 2015
+++ src/lib/libpthread/pthread.c	Sun Jul  2 16:41:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread.c,v 1.147 2015/05/29 16:05:13 christos Exp $	*/
+/*	$NetBSD: pthread.c,v 1.148 2017/07/02 16:41:32 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread.c,v 1.147 2015/05/29 16:05:13 christos Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.148 2017/07/02 16:41:32 joerg Exp $");
 
 #define	__EXPOSE_STACK	1
 
@@ -40,7 +40,9 @@ __RCSID("$NetBSD: pthread.c,v 1.147 2015
 #include <sys/lwp.h>
 #include <sys/lwpctl.h>
 #include <sys/resource.h>
+#include <sys/sysctl.h>
 #include <sys/tls.h>
+#include <uvm/uvm_param.h>
 
 #include <assert.h>
 #include <dlfcn.h>
@@ -115,6 +117,7 @@ int pthread__dbg;	/* set by libpthread_d
  * stack pointer to thread data afterwards.
  */
 size_t	pthread__stacksize;
+size_t	pthread__guardsize;
 size_t	pthread__pagesize;
 static struct __pthread_st *pthread__main;
 static size_t __pthread_st_size;
@@ -164,6 +167,9 @@ pthread__init(void)
 	pthread_t first;
 	char *p;
 	int i;
+	int mib[2];
+	unsigned int value;
+	size_t len;
 	extern int __isthreaded;
 
 	/*
@@ -182,6 +188,14 @@ pthread__init(void)
 	pthread__pagesize = (size_t)sysconf(_SC_PAGESIZE);
 	pthread__concurrency = (int)sysconf(_SC_NPROCESSORS_CONF);
 
+	mib[0] = CTL_VM;
+	mib[1] = VM_THREAD_GUARD_SIZE;
+	len = sizeof(value);
+	if (sysctl(mib, __arraycount(mib), &value, &len, NULL, 0) == 0)
+		pthread__guardsize = value;
+	else
+		pthread__guardsize = pthread__pagesize;
+
 	/* Initialize locks first; they're needed elsewhere. */
 	pthread__lockprim_init();
 	for (i = 0; i < NHASHLOCK; i++) {
@@ -335,16 +349,19 @@ pthread__getstack(pthread_t newthread, c
 
 	if (attr != NULL) {
 		pthread_attr_getstack(attr, &stackbase, &stacksize);
+		pthread_attr_getguardsize(attr, &guardsize);
 	} else {
 		stackbase = NULL;
 		stacksize = 0;
+		guardsize = pthread__guardsize;
 	}
 	if (stacksize == 0)
 		stacksize = pthread__stacksize;
 
 	if (newthread->pt_stack_allocated) {
 		if (stackbase == NULL &&
-		    newthread->pt_stack.ss_size == stacksize)
+		    newthread->pt_stack.ss_size == stacksize &&
+		    newthread->pt_guardsize == guardsize)
 			return 0;
 		stackbase2 = newthread->pt_stack.ss_sp;
 #ifndef __MACHINE_STACK_GROWS_UP
@@ -362,14 +379,13 @@ pthread__getstack(pthread_t newthread, c
 
 	if (stackbase == NULL) {
 		stacksize = ((stacksize - 1) | (pthread__pagesize - 1)) + 1;
-		guardsize = pthread__pagesize;
+		guardsize = ((guardsize - 1) | (pthread__pagesize - 1)) + 1;
 		stackbase = mmap(NULL, stacksize + guardsize,
 		    PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, (off_t)0);
 		if (stackbase == MAP_FAILED)
 			return ENOMEM;
 		allocated = true;
 	} else {
-		guardsize = 0;
 		allocated = false;
 	}
 #ifdef __MACHINE_STACK_GROWS_UP
@@ -1280,7 +1296,9 @@ pthread__initmainstack(void)
 {
 	struct rlimit slimit;
 	const AuxInfo *aux;
-	size_t size;
+	size_t size, len;
+	int mib[2];
+	unsigned int value;
 
 	_DIAGASSERT(_dlauxinfo() != NULL);
 
@@ -1289,6 +1307,13 @@ pthread__initmainstack(void)
 		    "Couldn't get stack resource consumption limits");
 	size = slimit.rlim_cur;
 	pthread__main->pt_stack.ss_size = size;
+	pthread__main->pt_guardsize = pthread__pagesize;
+
+	mib[0] = CTL_VM;
+	mib[1] = VM_GUARD_SIZE;
+	len = sizeof(value);
+	if (sysctl(mib, __arraycount(mib), &value, &len, NULL, 0) == 0)
+		pthread__main->pt_guardsize = value;
 
 	for (aux = _dlauxinfo(); aux->a_type != AT_NULL; ++aux) {
 		if (aux->a_type == AT_STACKBASE) {

Index: src/lib/libpthread/pthread_attr.c
diff -u src/lib/libpthread/pthread_attr.c:1.16 src/lib/libpthread/pthread_attr.c:1.17
--- src/lib/libpthread/pthread_attr.c:1.16	Fri Mar  2 18:06:05 2012
+++ src/lib/libpthread/pthread_attr.c	Sun Jul  2 16:41:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_attr.c,v 1.16 2012/03/02 18:06:05 joerg Exp $	*/
+/*	$NetBSD: pthread_attr.c,v 1.17 2017/07/02 16:41:32 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_attr.c,v 1.16 2012/03/02 18:06:05 joerg Exp $");
+__RCSID("$NetBSD: pthread_attr.c,v 1.17 2017/07/02 16:41:32 joerg Exp $");
 
 #include <errno.h>
 #include <stdio.h>
@@ -107,7 +107,7 @@ pthread_attr_get_np(pthread_t thread, pt
 	p->ptap_namearg = thread->pt_name;
 	p->ptap_stackaddr = thread->pt_stack.ss_sp;
 	p->ptap_stacksize = thread->pt_stack.ss_size;
-	p->ptap_guardsize = pthread__pagesize;
+	p->ptap_guardsize = thread->pt_guardsize;
 	return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp);
 }
 
@@ -150,7 +150,7 @@ pthread_attr_getguardsize(const pthread_
 	struct pthread_attr_private *p;
 
 	if ((p = attr->pta_private) == NULL)
-		*guard = (size_t)sysconf(_SC_PAGESIZE);
+		*guard = pthread__guardsize;
 	else
 		*guard = p->ptap_guardsize;
 

Index: src/lib/libpthread/pthread_attr_getguardsize.3
diff -u src/lib/libpthread/pthread_attr_getguardsize.3:1.3 src/lib/libpthread/pthread_attr_getguardsize.3:1.4
--- src/lib/libpthread/pthread_attr_getguardsize.3:1.3	Thu Apr  7 06:21:48 2016
+++ src/lib/libpthread/pthread_attr_getguardsize.3	Sun Jul  2 16:41:32 2017
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pthread_attr_getguardsize.3,v 1.3 2016/04/07 06:21:48 dholland Exp $
+.\"	$NetBSD: pthread_attr_getguardsize.3,v 1.4 2017/07/02 16:41:32 joerg Exp $
 .\"
 .\" Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi>
 .\" All rights reserved.
@@ -25,7 +25,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd July 7, 2010
+.Dd July 2, 2017
 .Dt PTHREAD_ATTR_GETGUARDSIZE 3
 .Os
 .Sh NAME
@@ -66,12 +66,9 @@ In
 .Nx
 the default
 .Fa guardsize
-is the system page size.
-(This value is often 4096 bytes but varies on some ports; the
-precise value can be retrieved by using
-.Xr sysconf 3
-with
-.Dv _SC_PAGESIZE . )
+is given by the
+.Pa vm.thread_guard_size
+.Xr sysctl 7 .
 .Pp
 The rationale behind
 .Fa guardsize

Index: src/lib/libpthread/pthread_int.h
diff -u src/lib/libpthread/pthread_int.h:1.93 src/lib/libpthread/pthread_int.h:1.94
--- src/lib/libpthread/pthread_int.h:1.93	Wed Feb  8 03:44:41 2017
+++ src/lib/libpthread/pthread_int.h	Sun Jul  2 16:41:32 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_int.h,v 1.93 2017/02/08 03:44:41 kamil Exp $	*/
+/*	$NetBSD: pthread_int.h,v 1.94 2017/07/02 16:41:32 joerg Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -171,6 +171,7 @@ struct	__pthread_st {
 #define PT_ATTR_DEAD	0xDEAD0002
 
 extern size_t	pthread__stacksize;
+extern size_t	pthread__guardsize;
 extern size_t	pthread__pagesize;
 extern int	pthread__nspins;
 extern int	pthread__concurrency;

Index: src/sys/kern/exec_subr.c
diff -u src/sys/kern/exec_subr.c:1.81 src/sys/kern/exec_subr.c:1.82
--- src/sys/kern/exec_subr.c:1.81	Fri Jun 23 21:28:38 2017
+++ src/sys/kern/exec_subr.c	Sun Jul  2 16:41:33 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec_subr.c,v 1.81 2017/06/23 21:28:38 joerg Exp $	*/
+/*	$NetBSD: exec_subr.c,v 1.82 2017/07/02 16:41:33 joerg Exp $	*/
 
 /*
  * Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exec_subr.c,v 1.81 2017/06/23 21:28:38 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exec_subr.c,v 1.82 2017/07/02 16:41:33 joerg Exp $");
 
 #include "opt_pax.h"
 
@@ -67,7 +67,8 @@ VMCMD_EVCNT_DECL(kills);
 #define DPRINTF(a)
 #endif
 
-uint32_t user_stack_guard_size = 1024 * 1024;
+unsigned int user_stack_guard_size = 1024 * 1024;
+unsigned int user_thread_stack_guard_size = 64 * 1024;
 
 /*
  * new_vmcmd():

Index: src/sys/uvm/uvm_meter.c
diff -u src/sys/uvm/uvm_meter.c:1.65 src/sys/uvm/uvm_meter.c:1.66
--- src/sys/uvm/uvm_meter.c:1.65	Mon Dec  1 04:11:14 2014
+++ src/sys/uvm/uvm_meter.c	Sun Jul  2 16:41:33 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_meter.c,v 1.65 2014/12/01 04:11:14 msaitoh Exp $	*/
+/*	$NetBSD: uvm_meter.c,v 1.66 2017/07/02 16:41:33 joerg Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_meter.c,v 1.65 2014/12/01 04:11:14 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_meter.c,v 1.66 2017/07/02 16:41:33 joerg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -281,6 +281,18 @@ SYSCTL_SETUP(sysctl_vm_setup, "sysctl vm
 		       SYSCTL_DESCR("Maximum user address"),
 		       NULL, VM_MAX_ADDRESS, NULL, 0,
 		       CTL_VM, VM_MAXADDRESS, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_UNSIGNED,
+		       CTLTYPE_INT, "guard_size",
+		       SYSCTL_DESCR("Guard size of main thread"),
+		       NULL, 0, &user_stack_guard_size, 0,
+		       CTL_VM, VM_GUARD_SIZE, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_UNSIGNED|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "thread_guard_size",
+		       SYSCTL_DESCR("Guard size of other threads"),
+		       NULL, 0, &user_thread_stack_guard_size, 0,
+		       CTL_VM, VM_THREAD_GUARD_SIZE, CTL_EOL);
 
 	uvmpdpol_sysctlsetup();
 }

Index: src/sys/uvm/uvm_param.h
diff -u src/sys/uvm/uvm_param.h:1.36 src/sys/uvm/uvm_param.h:1.37
--- src/sys/uvm/uvm_param.h:1.36	Fri Jun 23 21:28:39 2017
+++ src/sys/uvm/uvm_param.h	Sun Jul  2 16:41:33 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_param.h,v 1.36 2017/06/23 21:28:39 joerg Exp $	*/
+/*	$NetBSD: uvm_param.h,v 1.37 2017/07/02 16:41:33 joerg Exp $	*/
 
 /*
  * Copyright (c) 1991, 1993
@@ -178,6 +178,8 @@ extern const int *const uvmexp_pageshift
 #define	VM_MINADDRESS	14
 #define	VM_MAXADDRESS	15
 #define	VM_PROC		16		/* process information */
+#define	VM_GUARD_SIZE	17		/* guard size for main thread */
+#define	VM_THREAD_GUARD_SIZE	18	/* default guard size for new threads */
 
 #define	VM_MAXID	17		/* number of valid vm ids */
 
@@ -201,6 +203,8 @@ extern const int *const uvmexp_pageshift
 	{ "minaddress", CTLTYPE_LONG }, \
 	{ "maxaddress", CTLTYPE_LONG }, \
 	{ "proc", CTLTYPE_STRUCT }, \
+	{ "guard_size", CTLTYPE_INT }, \
+	{ "thread_guard_size", CTLTYPE_INT }, \
 }
 
 #ifndef ASSEMBLER
@@ -224,7 +228,8 @@ extern const int *const uvmexp_pageshift
     round_page((vaddr_t)(da) + (vsize_t)maxdmap)
 #endif
 
-extern uint32_t user_stack_guard_size;
+extern unsigned int user_stack_guard_size;
+extern unsigned int user_thread_stack_guard_size;
 #ifndef VM_DEFAULT_ADDRESS_TOPDOWN
 #define VM_DEFAULT_ADDRESS_TOPDOWN(da, sz) \
     trunc_page(VM_MAXUSER_ADDRESS - MAXSSIZ - (sz) - user_stack_guard_size)

Index: src/tests/lib/libpthread/t_join.c
diff -u src/tests/lib/libpthread/t_join.c:1.8 src/tests/lib/libpthread/t_join.c:1.9
--- src/tests/lib/libpthread/t_join.c:1.8	Mon Mar 12 20:17:16 2012
+++ src/tests/lib/libpthread/t_join.c	Sun Jul  2 16:41:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $ */
+/* $NetBSD: t_join.c,v 1.9 2017/07/02 16:41:33 joerg Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $");
+__RCSID("$NetBSD: t_join.c,v 1.9 2017/07/02 16:41:33 joerg Exp $");
 
 #include <errno.h>
 #include <pthread.h>
@@ -104,6 +104,7 @@ threadfunc1(void *arg)
 		error = true;
 
 		ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0);
+		ATF_REQUIRE(pthread_attr_setguardsize(&attr, STACKSIZE * (i + 2)) == 0);
 
 		rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i);
 
@@ -148,13 +149,15 @@ threadfunc2(void *arg)
 	static uintptr_t i = 0;
 	uintptr_t j;
 	pthread_attr_t attr;
-	size_t stacksize;
+	size_t stacksize, guardsize;
 
 	j = (uintptr_t)arg;
 
 	ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0);
 	ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0);
 	ATF_REQUIRE(stacksize == STACKSIZE * (j + 1));
+	ATF_REQUIRE(pthread_attr_getguardsize(&attr, &guardsize) == 0);
+	ATF_REQUIRE(guardsize == STACKSIZE * (j + 2));
 	ATF_REQUIRE(pthread_attr_destroy(&attr) == 0);
 
 	if (i++ == j)

Reply via email to