- Synchronize access to a vm page's valid field using the containing
vm object's lock. - Reduce the scope of the vm page queues lock in two places.
This commit is contained in:
parent
7044867f83
commit
1b26eb10ff
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=121230
@ -324,49 +324,48 @@ vnode_pager_setsize(vp, nsize)
|
||||
* it can screw up NFS reads, so we don't allow the case.
|
||||
*/
|
||||
if ((nsize & PAGE_MASK) &&
|
||||
(m = vm_page_lookup(object, OFF_TO_IDX(nsize))) != NULL) {
|
||||
(m = vm_page_lookup(object, OFF_TO_IDX(nsize))) != NULL &&
|
||||
m->valid != 0) {
|
||||
int base = (int)nsize & PAGE_MASK;
|
||||
int size = PAGE_SIZE - base;
|
||||
|
||||
/*
|
||||
* Clear out partial-page garbage in case
|
||||
* the page has been mapped.
|
||||
*/
|
||||
pmap_zero_page_area(m, base, size);
|
||||
|
||||
/*
|
||||
* XXX work around SMP data integrity race
|
||||
* by unmapping the page from user processes.
|
||||
* The garbage we just cleared may be mapped
|
||||
* to a user process running on another cpu
|
||||
* and this code is not running through normal
|
||||
* I/O channels which handle SMP issues for
|
||||
* us, so unmap page to synchronize all cpus.
|
||||
*
|
||||
* XXX should vm_pager_unmap_page() have
|
||||
* dealt with this?
|
||||
*/
|
||||
vm_page_lock_queues();
|
||||
if (m->valid) {
|
||||
int base = (int)nsize & PAGE_MASK;
|
||||
int size = PAGE_SIZE - base;
|
||||
pmap_remove_all(m);
|
||||
|
||||
/*
|
||||
* Clear out partial-page garbage in case
|
||||
* the page has been mapped.
|
||||
*/
|
||||
pmap_zero_page_area(m, base, size);
|
||||
|
||||
/*
|
||||
* XXX work around SMP data integrity race
|
||||
* by unmapping the page from user processes.
|
||||
* The garbage we just cleared may be mapped
|
||||
* to a user process running on another cpu
|
||||
* and this code is not running through normal
|
||||
* I/O channels which handle SMP issues for
|
||||
* us, so unmap page to synchronize all cpus.
|
||||
*
|
||||
* XXX should vm_pager_unmap_page() have
|
||||
* dealt with this?
|
||||
*/
|
||||
pmap_remove_all(m);
|
||||
|
||||
/*
|
||||
* Clear out partial-page dirty bits. This
|
||||
* has the side effect of setting the valid
|
||||
* bits, but that is ok. There are a bunch
|
||||
* of places in the VM system where we expected
|
||||
* m->dirty == VM_PAGE_BITS_ALL. The file EOF
|
||||
* case is one of them. If the page is still
|
||||
* partially dirty, make it fully dirty.
|
||||
*
|
||||
* note that we do not clear out the valid
|
||||
* bits. This would prevent bogus_page
|
||||
* replacement from working properly.
|
||||
*/
|
||||
vm_page_set_validclean(m, base, size);
|
||||
if (m->dirty != 0)
|
||||
m->dirty = VM_PAGE_BITS_ALL;
|
||||
}
|
||||
/*
|
||||
* Clear out partial-page dirty bits. This
|
||||
* has the side effect of setting the valid
|
||||
* bits, but that is ok. There are a bunch
|
||||
* of places in the VM system where we expected
|
||||
* m->dirty == VM_PAGE_BITS_ALL. The file EOF
|
||||
* case is one of them. If the page is still
|
||||
* partially dirty, make it fully dirty.
|
||||
*
|
||||
* note that we do not clear out the valid
|
||||
* bits. This would prevent bogus_page
|
||||
* replacement from working properly.
|
||||
*/
|
||||
vm_page_set_validclean(m, base, size);
|
||||
if (m->dirty != 0)
|
||||
m->dirty = VM_PAGE_BITS_ALL;
|
||||
vm_page_unlock_queues();
|
||||
}
|
||||
}
|
||||
@ -573,14 +572,17 @@ vnode_pager_input_old(object, m)
|
||||
bzero((caddr_t) kva + count, PAGE_SIZE - count);
|
||||
}
|
||||
vm_pager_unmap_page(kva);
|
||||
|
||||
VM_OBJECT_LOCK(object);
|
||||
}
|
||||
vm_page_lock_queues();
|
||||
pmap_clear_modify(m);
|
||||
vm_page_undirty(m);
|
||||
vm_page_flag_clear(m, PG_ZERO);
|
||||
vm_page_unlock_queues();
|
||||
if (!error)
|
||||
m->valid = VM_PAGE_BITS_ALL;
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
return error ? VM_PAGER_ERROR : VM_PAGER_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user