diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -2163,7 +2163,7 @@ vm_object_coalesce(vm_object_t prev_object, vm_ooffset_t prev_offset, vm_size_t prev_size, vm_size_t next_size, boolean_t reserved) { - vm_pindex_t next_pindex; + vm_pindex_t next_end, next_pindex; if (prev_object == NULL) return (TRUE); @@ -2197,10 +2197,12 @@ return (FALSE); } + next_end = next_pindex + next_size; + /* * Account for the charge. */ - if (prev_object->cred != NULL) { + if (prev_object->cred != NULL && next_end > prev_object->size) { /* * If prev_object was charged, then this mapping, * although not charged now, may become writable @@ -2211,38 +2213,27 @@ * entry, and swap reservation for this entry is * managed in appropriate time. */ - if (!reserved && !swap_reserve_by_cred(ptoa(next_size), - prev_object->cred)) { + vm_size_t charge = ptoa(next_end - prev_object->size); + if (!reserved && + !swap_reserve_by_cred(charge, prev_object->cred)) { VM_OBJECT_WUNLOCK(prev_object); return (FALSE); } - prev_object->charge += ptoa(next_size); + prev_object->charge += charge; } /* * Remove any pages that may still be in the object from a previous * deallocation. */ - if (next_pindex < prev_object->size) { - vm_object_page_remove(prev_object, next_pindex, next_pindex + - next_size, 0); -#if 0 - if (prev_object->cred != NULL) { - KASSERT(prev_object->charge >= - ptoa(prev_object->size - next_pindex), - ("object %p overcharged 1 %jx %jx", prev_object, - (uintmax_t)next_pindex, (uintmax_t)next_size)); - prev_object->charge -= ptoa(prev_object->size - - next_pindex); - } -#endif - } + if (next_pindex < prev_object->size) + vm_object_page_remove(prev_object, next_pindex, next_end, 0); /* * Extend the object if necessary. */ - if (next_pindex + next_size > prev_object->size) - prev_object->size = next_pindex + next_size; + if (next_end > prev_object->size) + prev_object->size = next_end; #ifdef INVARIANTS /* @@ -2254,7 +2245,7 @@ vm_pindex_t pidx; pidx = swap_pager_seek_data(prev_object, next_pindex); - KASSERT(pidx >= next_pindex + next_size, + KASSERT(pidx >= next_end, ("found obj %p pindex %#jx e %#jx %#jx %#jx", prev_object, pidx, (uintmax_t)prev_offset, (uintmax_t)prev_size, (uintmax_t)next_size));