Changeset View
Changeset View
Standalone View
Standalone View
sys/vm/swap_pager.c
Show First 20 Lines • Show All 3,094 Lines • ▼ Show 20 Lines | if (nsw_wcount_async + n >= 0) { | ||||
"swpsysctl", 0); | "swpsysctl", 0); | ||||
} | } | ||||
} | } | ||||
mtx_unlock(&swbuf_mtx); | mtx_unlock(&swbuf_mtx); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* | |||||
* Make sure tmpfs vnodes with writable mappings can be found on the lazy list. | |||||
* | |||||
* This allows for periodic mtime updates while only scanning vnodes which are | |||||
* plausibly dirty, see tmpfs_update_mtime_lazy. | |||||
*/ | |||||
static void | static void | ||||
swap_pager_update_tmpfs(vm_object_t object, vm_offset_t old, vm_offset_t new) | |||||
{ | |||||
struct vnode *vp; | |||||
VM_OBJECT_ASSERT_WLOCKED(object); | |||||
if ((object->flags & OBJ_TMPFS) == 0) { | |||||
VM_OBJECT_WUNLOCK(object); | |||||
return; | |||||
} | |||||
vp = object->un_pager.swp.swp_tmpfs; | |||||
if (old == 0) { | |||||
VNASSERT((object->flags & OBJ_TMPFS_VREF) == 0, vp, | |||||
("object without writtable mappings has a reference")); | |||||
VNPASS(vp->v_usecount > 0, vp); | |||||
} else { | |||||
VNASSERT((object->flags & OBJ_TMPFS_VREF) != 0, vp, | |||||
("object with writtable mappings does not have a reference")); | |||||
} | |||||
if (old == new) { | |||||
VM_OBJECT_WUNLOCK(object); | |||||
return; | |||||
} | |||||
if (new == 0) { | |||||
vm_object_clear_flag(object, OBJ_TMPFS_VREF); | |||||
VM_OBJECT_WUNLOCK(object); | |||||
vrele(vp); | |||||
} else { | |||||
if ((object->flags & OBJ_TMPFS_VREF) == 0) { | |||||
vref(vp); | |||||
vlazy(vp); | |||||
vm_object_set_flag(object, OBJ_TMPFS_VREF); | |||||
} | |||||
VM_OBJECT_WUNLOCK(object); | |||||
} | |||||
} | |||||
static void | |||||
swap_pager_update_writecount(vm_object_t object, vm_offset_t start, | swap_pager_update_writecount(vm_object_t object, vm_offset_t start, | ||||
vm_offset_t end) | vm_offset_t end) | ||||
{ | { | ||||
vm_offset_t new, old; | |||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
KASSERT((object->flags & OBJ_ANON) == 0, | KASSERT((object->flags & OBJ_ANON) == 0, | ||||
("Splittable object with writecount")); | ("Splittable object with writecount")); | ||||
old = object->un_pager.swp.writemappings; | |||||
object->un_pager.swp.writemappings += (vm_ooffset_t)end - start; | object->un_pager.swp.writemappings += (vm_ooffset_t)end - start; | ||||
VM_OBJECT_WUNLOCK(object); | new = object->un_pager.swp.writemappings; | ||||
swap_pager_update_tmpfs(object, old, new); | |||||
VM_OBJECT_ASSERT_UNLOCKED(object); | |||||
} | } | ||||
static void | static void | ||||
swap_pager_release_writecount(vm_object_t object, vm_offset_t start, | swap_pager_release_writecount(vm_object_t object, vm_offset_t start, | ||||
kib: Don't you need to assert that TMPFS_VREF is set? Or even better, check that the flag is set… | |||||
vm_offset_t end) | vm_offset_t end) | ||||
{ | { | ||||
vm_offset_t new, old; | |||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
KASSERT((object->flags & OBJ_ANON) == 0, | KASSERT((object->flags & OBJ_ANON) == 0, | ||||
("Splittable object with writecount")); | ("Splittable object with writecount")); | ||||
old = object->un_pager.swp.writemappings; | |||||
object->un_pager.swp.writemappings -= (vm_ooffset_t)end - start; | object->un_pager.swp.writemappings -= (vm_ooffset_t)end - start; | ||||
VM_OBJECT_WUNLOCK(object); | new = object->un_pager.swp.writemappings; | ||||
swap_pager_update_tmpfs(object, old, new); | |||||
VM_OBJECT_ASSERT_UNLOCKED(object); | |||||
Not Done Inline Actions'new' is arguably useless kib: 'new' is arguably useless | |||||
Done Inline ActionsIt does not add anything per se, but I think it reads better. mjg: It does not add anything per se, but I think it reads better. | |||||
} | } | ||||
Done Inline ActionsI think for swap objects, release_writecount() can just call update_writecount() and decide what to do on the new writemapping value being 0 (clear flag) or not (set flag). kib: I think for swap objects, release_writecount() can just call update_writecount() and decide… |
Don't you need to assert that TMPFS_VREF is set? Or even better, check that the flag is set, and not vrele() if it is not. I am not sure that we never do update_writecount with effective value of 0.