- 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:
Alan Cox 2003-10-19 00:01:56 +00:00
parent 7044867f83
commit 1b26eb10ff

View File

@ -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;
}