summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-06-13 03:02:28 +0000
committeralc <alc@FreeBSD.org>2003-06-13 03:02:28 +0000
commitd66a37a0f2941403e0d02a5cb82f14bdb07338cc (patch)
tree131300009b7d968e4f3ac335ab6af00d92af89ef /sys/vm
parentf7366986b75e25cef2a0167fe951b8ee613d671a (diff)
downloadFreeBSD-src-d66a37a0f2941403e0d02a5cb82f14bdb07338cc.zip
FreeBSD-src-d66a37a0f2941403e0d02a5cb82f14bdb07338cc.tar.gz
Add vm object locking to various pagers' "get pages" methods, i386 stack
management functions, and a u area management function.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/device_pager.c3
-rw-r--r--sys/vm/swap_pager.c9
-rw-r--r--sys/vm/vm_glue.c2
-rw-r--r--sys/vm/vm_pager.h7
-rw-r--r--sys/vm/vnode_pager.c3
5 files changed, 17 insertions, 7 deletions
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 4503a0b..d96cd85 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -212,9 +212,9 @@ dev_pager_getpages(object, m, count, reqpage)
d_mmap_t *mapfunc;
int prot;
- mtx_assert(&Giant, MA_OWNED);
dev = object->handle;
offset = m[reqpage]->pindex;
+ VM_OBJECT_UNLOCK(object);
prot = PROT_READ; /* XXX should pass in? */
mapfunc = devsw(dev)->d_mmap;
@@ -228,6 +228,7 @@ dev_pager_getpages(object, m, count, reqpage)
* free up the all of the original pages.
*/
page = dev_pager_getfake(paddr);
+ VM_OBJECT_LOCK(object);
TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq);
vm_page_lock_queues();
for (i = 0; i < count; i++)
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 4ddc7fe..e1880f8 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -1006,8 +1006,6 @@ swap_pager_getpages(object, m, count, reqpage)
daddr_t blk;
vm_pindex_t lastpindex;
- GIANT_REQUIRED;
-
mreq = m[reqpage];
if (mreq->object != object) {
@@ -1075,6 +1073,10 @@ swap_pager_getpages(object, m, count, reqpage)
return (VM_PAGER_FAIL);
/*
+ * Getpbuf() can sleep.
+ */
+ VM_OBJECT_UNLOCK(object);
+ /*
* Get a swap buffer header to perform the IO
*/
bp = getpbuf(&nsw_rcount);
@@ -1095,6 +1097,7 @@ swap_pager_getpages(object, m, count, reqpage)
bp->b_bufsize = PAGE_SIZE * (j - i);
bp->b_pager.pg_reqpage = reqpage - i;
+ VM_OBJECT_LOCK(object);
vm_page_lock_queues();
{
int k;
@@ -1105,6 +1108,7 @@ swap_pager_getpages(object, m, count, reqpage)
}
}
vm_page_unlock_queues();
+ VM_OBJECT_UNLOCK(object);
bp->b_npages = j - i;
pbgetvp(swapdev_vp, bp);
@@ -1157,6 +1161,7 @@ swap_pager_getpages(object, m, count, reqpage)
vm_page_unlock_queues();
splx(s);
+ VM_OBJECT_LOCK(mreq->object);
/*
* mreq is left busied after completion, but all the other pages
* are freed. If we had an unrecoverable read error the page will
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 741bd0d..ec15d96 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -322,6 +322,7 @@ vm_proc_swapin(struct proc *p)
int i;
upobj = p->p_upages_obj;
+ VM_OBJECT_LOCK(upobj);
for (i = 0; i < UAREA_PAGES; i++) {
m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
if (m->valid != VM_PAGE_BITS_ALL) {
@@ -331,7 +332,6 @@ vm_proc_swapin(struct proc *p)
}
ma[i] = m;
}
- VM_OBJECT_LOCK(upobj);
if (upobj->resident_page_count != UAREA_PAGES)
panic("vm_proc_swapin: lost pages from upobj");
vm_page_lock_queues();
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 07b6878..c578c36 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -119,14 +119,17 @@ vm_pager_get_pages(
int count,
int reqpage
) {
+ int is_object_locked;
int r;
- GIANT_REQUIRED;
-
+ if (!(is_object_locked = VM_OBJECT_LOCKED(object)))
+ VM_OBJECT_LOCK(object);
r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage);
if (r == VM_PAGER_OK && m[reqpage]->valid != VM_PAGE_BITS_ALL) {
vm_page_zero_invalid(m[reqpage], TRUE);
}
+ if (!is_object_locked)
+ VM_OBJECT_UNLOCK(object);
return (r);
}
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index a6869b0..993725d 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -623,11 +623,12 @@ vnode_pager_getpages(object, m, count, reqpage)
struct vnode *vp;
int bytes = count * PAGE_SIZE;
- GIANT_REQUIRED;
vp = object->handle;
+ VM_OBJECT_UNLOCK(object);
rtval = VOP_GETPAGES(vp, m, bytes, reqpage, 0);
KASSERT(rtval != EOPNOTSUPP,
("vnode_pager: FS getpages not implemented\n"));
+ VM_OBJECT_LOCK(object);
return rtval;
}
OpenPOWER on IntegriCloud