summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-11-25 19:19:15 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-11-25 19:19:15 +0000
commiteeac4469fdaaf0d08c398d789b535b8ed2dd5433 (patch)
tree732fbc7556dba4cb02bf8442fc2d107a2632822d /sys/uvm
parent7093c79be6c40e8404e2ccd873052d736fdee798 (diff)
something hairy happened with cvs so this file didn't get added.
re-add uvm_objwire and uvm_objunwire. "you may commit that" kettenis@ original diff oked by ariane@ and art@
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_object.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/sys/uvm/uvm_object.c b/sys/uvm/uvm_object.c
new file mode 100644
index 00000000000..3c92593581c
--- /dev/null
+++ b/sys/uvm/uvm_object.c
@@ -0,0 +1,159 @@
+/* $OpenBSD: uvm_object.c,v 1.3 2009/11/25 19:19:14 oga Exp $ */
+
+/*
+ * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * uvm_object.c: operate with memory objects
+ *
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+
+#include <uvm/uvm.h>
+
+/* We will fetch this page count per step */
+#define FETCH_PAGECOUNT 16
+
+/*
+ * uvm_objwire: wire the pages of entire uobj
+ *
+ * => caller must pass page-aligned start and end values
+ * => if the caller passes in a pageq pointer, we'll return a list of
+ * wired pages.
+ */
+
+int
+uvm_objwire(struct uvm_object *uobj, off_t start, off_t end,
+ struct pglist *pageq)
+{
+ int i, npages, error;
+ struct vm_page *pgs[FETCH_PAGECOUNT];
+ off_t offset = start, left;
+
+ left = (end - start) >> PAGE_SHIFT;
+
+ simple_lock(&uobj->vmobjlock);
+ while (left) {
+
+ npages = MIN(FETCH_PAGECOUNT, left);
+
+ /* Get the pages */
+ memset(pgs, 0, sizeof(pgs));
+ error = (*uobj->pgops->pgo_get)(uobj, offset, pgs, &npages, 0,
+ VM_PROT_READ | VM_PROT_WRITE, UVM_ADV_SEQUENTIAL,
+ PGO_ALLPAGES | PGO_SYNCIO);
+
+ if (error)
+ goto error;
+
+ simple_lock(&uobj->vmobjlock);
+ for (i = 0; i < npages; i++) {
+
+ KASSERT(pgs[i] != NULL);
+ KASSERT(!(pgs[i]->pg_flags & PG_RELEASED));
+
+#if 0
+ /*
+ * Loan break
+ */
+ if (pgs[i]->loan_count) {
+ while (pgs[i]->loan_count) {
+ pg = uvm_loanbreak(pgs[i]);
+ if (!pg) {
+ simple_unlock(&uobj->vmobjlock);
+ uvm_wait("uobjwirepg");
+ simple_lock(&uobj->vmobjlock);
+ continue;
+ }
+ }
+ pgs[i] = pg;
+ }
+#endif
+
+ if (pgs[i]->pg_flags & PQ_AOBJ) {
+ atomic_clearbits_int(&pgs[i]->pg_flags,
+ PG_CLEAN);
+ uao_dropswap(uobj, i);
+ }
+ }
+
+ /* Wire the pages */
+ uvm_lock_pageq();
+ for (i = 0; i < npages; i++) {
+ uvm_pagewire(pgs[i]);
+ if (pageq != NULL)
+ TAILQ_INSERT_TAIL(pageq, pgs[i], pageq);
+ }
+ uvm_unlock_pageq();
+
+ /* Unbusy the pages */
+ uvm_page_unbusy(pgs, npages);
+
+ left -= npages;
+ offset += npages << PAGE_SHIFT;
+ }
+ simple_unlock(&uobj->vmobjlock);
+
+ return 0;
+
+error:
+ /* Unwire the pages which have been wired */
+ uvm_objunwire(uobj, start, offset);
+
+ return error;
+}
+
+/*
+ * uobj_unwirepages: unwire the pages of entire uobj
+ *
+ * => caller must pass page-aligned start and end values
+ */
+
+void
+uvm_objunwire(struct uvm_object *uobj, off_t start, off_t end)
+{
+ struct vm_page *pg;
+ off_t offset;
+
+ simple_lock(&uobj->vmobjlock);
+ uvm_lock_pageq();
+ for (offset = start; offset < end; offset += PAGE_SIZE) {
+ pg = uvm_pagelookup(uobj, offset);
+
+ KASSERT(pg != NULL);
+ KASSERT(!(pg->pg_flags & PG_RELEASED));
+
+ uvm_pageunwire(pg);
+ }
+ uvm_unlock_pageq();
+ simple_unlock(&uobj->vmobjlock);
+}