summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-06-18 04:27:18 +0000
committeralc <alc@FreeBSD.org>2003-06-18 04:27:18 +0000
commitcacc52e8aa28d836df641ea037690d2b04cb4dcc (patch)
treee7e7f5015a9cc484acf363887e325f7b9498d795 /sys/vm
parentb466954d4e6ffa78f98b19458bcf1560d8d8c776 (diff)
downloadFreeBSD-src-cacc52e8aa28d836df641ea037690d2b04cb4dcc.zip
FreeBSD-src-cacc52e8aa28d836df641ea037690d2b04cb4dcc.tar.gz
Lock the vm object when freeing a vm page.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vnode_pager.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 993725d..bfc255d 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -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");
}
OpenPOWER on IntegriCloud