mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-12 14:29:28 +00:00
Lock the vm object when freeing a vm page.
This commit is contained in:
parent
da9f245470
commit
31953be936
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=116512
@ -676,11 +676,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
* if we can't bmap, use old VOP code
|
||||
*/
|
||||
if (VOP_BMAP(vp, 0, &dp, 0, NULL, NULL)) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
for (i = 0; i < count; i++)
|
||||
if (i != reqpage)
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
cnt.v_vnodein++;
|
||||
cnt.v_vnodepgsin++;
|
||||
return vnode_pager_input_old(object, m[reqpage]);
|
||||
@ -692,11 +694,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
*/
|
||||
} else if ((PAGE_SIZE / bsize) > 1 &&
|
||||
(vp->v_mount->mnt_stat.f_type != nfs_mount_type)) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
for (i = 0; i < count; i++)
|
||||
if (i != reqpage)
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
cnt.v_vnodein++;
|
||||
cnt.v_vnodepgsin++;
|
||||
return vnode_pager_input_smlfs(object, m[reqpage]);
|
||||
@ -708,11 +712,13 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
* media.
|
||||
*/
|
||||
if (m[reqpage]->valid == VM_PAGE_BITS_ALL) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
for (i = 0; i < count; i++)
|
||||
if (i != reqpage)
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
return VM_PAGER_OK;
|
||||
}
|
||||
m[reqpage]->valid = 0;
|
||||
@ -729,6 +735,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
firstaddr = vnode_pager_addr(vp,
|
||||
IDX_TO_OFF(m[i]->pindex), &runpg);
|
||||
if (firstaddr == -1) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
if (i == reqpage && foff < object->un_pager.vnp.vnp_size) {
|
||||
panic("vnode_pager_getpages: unexpected missing page: firstaddr: %d, foff: 0x%jx%08jx, vnp_size: 0x%jx%08jx",
|
||||
firstaddr, (uintmax_t)(foff >> 32),
|
||||
@ -740,22 +747,27 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
vm_page_lock_queues();
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
runend = i + 1;
|
||||
first = runend;
|
||||
continue;
|
||||
}
|
||||
runend = i + runpg;
|
||||
if (runend <= reqpage) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
for (j = i; j < runend; j++)
|
||||
vm_page_free(m[j]);
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
} else {
|
||||
if (runpg < (count - first)) {
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
for (i = first + runpg; i < count; i++)
|
||||
vm_page_free(m[i]);
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
count = first + runpg;
|
||||
}
|
||||
break;
|
||||
@ -849,6 +861,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
*/
|
||||
relpbuf(bp, &vnode_pbuf_freecnt);
|
||||
|
||||
VM_OBJECT_LOCK(object);
|
||||
vm_page_lock_queues();
|
||||
for (i = 0, tfoff = foff; i < count; i++, tfoff = nextoff) {
|
||||
vm_page_t mt;
|
||||
@ -907,6 +920,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage)
|
||||
}
|
||||
}
|
||||
vm_page_unlock_queues();
|
||||
VM_OBJECT_UNLOCK(object);
|
||||
if (error) {
|
||||
printf("vnode_pager_getpages: I/O read error\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user