Subject: uobj_wirepages/unwirepages
To: None <tech-kern@netbsd.org>
From: Mindaugas <unex@linija.org>
List: tech-kern
Date: 10/10/2006 01:56:22
This is a multi-part message in MIME format.

--Multipart=_Tue__10_Oct_2006_01_56_22_+0300_vzpBg/0NQBeRnEuo
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

Hello,
as cleared up in previous topic (SysV SHM locking and reallocating
support) we need an additional UVM functionality for ability to lock
the objects into the physical memory.
Here is the uobj_wirepages and uobj_unwirepages functions for UVM. As
suggested by Chuck, I put them into the uvm_object.c file.
Functions has been tested and debuged, and according to vmstat, seems
wiring/unwiring works fine, finally.

Please review and comment an attached source, before I submit it in a
PR. After this I will prepare and submit a patch for SHM stuff.

Thanks YAMAMOTO who showed the way and huge thanks for Chuck who
explained me a lot of UVM things.

-- 
Best regards,
Mindaugas

--Multipart=_Tue__10_Oct_2006_01_56_22_+0300_vzpBg/0NQBeRnEuo
Content-Type: application/octet-stream;
 name="uvm_object.c"
Content-Disposition: attachment;
 filename="uvm_object.c"
Content-Transfer-Encoding: quoted-printable

/*	$NetBSD$	*/

/*
 * Copyright (c) 2006 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the NetBSD
 *      Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMI=
TED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICUL=
AR
 * 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 T=
HE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * uvm_object.c: operate with memory objects
 *
 * TODO:
 *  1. Support PG_RELEASED-using objects
 *
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD$");

#include "opt_uvmhist.h"

#include <sys/param.h>
#include <sys/lock.h>

#include <uvm/uvm.h>

/* We will fetch this page count per step */
#define	FETCH_PAGECOUNT	16

/*
 * uobj_wirepages: wire the pages of entire uobj
 *
 * =3D> NOTE: this function should only be used for types of objects
 *  where PG_RELEASED flag is never set (aobj objects)
 * =3D> caller must pass page-aligned start and end values
 */

int
uobj_wirepages(struct uvm_object *uobj, off_t start, off_t end)
{
	int i, npages =3D FETCH_PAGECOUNT, error;
	struct vm_page *pgs[FETCH_PAGECOUNT], *pg =3D NULL;
	off_t offset =3D start, left;

	left =3D (end - start) >> PAGE_SHIFT;

	simple_lock(&uobj->vmobjlock);
	while (left) {

		npages =3D MIN(FETCH_PAGECOUNT, left);

		/* Get the pages */
		memset(pgs, 0, sizeof(pgs));
		error =3D (*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 =3D 0; i < npages; i++) {

			KASSERT(pgs[i] !=3D NULL);
			KASSERT(!(pgs[i]->flags & PG_RELEASED));

			/*
			 * Loan break
			 */
			if (pgs[i]->loan_count) {
				while (pgs[i]->loan_count) {
					pg =3D uvm_loanbreak(pgs[i]);
					if (!pg) {
						simple_unlock(&uobj->vmobjlock);
						uvm_wait("uobjwirepg");
						simple_lock(&uobj->vmobjlock);
						continue;
					}
				}
				pgs[i] =3D pg;
			}

			if (pgs[i]->pqflags & PQ_AOBJ) {
				pgs[i]->flags &=3D ~(PG_CLEAN);
				uao_dropswap(uobj, i);
			}
		}

		/* Unwire the pages */
		uvm_lock_pageq();
		for (i =3D 0; i < npages; i++) {
			uvm_pagewire(pgs[i]);
		}
		uvm_unlock_pageq();

		/* Unbusy the pages */
		uvm_page_unbusy(pgs, npages);

		left -=3D npages;
		offset +=3D npages << PAGE_SHIFT;
	}
	simple_unlock(&uobj->vmobjlock);

	return 0;

error:
	/* Unwire the pages which has been wired */
	uobj_unwirepages(uobj, offset, end);

	return error;
}

/*
 * uobj_unwirepages: unwire the pages of entire uobj
 *
 * =3D> NOTE: this function should only be used for types of objects
 *  where PG_RELEASED flag is never set
 * =3D> caller must pass page-aligned start and end values
 */

void
uobj_unwirepages(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 =3D start; offset < end; offset +=3D PAGE_SIZE) {
		pg =3D uvm_pagelookup(uobj, offset);

		KASSERT(pg !=3D NULL);
		KASSERT(!(pg->flags & PG_RELEASED));

		uvm_pageunwire(pg);
	}
	uvm_unlock_pageq();
	simple_unlock(&uobj->vmobjlock);
}


--Multipart=_Tue__10_Oct_2006_01_56_22_+0300_vzpBg/0NQBeRnEuo
Content-Type: application/octet-stream;
 name="uobj_wiring.patch"
Content-Disposition: attachment;
 filename="uobj_wiring.patch"
Content-Transfer-Encoding: quoted-printable

Index: sys/uvm/files.uvm
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/uvm/files.uvm,v
retrieving revision 1.6
diff -u -r1.6 files.uvm
--- sys/uvm/files.uvm	30 Sep 2006 15:38:06 -0000	1.6
+++ sys/uvm/files.uvm	9 Oct 2006 22:19:18 -0000
@@ -25,6 +25,7 @@
 file	uvm/uvm_meter.c
 file	uvm/uvm_mmap.c
 file	uvm/uvm_mremap.c		compat_linux
+file	uvm/uvm_object.c
 file	uvm/uvm_page.c
 file	uvm/uvm_pager.c
 file	uvm/uvm_pdaemon.c
Index: sys/uvm/uvm_extern.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/uvm/uvm_extern.h,v
retrieving revision 1.119
diff -u -r1.119 uvm_extern.h
--- sys/uvm/uvm_extern.h	5 Oct 2006 14:48:33 -0000	1.119
+++ sys/uvm/uvm_extern.h	9 Oct 2006 22:19:18 -0000
@@ -653,6 +653,12 @@
 			    struct proc *, int);
 #define	UVM_MREMAP_FIXED	1
=20
+/* uvm_object.c */
+int			uobj_wirepages(struct uvm_object *uobj, off_t start,
+			    off_t end);
+void			uobj_unwirepages(struct uvm_object *uobj, off_t start,
+			    off_t end);
+
 /* uvm_page.c */
 struct vm_page		*uvm_pagealloc_strat(struct uvm_object *,
 			    voff_t, struct vm_anon *, int, int, int);
Index: sys/uvm/uvm_object.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/uvm/uvm_object.h,v
retrieving revision 1.21
diff -u -r1.21 uvm_object.h
--- sys/uvm/uvm_object.h	11 Dec 2005 12:25:29 -0000	1.21
+++ sys/uvm/uvm_object.h	9 Oct 2006 22:19:18 -0000
@@ -118,4 +118,11 @@
=20
 #endif /* _KERNEL */
=20
+/*
+ * prototypes
+ */
+
+int uobj_wirepages(struct uvm_object *uobj, off_t start, off_t end);
+void uobj_unwirepages(struct uvm_object *uobj, off_t start, off_t end);
+
 #endif /* _UVM_UVM_OBJECT_H_ */

--Multipart=_Tue__10_Oct_2006_01_56_22_+0300_vzpBg/0NQBeRnEuo--