Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/swap_pager.c
Show First 20 Lines • Show All 196 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
uint64_t newval; | uint64_t newval; | ||||
u_long value = *(u_long *)arg1; | u_long value = *(u_long *)arg1; | ||||
newval = ((uint64_t)value) << PAGE_SHIFT; | newval = ((uint64_t)value) << PAGE_SHIFT; | ||||
return (sysctl_handle_64(oidp, &newval, 0, req)); | return (sysctl_handle_64(oidp, &newval, 0, req)); | ||||
} | } | ||||
int | static bool | ||||
swap_reserve_by_cred_rlimit(u_long pincr, struct ucred *cred, int oc) | |||||
{ | |||||
struct uidinfo *uip; | |||||
u_long prev; | |||||
uip = cred->cr_ruidinfo; | |||||
prev = atomic_fetchadd_long(&uip->ui_vmsize, pincr); | |||||
if ((oc & SWAP_RESERVE_RLIMIT_ON) != 0 && | |||||
prev + pincr > lim_cur(curthread, RLIMIT_SWAP) && | |||||
priv_check(curthread, PRIV_VM_SWAP_NORLIMIT) != 0) { | |||||
kib: `priv_check() != 0` | |||||
prev = atomic_fetchadd_long(&uip->ui_vmsize, -pincr); | |||||
KASSERT(prev >= pincr, ("negative vmsize for uid = %d\n", uip->ui_uid)); | |||||
Not Done Inline ActionsMight be, make this KASSERT kib: Might be, make this KASSERT | |||||
return (false); | |||||
} | |||||
return (true); | |||||
} | |||||
static void | |||||
swap_release_by_cred_rlimit(u_long pdecr, struct ucred *cred) | |||||
{ | |||||
struct uidinfo *uip; | |||||
#ifdef INVARIANTS | |||||
u_long prev; | |||||
#endif | |||||
uip = cred->cr_ruidinfo; | |||||
#ifdef INVARIANTS | |||||
prev = atomic_fetchadd_long(&uip->ui_vmsize, -pdecr); | |||||
KASSERT(prev >= pdecr, ("negative vmsize for uid = %d\n", uip->ui_uid)); | |||||
#else | |||||
atomic_subtract_long(&uip->ui_vmsize, pdecr); | |||||
#endif | |||||
} | |||||
static void | |||||
swap_reserve_force_rlimit(u_long pincr, struct ucred *cred) | |||||
{ | |||||
struct uidinfo *uip; | |||||
uip = cred->cr_ruidinfo; | |||||
atomic_add_long(&uip->ui_vmsize, pincr); | |||||
} | |||||
bool | |||||
swap_reserve(vm_ooffset_t incr) | swap_reserve(vm_ooffset_t incr) | ||||
{ | { | ||||
return (swap_reserve_by_cred(incr, curthread->td_ucred)); | return (swap_reserve_by_cred(incr, curthread->td_ucred)); | ||||
} | } | ||||
int | bool | ||||
swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred) | swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred) | ||||
{ | { | ||||
u_long r, s, prev, pincr; | u_long r, s, prev, pincr; | ||||
int res, error; | #ifdef RACCT | ||||
int error; | |||||
#endif | |||||
int oc; | |||||
static int curfail; | static int curfail; | ||||
static struct timeval lastfail; | static struct timeval lastfail; | ||||
struct uidinfo *uip; | |||||
Not Done Inline ActionsMove oc declaration above statics. kib: Move oc declaration above statics. | |||||
uip = cred->cr_ruidinfo; | |||||
KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__, | KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__, | ||||
(uintmax_t)incr)); | (uintmax_t)incr)); | ||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable) { | if (RACCT_ENABLED()) { | ||||
PROC_LOCK(curproc); | PROC_LOCK(curproc); | ||||
error = racct_add(curproc, RACCT_SWAP, incr); | error = racct_add(curproc, RACCT_SWAP, incr); | ||||
PROC_UNLOCK(curproc); | PROC_UNLOCK(curproc); | ||||
if (error != 0) | if (error != 0) | ||||
return (0); | return (false); | ||||
} | } | ||||
#endif | #endif | ||||
pincr = atop(incr); | pincr = atop(incr); | ||||
res = 0; | |||||
prev = atomic_fetchadd_long(&swap_reserved, pincr); | prev = atomic_fetchadd_long(&swap_reserved, pincr); | ||||
r = prev + pincr; | r = prev + pincr; | ||||
if (overcommit & SWAP_RESERVE_ALLOW_NONWIRED) { | s = swap_total; | ||||
s = vm_cnt.v_page_count - vm_cnt.v_free_reserved - | oc = atomic_load_int(&overcommit); | ||||
if (r > s && (oc & SWAP_RESERVE_ALLOW_NONWIRED) != 0) { | |||||
s += vm_cnt.v_page_count - vm_cnt.v_free_reserved - | |||||
vm_wire_count(); | vm_wire_count(); | ||||
} else | } | ||||
s = 0; | if ((oc & SWAP_RESERVE_FORCE_ON) != 0 && r > s && | ||||
s += swap_total; | priv_check(curthread, PRIV_VM_SWAP_NOQUOTA) != 0) { | ||||
Not Done Inline ActionsPlease invert all conditions and s/||/&&/ kib: Please invert all conditions and s/||/&&/ | |||||
if ((overcommit & SWAP_RESERVE_FORCE_ON) == 0 || r <= s || | |||||
(error = priv_check(curthread, PRIV_VM_SWAP_NOQUOTA)) == 0) { | |||||
res = 1; | |||||
} else { | |||||
prev = atomic_fetchadd_long(&swap_reserved, -pincr); | prev = atomic_fetchadd_long(&swap_reserved, -pincr); | ||||
Not Done Inline Actionsif (r > s && (oc & _ALLOW_NONWIRED) != 0) { kib: `if (r > s && (oc & _ALLOW_NONWIRED) != 0) {` | |||||
if (prev < pincr) | KASSERT(prev >= pincr, ("swap_reserved < incr on overcommit fail")); | ||||
Not Done Inline ActionsAgain, make this KASSERT kib: Again, make this KASSERT | |||||
panic("swap_reserved < incr on overcommit fail"); | goto out_error; | ||||
} | } | ||||
if (res) { | |||||
Not Done Inline ActionsAnd this kib: And this | |||||
prev = atomic_fetchadd_long(&uip->ui_vmsize, pincr); | if (!swap_reserve_by_cred_rlimit(pincr, cred, oc)) { | ||||
if ((overcommit & SWAP_RESERVE_RLIMIT_ON) != 0 && | prev = atomic_fetchadd_long(&swap_reserved, -pincr); | ||||
prev + pincr > lim_cur(curthread, RLIMIT_SWAP) && | KASSERT(prev >= pincr, ("swap_reserved < incr on overcommit fail")); | ||||
priv_check(curthread, PRIV_VM_SWAP_NORLIMIT)) { | goto out_error; | ||||
res = 0; | |||||
prev = atomic_fetchadd_long(&uip->ui_vmsize, -pincr); | |||||
if (prev < pincr) | |||||
panic("uip->ui_vmsize < incr on overcommit fail"); | |||||
} | } | ||||
} | |||||
if (!res && ppsratecheck(&lastfail, &curfail, 1)) { | return (true); | ||||
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", | ||||
uip->ui_uid, curproc->p_pid, incr); | cred->cr_ruidinfo->ui_uid, curproc->p_pid, incr); | ||||
} | } | ||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable && !res) { | if (RACCT_ENABLED()) { | ||||
PROC_LOCK(curproc); | PROC_LOCK(curproc); | ||||
racct_sub(curproc, RACCT_SWAP, incr); | racct_sub(curproc, RACCT_SWAP, incr); | ||||
PROC_UNLOCK(curproc); | PROC_UNLOCK(curproc); | ||||
} | } | ||||
#endif | #endif | ||||
return (res); | return (false); | ||||
} | } | ||||
void | void | ||||
swap_reserve_force(vm_ooffset_t incr) | swap_reserve_force(vm_ooffset_t incr) | ||||
{ | { | ||||
struct uidinfo *uip; | |||||
u_long pincr; | u_long pincr; | ||||
KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__, | KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__, | ||||
(uintmax_t)incr)); | (uintmax_t)incr)); | ||||
PROC_LOCK(curproc); | |||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable) | if (RACCT_ENABLED()) { | ||||
PROC_LOCK(curproc); | |||||
racct_add_force(curproc, RACCT_SWAP, incr); | racct_add_force(curproc, RACCT_SWAP, incr); | ||||
PROC_UNLOCK(curproc); | |||||
} | |||||
#endif | #endif | ||||
pincr = atop(incr); | pincr = atop(incr); | ||||
atomic_add_long(&swap_reserved, pincr); | atomic_add_long(&swap_reserved, pincr); | ||||
uip = curproc->p_ucred->cr_ruidinfo; | swap_reserve_force_rlimit(pincr, curthread->td_ucred); | ||||
atomic_add_long(&uip->ui_vmsize, pincr); | |||||
PROC_UNLOCK(curproc); | |||||
} | } | ||||
void | void | ||||
swap_release(vm_ooffset_t decr) | swap_release(vm_ooffset_t decr) | ||||
{ | { | ||||
struct ucred *cred; | struct ucred *cred; | ||||
PROC_LOCK(curproc); | PROC_LOCK(curproc); | ||||
cred = curproc->p_ucred; | cred = curproc->p_ucred; | ||||
swap_release_by_cred(decr, cred); | swap_release_by_cred(decr, cred); | ||||
PROC_UNLOCK(curproc); | PROC_UNLOCK(curproc); | ||||
} | } | ||||
void | void | ||||
swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred) | swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred) | ||||
{ | { | ||||
u_long prev, pdecr; | u_long prev, pdecr; | ||||
struct uidinfo *uip; | |||||
uip = cred->cr_ruidinfo; | |||||
KASSERT((decr & PAGE_MASK) == 0, ("%s: decr: %ju & PAGE_MASK", __func__, | KASSERT((decr & PAGE_MASK) == 0, ("%s: decr: %ju & PAGE_MASK", __func__, | ||||
(uintmax_t)decr)); | (uintmax_t)decr)); | ||||
pdecr = atop(decr); | pdecr = atop(decr); | ||||
prev = atomic_fetchadd_long(&swap_reserved, -pdecr); | prev = atomic_fetchadd_long(&swap_reserved, -pdecr); | ||||
if (prev < pdecr) | if (prev < pdecr) | ||||
panic("swap_reserved < decr"); | panic("swap_reserved < decr"); | ||||
prev = atomic_fetchadd_long(&uip->ui_vmsize, -pdecr); | swap_release_by_cred_rlimit(pdecr, cred); | ||||
if (prev < pdecr) | |||||
printf("negative vmsize for uid = %d\n", uip->ui_uid); | |||||
#ifdef RACCT | #ifdef RACCT | ||||
if (racct_enable) | if (racct_enable) | ||||
racct_sub_cred(cred, RACCT_SWAP, decr); | racct_sub_cred(cred, RACCT_SWAP, decr); | ||||
#endif | #endif | ||||
} | } | ||||
static int swap_pager_full = 2; /* swap space exhaustion (task killing) */ | static int swap_pager_full = 2; /* swap space exhaustion (task killing) */ | ||||
static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/ | static int swap_pager_almost_full = 1; /* swap space exhaustion (w/hysteresis)*/ | ||||
▲ Show 20 Lines • Show All 2,736 Lines • Show Last 20 Lines |
priv_check() != 0