git: 0ab96c91676d - stable/15 - rfork(2): fix swap accounting in vmspace_unshare()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 24 Jan 2026 00:32:23 UTC
The branch stable/15 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=0ab96c91676d8f5158227ae1d1465019ef97cdb3
commit 0ab96c91676d8f5158227ae1d1465019ef97cdb3
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-01-04 00:19:36 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-01-24 00:26:45 +0000
rfork(2): fix swap accounting in vmspace_unshare()
(cherry picked from commit de770681234d001a1f4cdb8121179331dc3a2def)
---
sys/vm/swap_pager.c | 10 ++++++++--
sys/vm/vm.h | 1 +
sys/vm/vm_map.c | 7 +++++++
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index e0bdca07ff0f..3f077289ac30 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -330,7 +330,7 @@ out_error:
}
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 d28c84dd1c95..0da1891dfcc7 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 68dcadd2b2f1..4c33b786eaa0 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);
}