svn commit: r235375 - head/sys/vm

Konstantin Belousov kib at FreeBSD.org
Sat May 12 20:49:59 UTC 2012


Author: kib
Date: Sat May 12 20:49:58 2012
New Revision: 235375
URL: http://svn.freebsd.org/changeset/base/235375

Log:
  Add new pager type, OBJT_MGTDEVICE. It provides the device pager
  which carries fictitous managed pages. 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.
  
  Most likely, only i386 and amd64 pmaps can handle fictitious managed
  pages right now.
  
  Sponsored by:	The FreeBSD Foundation
  Reviewed by:	alc
  MFC after:	1 month

Modified:
  head/sys/vm/device_pager.c
  head/sys/vm/vm.h
  head/sys/vm/vm_pager.c
  head/sys/vm/vm_pager.h

Modified: head/sys/vm/device_pager.c
==============================================================================
--- head/sys/vm/device_pager.c	Sat May 12 20:49:02 2012	(r235374)
+++ head/sys/vm/device_pager.c	Sat May 12 20:49:58 2012	(r235375)
@@ -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);
@@ -115,7 +124,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);
 
 	/*
@@ -196,6 +205,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);
 }
@@ -213,11 +240,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
@@ -240,8 +271,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: head/sys/vm/vm.h
==============================================================================
--- head/sys/vm/vm.h	Sat May 12 20:49:02 2012	(r235374)
+++ head/sys/vm/vm.h	Sat May 12 20:49:58 2012	(r235375)
@@ -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: head/sys/vm/vm_pager.c
==============================================================================
--- head/sys/vm/vm_pager.c	Sat May 12 20:49:02 2012	(r235374)
+++ head/sys/vm/vm_pager.c	Sat May 12 20:49:58 2012	(r235375)
@@ -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: head/sys/vm/vm_pager.h
==============================================================================
--- head/sys/vm/vm_pager.h	Sat May 12 20:49:02 2012	(r235374)
+++ head/sys/vm/vm_pager.h	Sat May 12 20:49:58 2012	(r235375)
@@ -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


More information about the svn-src-head mailing list