Page MenuHomeFreeBSD

D6085.id15571.diff
No OneTemporary

D6085.id15571.diff

Index: sys/vm/vm_fault.c
===================================================================
--- sys/vm/vm_fault.c
+++ sys/vm/vm_fault.c
@@ -137,7 +137,12 @@
vm_page_xunbusy(fs->m);
vm_page_lock(fs->m);
- vm_page_deactivate(fs->m);
+ if (fs->m->valid == 0) {
+ if (fs->m->wire_count == 0)
+ vm_page_free(fs->m);
+ } else {
+ vm_page_deactivate(fs->m);
+ }
vm_page_unlock(fs->m);
fs->m = NULL;
}
@@ -292,7 +297,8 @@
struct faultstate fs;
struct vnode *vp;
vm_page_t m;
- int ahead, behind, cluster_offset, error, locked;
+ int ahead, behind, cluster_offset, dead, error, locked, rv;
+ u_char behavior;
hardfault = 0;
growstack = TRUE;
@@ -412,7 +418,7 @@
fs.lookup_still_valid = TRUE;
- fs.first_m = NULL;
+ fs.m = fs.first_m = NULL;
/*
* Search for the page at object/offset.
@@ -421,11 +427,20 @@
fs.pindex = fs.first_pindex;
while (TRUE) {
/*
- * If the object is dead, we stop here
+ * If the object is marked for imminent termination,
+ * we retry here, since the collapse pass has raced
+ * with us. Otherwise, if we see terminally dead
+ * object, return fail.
*/
- if (fs.object->flags & OBJ_DEAD) {
+ if ((fs.object->flags & OBJ_DEAD) != 0) {
+ dead = fs.object->type == OBJT_DEAD;
+ if (fs.m != NULL && fs.m != fs.first_m)
+ release_page(&fs);
unlock_and_deallocate(&fs);
- return (KERN_PROTECTION_FAILURE);
+ if (dead)
+ return (KERN_PROTECTION_FAILURE);
+ pause("vmf_de", 1);
+ goto RetryFault;
}
/*
@@ -551,9 +566,18 @@
* zero-filled pages.
*/
if (fs.object->type != OBJT_DEFAULT) {
- int rv;
- u_char behavior = vm_map_entry_behavior(fs.entry);
-
+ if (!fs.lookup_still_valid) {
+ locked = vm_map_trylock_read(fs.map);
+ if (locked)
+ fs.lookup_still_valid = TRUE;
+ if (!locked || fs.map->timestamp !=
+ map_generation) {
+ release_page(&fs);
+ unlock_and_deallocate(&fs);
+ goto RetryFault;
+ }
+ }
+ behavior = vm_map_entry_behavior(fs.entry);
era = fs.entry->read_ahead;
if (behavior == MAP_ENTRY_BEHAV_RANDOM ||
P_KILLED(curproc)) {
@@ -604,6 +628,7 @@
}
ahead = ulmin(ahead, atop(fs.entry->end - vaddr) - 1);
if (era != nera)
+ /* XXX only read-lock on map */
fs.entry->read_ahead = nera;
/*
@@ -821,6 +846,7 @@
if (vm_page_rename(fs.m, fs.first_object,
fs.first_pindex)) {
VM_OBJECT_WUNLOCK(fs.first_object);
+ release_page(&fs);
unlock_and_deallocate(&fs);
goto RetryFault;
}
Index: sys/vm/vm_object.c
===================================================================
--- sys/vm/vm_object.c
+++ sys/vm/vm_object.c
@@ -1584,7 +1584,7 @@
continue;
}
- KASSERT(pp == NULL || pp->valid != 0,
+ KASSERT(pp == NULL || pp->wire_count > 0 || pp->valid != 0,
("unbusy invalid page %p", pp));
if (pp != NULL || vm_pager_has_page(object, new_pindex, NULL,
@@ -1669,11 +1669,14 @@
void
vm_object_collapse(vm_object_t object)
{
+ vm_object_t backing_object, new_backing_object;
+
VM_OBJECT_ASSERT_WLOCKED(object);
-
- while (TRUE) {
- vm_object_t backing_object;
+ if ((object->flags & OBJ_DEAD) != 0)
+ return;
+ vm_object_pip_add(object, 1);
+ while (TRUE) {
/*
* Verify that the conditions are right for collapse:
*
@@ -1699,14 +1702,14 @@
break;
}
- if (
- object->paging_in_progress != 0 ||
- backing_object->paging_in_progress != 0
- ) {
+ if (object->paging_in_progress > 1 /* one ref is from us */ ||
+ backing_object->paging_in_progress != 0) {
vm_object_qcollapse(object);
VM_OBJECT_WUNLOCK(backing_object);
break;
}
+ vm_object_pip_add(backing_object, 1);
+
/*
* We know that we can either collapse the backing object (if
* the parent is the only reference to it) or (perhaps) have
@@ -1789,6 +1792,7 @@
KASSERT(backing_object->ref_count == 1, (
"backing_object %p was somehow re-referenced during collapse!",
backing_object));
+ vm_object_pip_wakeup(backing_object);
backing_object->type = OBJT_DEAD;
backing_object->ref_count = 0;
VM_OBJECT_WUNLOCK(backing_object);
@@ -1796,14 +1800,13 @@
object_collapses++;
} else {
- vm_object_t new_backing_object;
-
/*
* If we do not entirely shadow the backing object,
* there is nothing we can do so we give up.
*/
if (object->resident_page_count != object->size &&
!vm_object_scan_all_shadowed(object)) {
+ vm_object_pip_wakeup(backing_object);
VM_OBJECT_WUNLOCK(backing_object);
break;
}
@@ -1836,6 +1839,7 @@
* its ref_count was at least 2, it will not vanish.
*/
backing_object->ref_count--;
+ vm_object_pip_wakeup(backing_object);
VM_OBJECT_WUNLOCK(backing_object);
object_bypasses++;
}
@@ -1844,6 +1848,7 @@
* Try again with this object's new backing object.
*/
}
+ vm_object_pip_wakeup(object);
}
/*
Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c
+++ sys/vm/vm_page.c
@@ -1944,8 +1944,10 @@
m < &m_ret[npages]; m++) {
if ((req & VM_ALLOC_WIRED) != 0)
m->wire_count = 0;
- if (m >= m_tmp)
+ if (m >= m_tmp) {
m->object = NULL;
+ m->oflags |= VPO_UNMANAGED;
+ }
vm_page_free(m);
}
return (NULL);
@@ -3288,7 +3290,8 @@
cache_was_empty = vm_radix_is_empty(&object->cache);
if (vm_radix_insert(&object->cache, m)) {
mtx_unlock(&vm_page_queue_free_mtx);
- if (object->resident_page_count == 0)
+ if (object->type == OBJT_VNODE &&
+ object->resident_page_count == 0)
vdrop(object->handle);
m->object = NULL;
vm_page_free(m);

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 15, 4:48 AM (12 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
9091418
Default Alt Text
D6085.id15571.diff (5 KB)

Event Timeline