diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index e0bdca07ff0..3f077289ac3 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -330,7 +330,7 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred) } void -swap_reserve_force(vm_ooffset_t incr) +swap_reserve_force_by_cred(vm_ooffset_t incr, struct ucred *cred) { u_long pincr; @@ -346,7 +346,13 @@ swap_reserve_force(vm_ooffset_t incr) #endif pincr = atop(incr); atomic_add_long(&swap_reserved, pincr); - swap_reserve_force_rlimit(pincr, curthread->td_ucred); + swap_reserve_force_rlimit(pincr, cred); +} + +void +swap_reserve_force(vm_ooffset_t incr) +{ + swap_reserve_force_by_cred(incr, curthread->td_ucred); } void diff --git a/sys/vm/vm.h b/sys/vm/vm.h index d28c84dd1c9..0da1891dfcc 100644 --- a/sys/vm/vm.h +++ b/sys/vm/vm.h @@ -168,6 +168,7 @@ void vm_ksubmap_init(struct kva_md_info *); bool swap_reserve(vm_ooffset_t incr); bool swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred); void swap_reserve_force(vm_ooffset_t incr); +void swap_reserve_force_by_cred(vm_ooffset_t incr, struct ucred *cred); void swap_release(vm_ooffset_t decr); void swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred); diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 68dcadd2b2f..4c33b786eaa 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -4957,6 +4957,13 @@ vmspace_unshare(struct proc *p) if (newvmspace == NULL) return (ENOMEM); if (!swap_reserve_by_cred(fork_charge, p->p_ucred)) { + /* + * The swap reservation failed. The accounting from + * the entries of the copied newvmspace will be + * subtracted in vmspace_free(), so force the + * reservation there. + */ + swap_reserve_force_by_cred(fork_charge, p->p_ucred); vmspace_free(newvmspace); return (ENOMEM); }