Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jun 2012 21:25:21 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r236925 - stable/9/sys/vm
Message-ID:  <201206112125.q5BLPLxS011051@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Jun 11 21:25:20 2012
New Revision: 236925
URL: http://svn.freebsd.org/changeset/base/236925

Log:
  MFC r235375:
  Add new pager type, OBJT_MGTDEVICE. It provides the device pager
  which carries fictitous managed pges. In particular, the consumers of
  the new object type can remove all mappings of the device page with
  pmap_remove_all().
  
  The range of physical addresses used for fake page allocation shall be
  registered with vm_phys_fictitious_reg_range() interface to allow the
  PHYS_TO_VM_PAGE() to work in pmap.

Modified:
  stable/9/sys/vm/device_pager.c
  stable/9/sys/vm/vm.h
  stable/9/sys/vm/vm_pager.c
  stable/9/sys/vm/vm_pager.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/vm/device_pager.c
==============================================================================
--- stable/9/sys/vm/device_pager.c	Mon Jun 11 21:19:59 2012	(r236924)
+++ stable/9/sys/vm/device_pager.c	Mon Jun 11 21:25:20 2012	(r236925)
@@ -61,6 +61,7 @@ static void dev_pager_putpages(vm_object
 		boolean_t, int *);
 static boolean_t dev_pager_haspage(vm_object_t, vm_pindex_t, int *,
 		int *);
+static void dev_pager_free_page(vm_object_t object, vm_page_t m);
 
 /* list of device pager objects */
 static struct pagerlst dev_pager_object_list;
@@ -76,6 +77,14 @@ struct pagerops devicepagerops = {
 	.pgo_haspage =	dev_pager_haspage,
 };
 
+struct pagerops mgtdevicepagerops = {
+	.pgo_alloc =	dev_pager_alloc,
+	.pgo_dealloc =	dev_pager_dealloc,
+	.pgo_getpages =	dev_pager_getpages,
+	.pgo_putpages =	dev_pager_putpages,
+	.pgo_haspage =	dev_pager_haspage,
+};
+
 static int old_dev_pager_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
     vm_ooffset_t foff, struct ucred *cred, u_short *color);
 static void old_dev_pager_dtor(void *handle);
@@ -114,7 +123,7 @@ cdev_pager_allocate(void *handle, enum o
 	vm_pindex_t pindex;
 	u_short color;
 
-	if (tp != OBJT_DEVICE)
+	if (tp != OBJT_DEVICE && tp != OBJT_MGTDEVICE)
 		return (NULL);
 
 	/*
@@ -195,6 +204,24 @@ cdev_pager_free_page(vm_object_t object,
 {
 
 	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+	if (object->type == OBJT_MGTDEVICE) {
+		KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("unmanaged %p", m));
+		pmap_remove_all(m);
+		vm_page_lock(m);
+		vm_page_remove(m);
+		vm_page_unlock(m);
+	} else if (object->type == OBJT_DEVICE)
+		dev_pager_free_page(object, m);
+}
+
+static void
+dev_pager_free_page(vm_object_t object, vm_page_t m)
+{
+
+	VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
+	KASSERT((object->type == OBJT_DEVICE &&
+	    (m->oflags & VPO_UNMANAGED) != 0),
+	    ("Managed device or page obj %p m %p", object, m));
 	TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, pageq);
 	vm_page_putfake(m);
 }
@@ -212,11 +239,15 @@ dev_pager_dealloc(object)
 	TAILQ_REMOVE(&dev_pager_object_list, object, pager_object_list);
 	mtx_unlock(&dev_pager_mtx);
 	VM_OBJECT_LOCK(object);
-	/*
-	 * Free up our fake pages.
-	 */
-	while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist)) != NULL)
-		cdev_pager_free_page(object, m);
+
+	if (object->type == OBJT_DEVICE) {
+		/*
+		 * Free up our fake pages.
+		 */
+		while ((m = TAILQ_FIRST(&object->un_pager.devp.devp_pglist))
+		    != NULL)
+			dev_pager_free_page(object, m);
+	}
 }
 
 static int
@@ -239,8 +270,15 @@ dev_pager_getpages(vm_object_t object, v
 	}
 
 	if (error == VM_PAGER_OK) {
-		TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist,
-		    ma[reqpage], pageq);
+		KASSERT((object->type == OBJT_DEVICE &&
+		     (ma[reqpage]->oflags & VPO_UNMANAGED) != 0) ||
+		    (object->type == OBJT_MGTDEVICE &&
+		     (ma[reqpage]->oflags & VPO_UNMANAGED) == 0),
+		    ("Wrong page type %p %p", ma[reqpage], object));
+		if (object->type == OBJT_DEVICE) {
+			TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist,
+			    ma[reqpage], pageq);
+		}
 	}
 
 	return (error);

Modified: stable/9/sys/vm/vm.h
==============================================================================
--- stable/9/sys/vm/vm.h	Mon Jun 11 21:19:59 2012	(r236924)
+++ stable/9/sys/vm/vm.h	Mon Jun 11 21:25:20 2012	(r236925)
@@ -83,7 +83,7 @@ typedef u_char vm_prot_t;	/* protection 
 #define	VM_PROT_DEFAULT		VM_PROT_ALL
 
 enum obj_type { OBJT_DEFAULT, OBJT_SWAP, OBJT_VNODE, OBJT_DEVICE, OBJT_PHYS,
-		OBJT_DEAD, OBJT_SG };
+		OBJT_DEAD, OBJT_SG, OBJT_MGTDEVICE };
 typedef u_char objtype_t;
 
 union vm_map_object;

Modified: stable/9/sys/vm/vm_pager.c
==============================================================================
--- stable/9/sys/vm/vm_pager.c	Mon Jun 11 21:19:59 2012	(r236924)
+++ stable/9/sys/vm/vm_pager.c	Mon Jun 11 21:25:20 2012	(r236925)
@@ -159,7 +159,8 @@ struct pagerops *pagertab[] = {
 	&devicepagerops,	/* OBJT_DEVICE */
 	&physpagerops,		/* OBJT_PHYS */
 	&deadpagerops,		/* OBJT_DEAD */
-	&sgpagerops		/* OBJT_SG */
+	&sgpagerops,		/* OBJT_SG */
+	&mgtdevicepagerops,	/* OBJT_MGTDEVICE */
 };
 
 static const int npagers = sizeof(pagertab) / sizeof(pagertab[0]);

Modified: stable/9/sys/vm/vm_pager.h
==============================================================================
--- stable/9/sys/vm/vm_pager.h	Mon Jun 11 21:19:59 2012	(r236924)
+++ stable/9/sys/vm/vm_pager.h	Mon Jun 11 21:25:20 2012	(r236925)
@@ -71,6 +71,7 @@ extern struct pagerops vnodepagerops;
 extern struct pagerops devicepagerops;
 extern struct pagerops physpagerops;
 extern struct pagerops sgpagerops;
+extern struct pagerops mgtdevicepagerops;
 
 /*
  * get/put return values



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206112125.q5BLPLxS011051>