Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150418489
D36540.id110502.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D36540.id110502.diff
View Options
diff --git a/contrib/jemalloc/src/pages.c b/contrib/jemalloc/src/pages.c
--- a/contrib/jemalloc/src/pages.c
+++ b/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];
diff --git a/lib/libc/gen/auxv.c b/lib/libc/gen/auxv.c
--- a/lib/libc/gen/auxv.c
+++ b/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;
diff --git a/lib/libc/gen/elf_utils.c b/lib/libc/gen/elf_utils.c
--- a/lib/libc/gen/elf_utils.c
+++ b/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
diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c
--- a/lib/libthr/thread/thr_stack.c
+++ b/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>
@@ -149,19 +150,26 @@
{
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)
+ 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, &len, sizeof(len)) != 0 &&
+ 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_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());
}
void
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
--- a/sys/kern/imgact_elf.c
+++ b/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);
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
--- a/sys/sys/elf_common.h
+++ b/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_ */
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
--- a/sys/vm/swap_pager.c
+++ b/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
diff --git a/sys/vm/vm.h b/sys/vm/vm.h
--- a/sys/vm/vm.h
+++ b/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
Thu, Apr 2, 1:51 AM (2 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30698386
Default Alt Text
D36540.id110502.diff (10 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