The branch stable/15 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=a4123ac9f596415a090e74849b7a4bedf548f97b

commit a4123ac9f596415a090e74849b7a4bedf548f97b
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-01-03 09:34:23 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-01-24 00:26:45 +0000

    vm_object: remove the charge member
    
    (cherry picked from commit d160447129fe060b28bcd6ba429d17afdf494ff2)
---
 sys/dev/md/md.c     |  2 --
 sys/kern/uipc_shm.c |  2 --
 sys/vm/swap_pager.c |  8 ++------
 sys/vm/vm_fault.c   |  5 ++---
 sys/vm/vm_map.c     | 45 ++++++++++++++++++++++-----------------------
 sys/vm/vm_object.c  | 46 +++++++++++++++++++++++++++-------------------
 sys/vm/vm_object.h  |  4 +---
 7 files changed, 54 insertions(+), 58 deletions(-)

diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 9d246d7c78fd..8d2908264aac 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -1617,7 +1617,6 @@ mdresize(struct md_s *sc, struct md_req *mdr)
                            0, 0);
                        swap_release_by_cred(IDX_TO_OFF(oldpages -
                            newpages), sc->cred);
-                       sc->s_swap.object->charge = IDX_TO_OFF(newpages);
                        sc->s_swap.object->size = newpages;
                        VM_OBJECT_WUNLOCK(sc->s_swap.object);
                } else if (newpages > oldpages) {
@@ -1637,7 +1636,6 @@ mdresize(struct md_s *sc, struct md_req *mdr)
                                }
                        }
                        VM_OBJECT_WLOCK(sc->s_swap.object);
-                       sc->s_swap.object->charge = IDX_TO_OFF(newpages);
                        sc->s_swap.object->size = newpages;
                        VM_OBJECT_WUNLOCK(sc->s_swap.object);
                }
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index eb1327f7f2de..fe3feab4149f 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -759,7 +759,6 @@ shm_dotruncate_locked(struct shmfd *shmfd, off_t length, 
void *rl_cookie)
 
                /* Free the swap accounted for shm */
                swap_release_by_cred(delta, object->cred);
-               object->charge -= delta;
        } else {
                if ((shmfd->shm_seals & F_SEAL_GROW) != 0)
                        return (EPERM);
@@ -768,7 +767,6 @@ shm_dotruncate_locked(struct shmfd *shmfd, off_t length, 
void *rl_cookie)
                delta = IDX_TO_OFF(nobjsize - object->size);
                if (!swap_reserve_by_cred(delta, object->cred))
                        return (ENOMEM);
-               object->charge += delta;
        }
        shmfd->shm_size = length;
        mtx_lock(&shm_timestamp_lock);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 3f077289ac30..efb0dd477c93 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -784,10 +784,7 @@ swap_pager_init_object(vm_object_t object, void *handle, 
struct ucred *cred,
 
        object->un_pager.swp.writemappings = 0;
        object->handle = handle;
-       if (cred != NULL) {
-               object->cred = cred;
-               object->charge = size;
-       }
+       object->cred = cred;
        return (true);
 }
 
@@ -900,8 +897,7 @@ swap_pager_dealloc(vm_object_t object)
         * Release the allocation charge.
         */
        if (object->cred != NULL) {
-               swap_release_by_cred(object->charge, object->cred);
-               object->charge = 0;
+               swap_release_by_cred(ptoa(object->size), object->cred);
                crfree(object->cred);
                object->cred = NULL;
        }
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 1f13869aebf1..addda72e2b56 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -2310,13 +2310,12 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map 
__unused,
                 * directly.
                 */
                dst_object = vm_object_allocate_anon(atop(dst_entry->end -
-                   dst_entry->start), NULL, NULL, 0);
+                   dst_entry->start), NULL, NULL);
 #if VM_NRESERVLEVEL > 0
                dst_object->flags |= OBJ_COLORED;
                dst_object->pg_color = atop(dst_entry->start);
 #endif
                dst_object->domain = src_object->domain;
-               dst_object->charge = dst_entry->end - dst_entry->start;
 
                dst_entry->object.vm_object = dst_object;
                dst_entry->offset = 0;
@@ -2329,7 +2328,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map 
__unused,
                    ("vm_fault_copy_entry: leaked swp charge"));
                dst_object->cred = curthread->td_ucred;
                crhold(dst_object->cred);
-               *fork_charge += dst_object->charge;
+               *fork_charge += ptoa(dst_object->size);
        } else if ((dst_object->flags & OBJ_SWAP) != 0 &&
            dst_object->cred == NULL) {
                KASSERT(dst_entry->cred != NULL, ("no cred for entry %p",
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 4c33b786eaa0..04628f44a497 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2428,7 +2428,7 @@ vm_map_entry_back(vm_map_entry_t entry)
        KASSERT((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0,
            ("map entry %p is a submap", entry));
        object = vm_object_allocate_anon(atop(entry->end - entry->start), NULL,
-           entry->cred, entry->end - entry->start);
+           entry->cred);
        entry->object.vm_object = object;
        entry->offset = 0;
        entry->cred = NULL;
@@ -2443,21 +2443,26 @@ vm_map_entry_back(vm_map_entry_t entry)
 static inline void
 vm_map_entry_charge_object(vm_map_t map, vm_map_entry_t entry)
 {
+       vm_object_t object;
 
        VM_MAP_ASSERT_LOCKED(map);
        KASSERT((entry->eflags & MAP_ENTRY_IS_SUB_MAP) == 0,
            ("map entry %p is a submap", entry));
-       if (entry->object.vm_object == NULL && !vm_map_is_system(map) &&
+       object = entry->object.vm_object;
+       if (object == NULL && !vm_map_is_system(map) &&
            (entry->eflags & MAP_ENTRY_GUARD) == 0)
                vm_map_entry_back(entry);
-       else if (entry->object.vm_object != NULL &&
+       else if (object != NULL &&
            ((entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) &&
            entry->cred != NULL) {
-               VM_OBJECT_WLOCK(entry->object.vm_object);
-               KASSERT(entry->object.vm_object->cred == NULL,
+               VM_OBJECT_WLOCK(object);
+               KASSERT(object->cred == NULL,
                    ("OVERCOMMIT: %s: both cred e %p", __func__, entry));
-               entry->object.vm_object->cred = entry->cred;
-               entry->object.vm_object->charge = entry->end - entry->start;
+               object->cred = entry->cred;
+               if (entry->end - entry->start < ptoa(object->size)) {
+                       swap_reserve_force_by_cred(ptoa(object->size) -
+                           entry->end + entry->start, object->cred);
+               }
                VM_OBJECT_WUNLOCK(entry->object.vm_object);
                entry->cred = NULL;
        }
@@ -2956,7 +2961,7 @@ again:
                 * we cannot distinguish between non-charged and
                 * charged clipped mapping of the same object later.
                 */
-               KASSERT(obj->charge == 0,
+               KASSERT(obj->cred == NULL,
                    ("vm_map_protect: object %p overcharged (entry %p)",
                    obj, entry));
                if (!swap_reserve(ptoa(obj->size))) {
@@ -2968,7 +2973,6 @@ again:
 
                crhold(cred);
                obj->cred = cred;
-               obj->charge = ptoa(obj->size);
                VM_OBJECT_WUNLOCK(obj);
        }
 
@@ -3942,7 +3946,7 @@ static void
 vm_map_entry_delete(vm_map_t map, vm_map_entry_t entry)
 {
        vm_object_t object;
-       vm_pindex_t offidxstart, offidxend, size1;
+       vm_pindex_t offidxstart, offidxend, oldsize;
        vm_size_t size;
 
        vm_map_entry_unlink(map, entry, UNLINK_MERGE_NONE);
@@ -3989,15 +3993,11 @@ vm_map_entry_delete(vm_map_t map, vm_map_entry_t entry)
                            OBJPR_NOTMAPPED);
                        if (offidxend >= object->size &&
                            offidxstart < object->size) {
-                               size1 = object->size;
+                               oldsize = object->size;
                                object->size = offidxstart;
                                if (object->cred != NULL) {
-                                       size1 -= object->size;
-                                       KASSERT(object->charge >= ptoa(size1),
-                                           ("object %p charge < 0", object));
-                                       swap_release_by_cred(ptoa(size1),
-                                           object->cred);
-                                       object->charge -= ptoa(size1);
+                                       swap_release_by_cred(ptoa(oldsize -
+                                           ptoa(object->size)), object->cred);
                                }
                        }
                }
@@ -4198,7 +4198,7 @@ vm_map_copy_swap_object(vm_map_entry_t src_entry, 
vm_map_entry_t dst_entry,
                    ("OVERCOMMIT: vm_map_copy_anon_entry: cred %p",
                     src_object));
                src_object->cred = src_entry->cred;
-               src_object->charge = size;
+               *fork_charge += ptoa(src_object->size) - size;
        }
        dst_entry->object.vm_object = src_object;
        if (charged) {
@@ -4455,7 +4455,7 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t 
*fork_charge)
                                        KASSERT(object->cred == NULL,
                                            ("vmspace_fork both cred"));
                                        object->cred = old_entry->cred;
-                                       object->charge = old_entry->end -
+                                       *fork_charge += old_entry->end -
                                            old_entry->start;
                                        old_entry->cred = NULL;
                                }
@@ -5145,7 +5145,7 @@ RetryLookupLocked:
                if (vm_map_lock_upgrade(map))
                        goto RetryLookup;
                entry->object.vm_object = vm_object_allocate_anon(atop(size),
-                   NULL, entry->cred, size);
+                   NULL, entry->cred);
                entry->offset = 0;
                entry->cred = NULL;
                vm_map_lock_downgrade(map);
@@ -5403,9 +5403,8 @@ vm_map_print(vm_map_t map)
                            (void *)entry->object.vm_object,
                            (uintmax_t)entry->offset);
                        if (entry->object.vm_object && 
entry->object.vm_object->cred)
-                               db_printf(", obj ruid %d charge %jx",
-                                   entry->object.vm_object->cred->cr_ruid,
-                                   (uintmax_t)entry->object.vm_object->charge);
+                               db_printf(", obj ruid %d ",
+                                   entry->object.vm_object->cred->cr_ruid);
                        if (entry->eflags & MAP_ENTRY_COW)
                                db_printf(", copy (%s)",
                                    (entry->eflags & MAP_ENTRY_NEEDS_COPY) ? 
"needed" : "done");
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index f4c54ba91742..aa2d7676e6a8 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -196,9 +196,9 @@ vm_object_zdtor(void *mem, int size, void *arg)
        KASSERT(object->type == OBJT_DEAD,
            ("object %p has non-dead type %d",
            object, object->type));
-       KASSERT(object->charge == 0 && object->cred == NULL,
-           ("object %p has non-zero charge %ju (%p)",
-           object, (uintmax_t)object->charge, object->cred));
+       KASSERT(object->cred == NULL,
+           ("object %p has non-zero charge cred %p",
+           object, object->cred));
 }
 #endif
 
@@ -254,7 +254,6 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, 
u_short flags,
        refcount_init(&object->ref_count, 1);
        object->memattr = VM_MEMATTR_DEFAULT;
        object->cred = NULL;
-       object->charge = 0;
        object->handle = handle;
        object->backing_object = NULL;
        object->backing_object_offset = (vm_ooffset_t) 0;
@@ -452,7 +451,7 @@ vm_object_allocate_dyn(objtype_t dyntype, vm_pindex_t size, 
u_short flags)
  */
 vm_object_t
 vm_object_allocate_anon(vm_pindex_t size, vm_object_t backing_object,
-    struct ucred *cred, vm_size_t charge)
+    struct ucred *cred)
 {
        vm_object_t handle, object;
 
@@ -466,7 +465,6 @@ vm_object_allocate_anon(vm_pindex_t size, vm_object_t 
backing_object,
        _vm_object_allocate(OBJT_SWAP, size,
            OBJ_ANON | OBJ_ONEMAPPING | OBJ_SWAP, object, handle);
        object->cred = cred;
-       object->charge = cred != NULL ? charge : 0;
        return (object);
 }
 
@@ -1448,7 +1446,7 @@ vm_object_shadow(vm_object_t *object, vm_ooffset_t 
*offset, vm_size_t length,
        /*
         * Allocate a new object with the given length.
         */
-       result = vm_object_allocate_anon(atop(length), source, cred, length);
+       result = vm_object_allocate_anon(atop(length), source, cred);
 
        /*
         * Store the offset into the source object, and fix up the offset into
@@ -1511,6 +1509,7 @@ vm_object_split(vm_map_entry_t entry)
        struct pctrie_iter pages;
        vm_page_t m;
        vm_object_t orig_object, new_object, backing_object;
+       struct ucred *cred;
        vm_pindex_t offidxstart;
        vm_size_t size;
 
@@ -1525,9 +1524,26 @@ vm_object_split(vm_map_entry_t entry)
 
        offidxstart = OFF_TO_IDX(entry->offset);
        size = atop(entry->end - entry->start);
+       if (orig_object->cred != NULL) {
+               /*
+                * vm_object_split() is currently called from
+                * vmspace_fork(), and it might be tempting to add the
+                * charge for the split object to fork_charge.  But
+                * fork_charge is discharged on error when the copied
+                * vmspace is destroyed.  Since the split object is
+                * inserted into the shadow hierarchy serving the
+                * source vm_map, it is kept even after the
+                * unsuccessful fork, meaning that we have to force
+                * its swap usage.
+                */
+               cred = curthread->td_ucred;
+               crhold(cred);
+               swap_reserve_force_by_cred(ptoa(size), cred);
+       } else {
+               cred = NULL;
+       }
 
-       new_object = vm_object_allocate_anon(size, orig_object,
-           orig_object->cred, ptoa(size));
+       new_object = vm_object_allocate_anon(size, orig_object, cred);
 
        /*
         * We must wait for the orig_object to complete any in-progress
@@ -1550,12 +1566,6 @@ vm_object_split(vm_map_entry_t entry)
                new_object->backing_object_offset = 
                    orig_object->backing_object_offset + entry->offset;
        }
-       if (orig_object->cred != NULL) {
-               crhold(orig_object->cred);
-               KASSERT(orig_object->charge >= ptoa(size),
-                   ("orig_object->charge < 0"));
-               orig_object->charge -= ptoa(size);
-       }
 
        /*
         * Mark the split operation so that swap_pager_getpages() knows
@@ -2233,7 +2243,6 @@ vm_object_coalesce(vm_object_t prev_object, vm_ooffset_t 
prev_offset,
                                swap_release_by_cred(ptoa(prev_object->size -
                                    next_pindex), prev_object->cred);
                        }
-                       prev_object->charge += charge;
                } else if ((cflags & OBJCO_CHARGED) != 0) {
                        /*
                         * The caller charged, but the object has
@@ -2786,9 +2795,8 @@ DB_SHOW_COMMAND(object, vm_object_print_static)
        db_iprintf("Object %p: type=%d, size=0x%jx, res=%d, ref=%d, flags=0x%x",
            object, (int)object->type, (uintmax_t)object->size,
            object->resident_page_count, object->ref_count, object->flags);
-       db_iprintf(" ruid %d charge %jx\n",
-           object->cred ? object->cred->cr_ruid : -1,
-           (uintmax_t)object->charge);
+       db_iprintf(" ruid %d\n",
+           object->cred ? object->cred->cr_ruid : -1);
        db_iprintf(" sref=%d, backing_object(%d)=(%p)+0x%jx\n",
            atomic_load_int(&object->shadow_count),
            object->backing_object ? object->backing_object->ref_count : 0,
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index fdc0bcfc9f28..b056ebe9a4b7 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -175,7 +175,6 @@ struct vm_object {
                } phys;
        } un_pager;
        struct ucred *cred;
-       vm_ooffset_t charge;
        void *umtx_data;
 };
 
@@ -358,8 +357,7 @@ void umtx_shm_object_terminated(vm_object_t object);
 extern int umtx_shm_vnobj_persistent;
 
 vm_object_t vm_object_allocate (objtype_t, vm_pindex_t);
-vm_object_t vm_object_allocate_anon(vm_pindex_t, vm_object_t, struct ucred *,
-   vm_size_t);
+vm_object_t vm_object_allocate_anon(vm_pindex_t, vm_object_t, struct ucred *);
 vm_object_t vm_object_allocate_dyn(objtype_t, vm_pindex_t, u_short);
 boolean_t vm_object_coalesce(vm_object_t, vm_ooffset_t, vm_size_t, vm_size_t,
    int);

Reply via email to