Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144458054
D36540.id110529.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D36540.id110529.diff
View Options
Index: contrib/jemalloc/src/pages.c
===================================================================
--- contrib/jemalloc/src/pages.c
+++ contrib/jemalloc/src/pages.c
@@ -12,6 +12,7 @@
#include <sys/sysctl.h>
#ifdef __FreeBSD__
#include <vm/vm_param.h>
+#include <sys/auxv.h>
#endif
#endif
@@ -437,9 +438,14 @@
#ifdef JEMALLOC_SYSCTL_VM_OVERCOMMIT
static bool
os_overcommits_sysctl(void) {
- int vm_overcommit;
+ int vm_overcommit, bsdflags;
size_t sz;
+#ifdef ELF_BSDF_VMNOOVERCOMMIT
+ if (_elf_aux_info(AT_BSDFLAGS, &bsdflags, sizeof(bsdflags)) == 0)
+ return ((bsdflags & ELF_BSDF_VMNOOVERCOMMIT) == 0);
+#endif
+
sz = sizeof(vm_overcommit);
#if defined(__FreeBSD__) && defined(VM_OVERCOMMIT)
int mib[2];
Index: lib/libc/gen/auxv.c
===================================================================
--- lib/libc/gen/auxv.c
+++ lib/libc/gen/auxv.c
@@ -73,6 +73,7 @@
static void *ps_strings, *timekeep;
static u_long hwcap, hwcap2;
static void *fxrng_seed_version;
+static u_long usrstackbase, usrstacklim;
#ifdef __powerpc__
static int powerpc_new_auxv_format = 0;
@@ -144,6 +145,14 @@
case AT_FXRNG:
fxrng_seed_version = aux->a_un.a_ptr;
break;
+
+ case AT_USRSTACKBASE:
+ usrstackbase = aux->a_un.a_val;
+ break;
+
+ case AT_USRSTACKLIM:
+ usrstacklim = aux->a_un.a_val;
+ break;
#ifdef __powerpc__
/*
* Since AT_STACKPROT is always set, and the common
@@ -370,6 +379,20 @@
} else
res = EINVAL;
break;
+ case AT_USRSTACKBASE:
+ if (buflen == sizeof(u_long)) {
+ *(u_long *)buf = usrstackbase;
+ res = 0;
+ } else
+ res = EINVAL;
+ break;
+ case AT_USRSTACKLIM:
+ if (buflen == sizeof(u_long)) {
+ *(u_long *)buf = usrstacklim;
+ res = 0;
+ } else
+ res = EINVAL;
+ break;
default:
res = ENOENT;
break;
Index: lib/libc/gen/elf_utils.c
===================================================================
--- lib/libc/gen/elf_utils.c
+++ lib/libc/gen/elf_utils.c
@@ -28,7 +28,8 @@
* $FreeBSD$
*/
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
@@ -77,19 +78,23 @@
{
int mib[2];
struct rlimit rlim;
- u_long usrstack;
+ u_long usrstack, stacksz;
size_t len;
- mib[0] = CTL_KERN;
- mib[1] = KERN_USRSTACK;
- len = sizeof(usrstack);
- if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0)
- == -1)
- return;
- if (getrlimit(RLIMIT_STACK, &rlim) == -1)
- return;
- mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur),
- rlim.rlim_cur, _rtld_get_stack_prot());
+ if (_elf_aux_info(AT_USRSTACKBASE, &usrstack, sizeof(usrstack)) != 0) {
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_USRSTACK;
+ len = sizeof(usrstack);
+ if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1)
+ return;
+ }
+ if (_elf_aux_info(AT_USRSTACKLIM, &stacksz, sizeof(stacksz)) != 0) {
+ if (getrlimit(RLIMIT_STACK, &rlim) == -1)
+ return;
+ stacksz = rlim.rlim_cur;
+ }
+ mprotect((void *)(uintptr_t)(usrstack - stacksz), stacksz,
+ _rtld_get_stack_prot());
}
#pragma weak __pthread_map_stacks_exec
Index: lib/libthr/thread/thr_init.c
===================================================================
--- lib/libthr/thread/thr_init.c
+++ lib/libthr/thread/thr_init.c
@@ -37,7 +37,8 @@
__FBSDID("$FreeBSD$");
#include "namespace.h"
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/auxv.h>
#include <sys/signalvar.h>
#include <sys/ioctl.h>
#include <sys/link_elf.h>
@@ -433,12 +434,43 @@
/* Others cleared to zero by thr_alloc() */
}
-static void
-init_private(void)
+bool
+__thr_get_main_stack_base(char **base)
{
- struct rlimit rlim;
size_t len;
int mib[2];
+
+ if (elf_aux_info(AT_USRSTACKBASE, base, sizeof(*base)) == 0)
+ return (true);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_USRSTACK;
+ len = sizeof(*base);
+ if (sysctl(mib, nitems(mib), base, &len, NULL, 0) == 0)
+ return (true);
+
+ return (false);
+}
+
+bool
+__thr_get_main_stack_lim(size_t *lim)
+{
+ struct rlimit rlim;
+
+ if (elf_aux_info(AT_USRSTACKLIM, lim, sizeof(*lim)) == 0)
+ return (true);
+
+ if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
+ *lim = rlim.rlim_cur;
+ return (true);
+ }
+
+ return (false);
+}
+
+static void
+init_private(void)
+{
char *env, *env_bigstack, *env_splitstack;
_thr_umutex_init(&_mutex_static_lock);
@@ -462,18 +494,15 @@
if (init_once == 0) {
__thr_pshared_init();
__thr_malloc_init();
+
/* Find the stack top */
- mib[0] = CTL_KERN;
- mib[1] = KERN_USRSTACK;
- len = sizeof (_usrstack);
- if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
- PANIC("Cannot get kern.usrstack from sysctl");
+ if (!__thr_get_main_stack_base(&_usrstack))
+ PANIC("Cannot get kern.usrstack");
env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN");
env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN");
if (env_bigstack != NULL || env_splitstack == NULL) {
- if (getrlimit(RLIMIT_STACK, &rlim) == -1)
+ if (!__thr_get_main_stack_lim(&_thr_stack_initial))
PANIC("Cannot get stack rlimit");
- _thr_stack_initial = rlim.rlim_cur;
}
_thr_is_smp = sysconf(_SC_NPROCESSORS_CONF);
if (_thr_is_smp == -1)
Index: lib/libthr/thread/thr_private.h
===================================================================
--- lib/libthr/thread/thr_private.h
+++ lib/libthr/thread/thr_private.h
@@ -1102,6 +1102,8 @@
int _thr_mutex_unlock(pthread_mutex_t *);
int __Tthr_mutex_lock(pthread_mutex_t *);
int __Tthr_mutex_trylock(pthread_mutex_t *);
+bool __thr_get_main_stack_base(char **base);
+bool __thr_get_main_stack_lim(size_t *lim);
__END_DECLS
__NULLABILITY_PRAGMA_POP
Index: lib/libthr/thread/thr_stack.c
===================================================================
--- lib/libthr/thread/thr_stack.c
+++ lib/libthr/thread/thr_stack.c
@@ -30,7 +30,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/queue.h>
#include <sys/resource.h>
@@ -147,21 +148,13 @@
static void
singlethread_map_stacks_exec(void)
{
- int mib[2];
- struct rlimit rlim;
- u_long usrstack;
- size_t len;
+ char *usrstack;
+ size_t stacksz;
- mib[0] = CTL_KERN;
- mib[1] = KERN_USRSTACK;
- len = sizeof(usrstack);
- if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0)
- == -1)
+ if (!__thr_get_main_stack_base(&usrstack) ||
+ !__thr_get_main_stack_lim(&stacksz))
return;
- if (getrlimit(RLIMIT_STACK, &rlim) == -1)
- return;
- mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur),
- rlim.rlim_cur, _rtld_get_stack_prot());
+ mprotect(usrstack - stacksz, stacksz, _rtld_get_stack_prot());
}
void
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -1448,7 +1448,8 @@
Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
Elf_Auxinfo *argarray, *pos;
struct vmspace *vmspace;
- int error;
+ rlim_t stacksz;
+ int error, bsdflags, oc;
argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
@@ -1489,8 +1490,12 @@
AUXARGS_ENTRY(pos, AT_HWCAP, *imgp->sysent->sv_hwcap);
if (imgp->sysent->sv_hwcap2 != NULL)
AUXARGS_ENTRY(pos, AT_HWCAP2, *imgp->sysent->sv_hwcap2);
- AUXARGS_ENTRY(pos, AT_BSDFLAGS, __elfN(sigfastblock) ?
- ELF_BSDF_SIGFASTBLK : 0);
+ bsdflags = 0;
+ bsdflags |= __elfN(sigfastblock) ? ELF_BSDF_SIGFASTBLK : 0;
+ oc = atomic_load_int(&vm_overcommit);
+ bsdflags |= (oc & (SWAP_RESERVE_FORCE_ON | SWAP_RESERVE_RLIMIT_ON)) !=
+ 0 ? ELF_BSDF_VMNOOVERCOMMIT : 0;
+ AUXARGS_ENTRY(pos, AT_BSDFLAGS, bsdflags);
AUXARGS_ENTRY(pos, AT_ARGC, imgp->args->argc);
AUXARGS_ENTRY_PTR(pos, AT_ARGV, imgp->argv);
AUXARGS_ENTRY(pos, AT_ENVC, imgp->args->envc);
@@ -1506,6 +1511,9 @@
AUXARGS_ENTRY(pos, AT_KPRELOAD,
vmspace->vm_shp_base + imgp->sysent->sv_vdso_offset);
}
+ AUXARGS_ENTRY(pos, AT_USRSTACKBASE, round_page(vmspace->vm_stacktop));
+ stacksz = imgp->proc->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur;
+ AUXARGS_ENTRY(pos, AT_USRSTACKLIM, stacksz);
AUXARGS_ENTRY(pos, AT_NULL, 0);
free(imgp->auxargs, M_TEMP);
Index: sys/sys/elf_common.h
===================================================================
--- sys/sys/elf_common.h
+++ sys/sys/elf_common.h
@@ -986,8 +986,10 @@
#define AT_PS_STRINGS 32 /* struct ps_strings */
#define AT_FXRNG 33 /* Pointer to root RNG seed version. */
#define AT_KPRELOAD 34 /* Base of vdso, preloaded by rtld */
+#define AT_USRSTACKBASE 35
+#define AT_USRSTACKLIM 36
-#define AT_COUNT 35 /* Count of defined aux entry types. */
+#define AT_COUNT 37 /* Count of defined aux entry types. */
/*
* Relocation types.
@@ -1501,5 +1503,6 @@
#define R_X86_64_REX_GOTPCRELX 42
#define ELF_BSDF_SIGFASTBLK 0x0001 /* Kernel supports fast sigblock */
+#define ELF_BSDF_VMNOOVERCOMMIT 0x0002
#endif /* !_SYS_ELF_COMMON_H_ */
Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ sys/vm/swap_pager.c
@@ -169,8 +169,8 @@
&swap_total, 0, sysctl_page_shift, "QU",
"Total amount of available swap storage.");
-static int overcommit = 0;
-SYSCTL_INT(_vm, VM_OVERCOMMIT, overcommit, CTLFLAG_RW, &overcommit, 0,
+int vm_overcommit __read_mostly = 0;
+SYSCTL_INT(_vm, VM_OVERCOMMIT, overcommit, CTLFLAG_RW, &vm_overcommit, 0,
"Configure virtual memory overcommit behavior. See tuning(7) "
"for details.");
static unsigned long swzone;
@@ -190,11 +190,6 @@
CTLFLAG_RD, &swap_free_completed,
"Number of deferred frees completed");
-/* bits from overcommit */
-#define SWAP_RESERVE_FORCE_ON (1 << 0)
-#define SWAP_RESERVE_RLIMIT_ON (1 << 1)
-#define SWAP_RESERVE_ALLOW_NONWIRED (1 << 2)
-
static int
sysctl_page_shift(SYSCTL_HANDLER_ARGS)
{
@@ -218,7 +213,8 @@
prev + pincr > lim_cur(curthread, RLIMIT_SWAP) &&
priv_check(curthread, PRIV_VM_SWAP_NORLIMIT) != 0) {
prev = atomic_fetchadd_long(&uip->ui_vmsize, -pincr);
- KASSERT(prev >= pincr, ("negative vmsize for uid = %d\n", uip->ui_uid));
+ KASSERT(prev >= pincr,
+ ("negative vmsize for uid %d\n", uip->ui_uid));
return (false);
}
return (true);
@@ -236,7 +232,8 @@
#ifdef INVARIANTS
prev = atomic_fetchadd_long(&uip->ui_vmsize, -pdecr);
- KASSERT(prev >= pdecr, ("negative vmsize for uid = %d\n", uip->ui_uid));
+ KASSERT(prev >= pdecr,
+ ("negative vmsize for uid %d\n", uip->ui_uid));
#else
atomic_subtract_long(&uip->ui_vmsize, pdecr);
#endif
@@ -269,8 +266,8 @@
static int curfail;
static struct timeval lastfail;
- KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__,
- (uintmax_t)incr));
+ KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK",
+ __func__, (uintmax_t)incr));
#ifdef RACCT
if (RACCT_ENABLED()) {
@@ -286,7 +283,7 @@
prev = atomic_fetchadd_long(&swap_reserved, pincr);
r = prev + pincr;
s = swap_total;
- oc = atomic_load_int(&overcommit);
+ oc = atomic_load_int(&vm_overcommit);
if (r > s && (oc & SWAP_RESERVE_ALLOW_NONWIRED) != 0) {
s += vm_cnt.v_page_count - vm_cnt.v_free_reserved -
vm_wire_count();
@@ -294,13 +291,15 @@
if ((oc & SWAP_RESERVE_FORCE_ON) != 0 && r > s &&
priv_check(curthread, PRIV_VM_SWAP_NOQUOTA) != 0) {
prev = atomic_fetchadd_long(&swap_reserved, -pincr);
- KASSERT(prev >= pincr, ("swap_reserved < incr on overcommit fail"));
+ KASSERT(prev >= pincr,
+ ("swap_reserved < incr on overcommit fail"));
goto out_error;
}
if (!swap_reserve_by_cred_rlimit(pincr, cred, oc)) {
prev = atomic_fetchadd_long(&swap_reserved, -pincr);
- KASSERT(prev >= pincr, ("swap_reserved < incr on overcommit fail"));
+ KASSERT(prev >= pincr,
+ ("swap_reserved < incr on overcommit fail"));
goto out_error;
}
@@ -308,7 +307,8 @@
out_error:
if (ppsratecheck(&lastfail, &curfail, 1)) {
- printf("uid %d, pid %d: swap reservation for %jd bytes failed\n",
+ printf("uid %d, pid %d: swap reservation "
+ "for %jd bytes failed\n",
cred->cr_ruidinfo->ui_uid, curproc->p_pid, incr);
}
#ifdef RACCT
@@ -327,8 +327,8 @@
{
u_long pincr;
- KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__,
- (uintmax_t)incr));
+ KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK",
+ __func__, (uintmax_t)incr));
#ifdef RACCT
if (RACCT_ENABLED()) {
@@ -361,8 +361,8 @@
u_long prev;
#endif
- KASSERT((decr & PAGE_MASK) == 0, ("%s: decr: %ju & PAGE_MASK", __func__,
- (uintmax_t)decr));
+ KASSERT((decr & PAGE_MASK) == 0, ("%s: decr: %ju & PAGE_MASK",
+ __func__, (uintmax_t)decr));
pdecr = atop(decr);
#ifdef INVARIANTS
Index: sys/vm/vm.h
===================================================================
--- sys/vm/vm.h
+++ sys/vm/vm.h
@@ -165,6 +165,12 @@
extern int vm_ndomains;
+/* bits from overcommit */
+#define SWAP_RESERVE_FORCE_ON (1 << 0)
+#define SWAP_RESERVE_RLIMIT_ON (1 << 1)
+#define SWAP_RESERVE_ALLOW_NONWIRED (1 << 2)
+extern int vm_overcommit;
+
#ifdef _KERNEL
struct ucred;
bool swap_reserve(vm_ooffset_t incr);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 1:22 PM (2 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28583461
Default Alt Text
D36540.id110529.diff (12 KB)
Attached To
Mode
D36540: Pass stack size, limit, and (no)overcommit flag to image using auxv, to avoid syscalls on jemalloc and libthr startup.
Attached
Detach File
Event Timeline
Log In to Comment