From owner-svn-src-stable@FreeBSD.ORG Wed Apr 14 16:31:59 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B3C61106566C; Wed, 14 Apr 2010 16:31:59 +0000 (UTC) (envelope-from alc@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A22D18FC0A; Wed, 14 Apr 2010 16:31:59 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o3EGVxSA025340; Wed, 14 Apr 2010 16:31:59 GMT (envelope-from alc@svn.freebsd.org) Received: (from alc@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o3EGVxvA025337; Wed, 14 Apr 2010 16:31:59 GMT (envelope-from alc@svn.freebsd.org) Message-Id: <201004141631.o3EGVxvA025337@svn.freebsd.org> From: Alan Cox Date: Wed, 14 Apr 2010 16:31:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r206607 - stable/8/sys/vm X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 14 Apr 2010 16:31:59 -0000 Author: alc Date: Wed Apr 14 16:31:59 2010 New Revision: 206607 URL: http://svn.freebsd.org/changeset/base/206607 Log: MFC r206409 Introduce the function kmem_alloc_attr(), which allocates kernel virtual memory with the specified physical attributes. Correct an error in the prototype for kmem_malloc(). Modified: stable/8/sys/vm/vm_contig.c stable/8/sys/vm/vm_extern.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/vm/vm_contig.c ============================================================================== --- stable/8/sys/vm/vm_contig.c Wed Apr 14 15:33:30 2010 (r206606) +++ stable/8/sys/vm/vm_contig.c Wed Apr 14 16:31:59 2010 (r206607) @@ -87,6 +87,8 @@ __FBSDID("$FreeBSD$"); #include #include +static void vm_contig_grow_cache(int tries); + static int vm_contig_launder_page(vm_page_t m, vm_page_t *next) { @@ -186,6 +188,99 @@ vm_page_release_contig(vm_page_t m, vm_p } /* + * Increase the number of cached pages. + */ +static void +vm_contig_grow_cache(int tries) +{ + int actl, actmax, inactl, inactmax; + + vm_page_lock_queues(); + inactl = 0; + inactmax = tries < 1 ? 0 : cnt.v_inactive_count; + actl = 0; + actmax = tries < 2 ? 0 : cnt.v_active_count; +again: + if (inactl < inactmax && vm_contig_launder(PQ_INACTIVE)) { + inactl++; + goto again; + } + if (actl < actmax && vm_contig_launder(PQ_ACTIVE)) { + actl++; + goto again; + } + vm_page_unlock_queues(); +} + +/* + * Allocates a region from the kernel address map and pages within the + * specified physical address range to the kernel object, creates a wired + * mapping from the region to these pages, and returns the region's starting + * virtual address. The allocated pages are not necessarily physically + * contiguous. If M_ZERO is specified through the given flags, then the pages + * are zeroed before they are mapped. + */ +vm_offset_t +kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low, + vm_paddr_t high, vm_memattr_t memattr) +{ + vm_object_t object = kernel_object; + vm_offset_t addr, i, offset; + vm_page_t m; + int tries; + + size = round_page(size); + vm_map_lock(map); + if (vm_map_findspace(map, vm_map_min(map), size, &addr)) { + vm_map_unlock(map); + return (0); + } + offset = addr - VM_MIN_KERNEL_ADDRESS; + vm_object_reference(object); + vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL, + VM_PROT_ALL, 0); + VM_OBJECT_LOCK(object); + for (i = 0; i < size; i += PAGE_SIZE) { + tries = 0; +retry: + m = vm_phys_alloc_contig(1, low, high, PAGE_SIZE, 0); + if (m == NULL) { + if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) { + VM_OBJECT_UNLOCK(object); + vm_map_unlock(map); + vm_contig_grow_cache(tries); + vm_map_lock(map); + VM_OBJECT_LOCK(object); + goto retry; + } + while (i != 0) { + i -= PAGE_SIZE; + m = vm_page_lookup(object, OFF_TO_IDX(offset + + i)); + vm_page_lock_queues(); + vm_page_free(m); + vm_page_unlock_queues(); + } + VM_OBJECT_UNLOCK(object); + vm_map_delete(map, addr, addr + size); + vm_map_unlock(map); + return (0); + } + if (memattr != VM_MEMATTR_DEFAULT) + pmap_page_set_memattr(m, memattr); + vm_page_insert(m, object, OFF_TO_IDX(offset + i)); + if ((flags & M_ZERO) && (m->flags & PG_ZERO) == 0) + pmap_zero_page(m); + m->valid = VM_PAGE_BITS_ALL; + } + VM_OBJECT_UNLOCK(object); + vm_map_unlock(map); + vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM | + VM_MAP_WIRE_NOHOLES); + return (addr); +} + +/* * Allocates a region from the kernel address map, inserts the * given physically contiguous pages into the kernel object, * creates a wired mapping from the region to the pages, and @@ -253,7 +348,7 @@ kmem_alloc_contig(vm_map_t map, vm_size_ vm_offset_t ret; vm_page_t pages; unsigned long npgs; - int actl, actmax, inactl, inactmax, tries; + int tries; size = round_page(size); npgs = size >> PAGE_SHIFT; @@ -262,23 +357,7 @@ retry: pages = vm_phys_alloc_contig(npgs, low, high, alignment, boundary); if (pages == NULL) { if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) { - vm_page_lock_queues(); - inactl = 0; - inactmax = tries < 1 ? 0 : cnt.v_inactive_count; - actl = 0; - actmax = tries < 2 ? 0 : cnt.v_active_count; -again: - if (inactl < inactmax && - vm_contig_launder(PQ_INACTIVE)) { - inactl++; - goto again; - } - if (actl < actmax && - vm_contig_launder(PQ_ACTIVE)) { - actl++; - goto again; - } - vm_page_unlock_queues(); + vm_contig_grow_cache(tries); tries++; goto retry; } Modified: stable/8/sys/vm/vm_extern.h ============================================================================== --- stable/8/sys/vm/vm_extern.h Wed Apr 14 15:33:30 2010 (r206606) +++ stable/8/sys/vm/vm_extern.h Wed Apr 14 16:31:59 2010 (r206607) @@ -41,6 +41,8 @@ struct vnode; int kernacc(void *, int, int); vm_offset_t kmem_alloc(vm_map_t, vm_size_t); +vm_offset_t kmem_alloc_attr(vm_map_t map, vm_size_t size, int flags, + vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr); vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, unsigned long alignment, unsigned long boundary, vm_memattr_t memattr); @@ -49,7 +51,7 @@ vm_offset_t kmem_alloc_wait(vm_map_t, vm void kmem_free(vm_map_t, vm_offset_t, vm_size_t); void kmem_free_wakeup(vm_map_t, vm_offset_t, vm_size_t); void kmem_init(vm_offset_t, vm_offset_t); -vm_offset_t kmem_malloc(vm_map_t, vm_size_t, boolean_t); +vm_offset_t kmem_malloc(vm_map_t map, vm_size_t size, int flags); vm_map_t kmem_suballoc(vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t, boolean_t); void swapout_procs(int);