FreeBSD Bugzilla – Attachment 169679 Details for
Bug 204426
Processes terminating cannot access memory
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch from D6085, adopted for stable/10.
1.patch (text/plain), 5.29 KB, created by
Konstantin Belousov
on 2016-04-25 15:13:33 UTC
(
hide
)
Description:
Patch from D6085, adopted for stable/10.
Filename:
MIME Type:
Creator:
Konstantin Belousov
Created:
2016-04-25 15:13:33 UTC
Size:
5.29 KB
patch
obsolete
>Index: sys/vm/vm_fault.c >=================================================================== >--- sys/vm/vm_fault.c (revision 298579) >+++ sys/vm/vm_fault.c (working copy) >@@ -137,7 +137,12 @@ release_page(struct faultstate *fs) > > 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; > } >@@ -294,7 +299,7 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_ > struct faultstate fs; > struct vnode *vp; > vm_page_t m; >- int locked, error; >+ int locked, error, dead; > > hardfault = 0; > growstack = TRUE; >@@ -414,7 +419,7 @@ fast_failed: > > fs.lookup_still_valid = TRUE; > >- fs.first_m = NULL; >+ fs.m = fs.first_m = NULL; > > /* > * Search for the page at object/offset. >@@ -423,11 +428,20 @@ fast_failed: > 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; > } > > /* >@@ -843,6 +857,8 @@ vnode_locked: > */ > 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 (revision 298579) >+++ sys/vm/vm_object.c (working copy) >@@ -1583,7 +1583,7 @@ vm_object_backing_scan(vm_object_t object, int op) > 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, >@@ -1673,11 +1673,14 @@ vm_object_qcollapse(vm_object_t object) > void > vm_object_collapse(vm_object_t object) > { >+ vm_object_t backing_object, new_backing_object; >+ > VM_OBJECT_ASSERT_WLOCKED(object); >- >+ >+ if ((object->flags & OBJ_DEAD) != 0) >+ return; >+ vm_object_pip_add(object, 1); > while (TRUE) { >- vm_object_t backing_object; >- > /* > * Verify that the conditions are right for collapse: > * >@@ -1703,14 +1706,14 @@ vm_object_collapse(vm_object_t object) > 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 >@@ -1793,6 +1796,7 @@ vm_object_collapse(vm_object_t object) > 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); >@@ -1800,8 +1804,6 @@ vm_object_collapse(vm_object_t object) > > 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. >@@ -1809,6 +1811,7 @@ vm_object_collapse(vm_object_t object) > if (object->resident_page_count != object->size && > !vm_object_backing_scan(object, > OBSC_TEST_ALL_SHADOWED)) { >+ vm_object_pip_wakeup(backing_object); > VM_OBJECT_WUNLOCK(backing_object); > break; > } >@@ -1841,6 +1844,7 @@ vm_object_collapse(vm_object_t object) > * 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++; > } >@@ -1849,6 +1853,7 @@ vm_object_collapse(vm_object_t object) > * 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 (revision 298579) >+++ sys/vm/vm_page.c (working copy) >@@ -1838,8 +1838,10 @@ retry: > 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); >@@ -2580,7 +2582,8 @@ vm_page_cache(vm_page_t m) > 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);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 204426
:
167570
|
168808
|
168832
|
168870
|
168872
| 169679