From owner-svn-src-head@FreeBSD.ORG Sat May 12 20:49:59 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8D28E1065679; Sat, 12 May 2012 20:49:59 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6D5068FC26; Sat, 12 May 2012 20:49:59 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4CKnxNd051887; Sat, 12 May 2012 20:49:59 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4CKnx67051882; Sat, 12 May 2012 20:49:59 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201205122049.q4CKnx67051882@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 12 May 2012 20:49:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r235375 - head/sys/vm X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 May 2012 20:49:59 -0000 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