*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_subr.c,v 1.118 2008/09/17 21:44:18 dillon Exp $
*/
/*
* If the vnode has an object, destroy it.
*/
lwkt_gettoken(&vmobj_token);
- if ((object = vp->v_object) != NULL) {
+ object = vp->v_object;
+ if (object != NULL) {
+ /*
+ * Use vm_object_lock() rather than vm_object_hold to avoid
+ * creating an extra (self-)hold on the object.
+ */
+ vm_object_lock(object);
KKASSERT(object == vp->v_object);
if (object->ref_count == 0) {
if ((object->flags & OBJ_DEAD) == 0)
vm_pager_deallocate(object);
}
vclrflags(vp, VOBJBUF);
+ vm_object_unlock(object);
}
lwkt_reltoken(&vmobj_token);
KKASSERT((vp->v_flag & VOBJBUF) == 0);
TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist,
page, pageq);
lwkt_gettoken(&vm_token);
+ vm_object_hold(object);
crit_enter();
vm_page_free(*mpp);
vm_page_insert(page, object, offset);
crit_exit();
+ vm_object_drop(object);
lwkt_reltoken(&vm_token);
}
mtx_unlock(&dev_pager_mtx);
/*
* kernel_object maps 1:1 to kernel_map.
*/
+ vm_object_hold(&kernel_object);
vm_object_reference(&kernel_object);
vm_map_insert(map, &count,
&kernel_object, addr,
}
vm_map_wire(map, addr, addr + size, 0);
+ vm_object_drop(&kernel_object);
+
lwkt_reltoken(&vm_token);
crit_exit();
return (addr);
* race with page-out. vm_map_wire will wire the pages.
*/
lwkt_gettoken(&vm_token);
+ vm_object_hold(&kernel_object);
for (i = gstart; i < size; i += PAGE_SIZE) {
vm_page_t mem;
vm_page_flag_clear(mem, PG_ZERO);
vm_page_wakeup(mem);
}
+ vm_object_drop(&kernel_object);
lwkt_reltoken(&vm_token);
/*
* being a negative impact on memory usage.
*
* The vm_map must be exclusively locked.
+ * The orig_object should be held.
*/
static void
vm_map_split(vm_map_entry_t entry)
lwkt_gettoken(&vm_token);
lwkt_gettoken(&vmobj_token);
+ vm_object_hold(new_object);
+
source = orig_object->backing_object;
if (source != NULL) {
+ vm_object_hold(source);
/* Referenced by new_object */
vm_object_reference_locked(source);
LIST_INSERT_HEAD(&source->shadow_head,
new_object->backing_object = source;
source->shadow_count++;
source->generation++;
+ vm_object_drop(source);
}
for (idx = 0; idx < size; idx++) {
entry->object.vm_object = new_object;
entry->offset = 0LL;
vm_object_deallocate_locked(orig_object);
+ vm_object_drop(new_object);
lwkt_reltoken(&vmobj_token);
lwkt_reltoken(&vm_token);
}
lwkt_reltoken(&vm_token);
/*
- * Wait for the object hold count to hit zero
+ * Let the pager know object is dead.
*/
- vm_object_hold_wait(object);
+ vm_pager_deallocate(object);
/*
- * Let the pager know object is dead.
+ * Wait for the object hold count to hit zero
*/
- vm_pager_deallocate(object);
+ vm_object_hold_wait(object);
/*
* Remove the object from the global object list.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
* $FreeBSD: src/sys/vm/vm_page.c,v 1.147.2.18 2002/03/10 05:03:19 alc Exp $
- * $DragonFly: src/sys/vm/vm_page.c,v 1.40 2008/08/25 17:01:42 dillon Exp $
*/
/*
*
* This routine may not block.
* This routine must be called with the vm_token held.
+ * This routine must be called with the vm_object held.
* This routine must be called with a critical section held.
*/
void
object = m->object;
+ vm_object_hold(object);
+
/*
* Remove the page from the object and update the object.
*/
object->generation++;
m->object = NULL;
+ vm_object_drop(object);
+
lwkt_reltoken(&vm_token);
}
vm_page_rename(vm_page_t m, vm_object_t new_object, vm_pindex_t new_pindex)
{
lwkt_gettoken(&vm_token);
+ vm_object_hold(new_object);
vm_page_remove(m);
vm_page_insert(m, new_object, new_pindex);
if (m->queue - m->pc == PQ_CACHE)
vm_page_deactivate(m);
vm_page_dirty(m);
vm_page_wakeup(m);
+ vm_object_drop(new_object);
lwkt_reltoken(&vm_token);
}
KKASSERT(allocflags &
(VM_ALLOC_NORMAL|VM_ALLOC_INTERRUPT|VM_ALLOC_SYSTEM));
lwkt_gettoken(&vm_token);
+ vm_object_hold(object);
retrylookup:
if ((m = vm_page_lookup(object, pindex)) != NULL) {
if (m->busy || (m->flags & PG_BUSY)) {
goto retrylookup;
}
done:
+ vm_object_drop(object);
lwkt_reltoken(&vm_token);
return(m);
}
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* rights to redistribute these changes.
*
* $FreeBSD: src/sys/vm/vm_pageout.c,v 1.151.2.15 2002/12/29 18:21:04 dillon Exp $
- * $DragonFly: src/sys/vm/vm_pageout.c,v 1.36 2008/07/01 02:02:56 dillon Exp $
*/
/*
* forward scan if room remains.
*/
+ vm_object_hold(object);
more:
while (ib && pageout_count < vm_pageout_page_count) {
vm_page_t p;
if (ib && pageout_count < vm_pageout_page_count)
goto more;
+ vm_object_drop(object);
+
/*
* we allow reads during pageouts...
*/
*
* The map must be locked.
* The caller must hold vm_token.
+ * The caller must hold the vm_object.
*/
static int vm_pageout_object_deactivate_pages_callback(vm_page_t, void *);
vm_pindex_t desired, int map_remove_only)
{
struct rb_vm_page_scan_info info;
+ vm_object_t tmp;
int remove_mode;
- if (object->type == OBJT_DEVICE || object->type == OBJT_PHYS)
- return;
-
while (object) {
if (pmap_resident_count(vm_map_pmap(map)) <= desired)
return;
- if (object->paging_in_progress)
+
+ vm_object_hold(object);
+
+ if (object->type == OBJT_DEVICE || object->type == OBJT_PHYS) {
+ vm_object_drop(object);
+ return;
+ }
+ if (object->paging_in_progress) {
+ vm_object_drop(object);
return;
+ }
remove_mode = map_remove_only;
if (object->shadow_count > 1)
&info
);
crit_exit();
- object = object->backing_object;
+ tmp = object->backing_object;
+ vm_object_drop(object);
+ object = tmp;
}
}
/*
* The caller must hold vm_token.
+ * The caller must hold the vm_object.
*/
static int
vm_pageout_object_deactivate_pages_callback(vm_page_t p, void *data)
tmpe = tmpe->next;
}
- if (bigobj)
+ if (bigobj)
vm_pageout_object_deactivate_pages(map, bigobj, desired, 0);
/*
case VM_MAPTYPE_NORMAL:
case VM_MAPTYPE_VPAGETABLE:
obj = tmpe->object.vm_object;
- if (obj)
+ if (obj)
vm_pageout_object_deactivate_pages(map, obj, desired, 0);
break;
default:
* simply populate an existing mapping.
*/
lwkt_gettoken(&vm_token);
+ vm_object_hold(z->zobj);
savezpc = z->zpagecount;
nbytes = z->zpagecount * PAGE_SIZE;
nbytes -= nbytes % z->zsize;
m = vm_page_alloc(z->zobj, z->zpagecount,
z->zallocflag);
/* note: z might be modified due to blocking */
- if (m == NULL)
+ if (m == NULL)
break;
/*
vmstats.v_wire_count++;
}
nitems = ((z->zpagecount * PAGE_SIZE) - nbytes) / z->zsize;
+ vm_object_drop(z->zobj);
lwkt_reltoken(&vm_token);
} else if (z->zflags & ZONE_SPECIAL) {
/*