svn commit: r212220 - user/nwhitehorn/ps3/powerpc/aim

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Sep 5 03:05:03 UTC 2010


Author: nwhitehorn
Date: Sun Sep  5 03:05:03 2010
New Revision: 212220
URL: http://svn.freebsd.org/changeset/base/212220

Log:
  Make the SLB UMA hypervisor allocator correctly free contig pages. Using
  vm_page_free() on pages allocated with vm_phys_alloc_contig() causes
  errors due to inconsistent wired-state tracking. Thanks to Colin Percival
  for helping me debug this.

Modified:
  user/nwhitehorn/ps3/powerpc/aim/slb.c
  user/nwhitehorn/ps3/powerpc/aim/uma_machdep.c

Modified: user/nwhitehorn/ps3/powerpc/aim/slb.c
==============================================================================
--- user/nwhitehorn/ps3/powerpc/aim/slb.c	Sun Sep  5 01:58:21 2010	(r212219)
+++ user/nwhitehorn/ps3/powerpc/aim/slb.c	Sun Sep  5 03:05:03 2010	(r212220)
@@ -37,7 +37,11 @@
 #include <vm/vm.h>
 #include <vm/pmap.h>
 #include <vm/uma.h>
+#include <vm/vm.h>
 #include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_phys.h>
 
 #include <machine/md_var.h>
 #include <machine/platform.h>
@@ -46,8 +50,6 @@
 
 uintptr_t moea64_get_unique_vsid(void);
 void moea64_release_vsid(uint64_t vsid);
-void *uma_small_alloc_core(uma_zone_t zone, int bytes, u_int8_t *flags,
-    int wait, vm_offset_t minphys, vm_offset_t maxphys);
 
 struct slbcontainer {
 	struct slb slb;
@@ -280,13 +282,57 @@ static void *
 slb_uma_cache_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
 {
 	static vm_offset_t realmax = 0;
+	void *va;
+	vm_page_t m;
+	int pflags;
 
 	if (realmax == 0)
 		realmax = platform_real_maxaddr();
 
-        return (uma_small_alloc_core(zone, bytes, flags, wait, 0, realmax));
+	*flags = UMA_SLAB_PRIV;
+	if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
+		pflags = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED;
+	else    
+		pflags = VM_ALLOC_SYSTEM | VM_ALLOC_WIRED;
+	if (wait & M_ZERO)
+		pflags |= VM_ALLOC_ZERO;
+
+	for (;;) {
+		m = vm_phys_alloc_contig(1, 0, realmax, PAGE_SIZE,
+			    PAGE_SIZE);
+		if (m == NULL) {
+			if (wait & M_NOWAIT)
+				return (NULL);
+			VM_WAIT;
+		} else
+                        break;
+        }
+
+	va = (void *) VM_PAGE_TO_PHYS(m);
+
+	if (!hw_direct_map)
+		pmap_kenter((vm_offset_t)va, VM_PAGE_TO_PHYS(m));
+
+	if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
+		bzero(va, PAGE_SIZE);
+
+        return (va);
 }
 
+static void
+slb_uma_cache_free(void *mem, int size, u_int8_t flags)
+{
+	vm_page_t m;
+
+	if (!hw_direct_map)
+		pmap_remove(kernel_pmap,(vm_offset_t)mem,
+		    (vm_offset_t)mem + PAGE_SIZE);
+
+	m = PHYS_TO_VM_PAGE((vm_offset_t)mem);
+	vm_page_lock_queues();
+	vm_phys_free_pages(m, 0);
+	vm_page_unlock_queues();
+}
 
 static void
 slb_zone_init(void *dummy)
@@ -297,8 +343,10 @@ slb_zone_init(void *dummy)
 	slb_cache_zone = uma_zcreate("SLB cache", 64*sizeof(struct slb),
 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM);
 
-	if (platform_real_maxaddr() != VM_MAX_ADDRESS)
+	if (platform_real_maxaddr() != VM_MAX_ADDRESS) {
 		uma_zone_set_allocf(slb_cache_zone, slb_uma_cache_alloc);
+		uma_zone_set_freef(slb_cache_zone, slb_uma_cache_free);
+	}
 }
 
 struct slb *

Modified: user/nwhitehorn/ps3/powerpc/aim/uma_machdep.c
==============================================================================
--- user/nwhitehorn/ps3/powerpc/aim/uma_machdep.c	Sun Sep  5 01:58:21 2010	(r212219)
+++ user/nwhitehorn/ps3/powerpc/aim/uma_machdep.c	Sun Sep  5 03:05:03 2010	(r212220)
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_kern.h>
 #include <vm/vm_pageout.h>
 #include <vm/vm_extern.h>
-#include <vm/vm_phys.h>
 #include <vm/uma.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
@@ -49,20 +48,9 @@ static int hw_uma_mdpages;
 SYSCTL_INT(_hw, OID_AUTO, uma_mdpages, CTLFLAG_RD, &hw_uma_mdpages, 0,
 	   "UMA MD pages in use");
 
-void *uma_small_alloc_core(uma_zone_t zone, int bytes, u_int8_t *flags,
-    int wait, vm_offset_t minphys, vm_offset_t maxphys);
-
 void *
 uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
 {
-	return (uma_small_alloc_core(zone, bytes, flags, wait,
-	    0, VM_MAX_ADDRESS));
-}
-
-void *
-uma_small_alloc_core(uma_zone_t zone, int bytes, u_int8_t *flags, int wait,
-    vm_offset_t minphys, vm_offset_t maxphys)
-{
 	static vm_pindex_t color;
 	void *va;
 	vm_page_t m;
@@ -77,12 +65,7 @@ uma_small_alloc_core(uma_zone_t zone, in
 		pflags |= VM_ALLOC_ZERO;
 
 	for (;;) {
-		if (minphys == 0 && maxphys == VM_MAX_ADDRESS)
-			m = vm_page_alloc(NULL, color++,
-			    pflags | VM_ALLOC_NOOBJ);
-		else
-			m = vm_phys_alloc_contig(1, minphys, maxphys, PAGE_SIZE,
-			    PAGE_SIZE);
+		m = vm_page_alloc(NULL, color++, pflags | VM_ALLOC_NOOBJ);
 		if (m == NULL) {
 			if (wait & M_NOWAIT)
 				return (NULL);


More information about the svn-src-user mailing list