Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Aug 2012 17:16:05 +0000 (UTC)
From:      Matthew D Fleming <mdf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r239566 - in stable/8/sys: kern vm
Message-ID:  <201208221716.q7MHG5vq065777@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mdf
Date: Wed Aug 22 17:16:05 2012
New Revision: 239566
URL: http://svn.freebsd.org/changeset/base/239566

Log:
  MFC r238502:
  
  Fix a bug with memguard(9) on 32-bit architectures without a
  VM_KMEM_MAX_SIZE.
  
  The code was not taking into account the size of the kernel_map, which
  the kmem_map is allocated from, so it could produce a sub-map size too
  large to fit.  The simplest solution is to ignore VM_KMEM_MAX entirely
  and base the memguard map's size off the kernel_map's size, since this
  is always relevant and always smaller.
  
  Found by:	Justin Hibbits

Modified:
  stable/8/sys/kern/kern_malloc.c
  stable/8/sys/vm/memguard.c
  stable/8/sys/vm/memguard.h
  stable/8/sys/vm/vm_map.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/boot/   (props changed)
  stable/8/sys/cddl/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/compat/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/   (props changed)
  stable/8/sys/dev/e1000/   (props changed)
  stable/8/sys/dev/sound/   (props changed)
  stable/8/sys/dev/sound/pci/   (props changed)
  stable/8/sys/dev/virtio/   (props changed)
  stable/8/sys/kern/   (props changed)
  stable/8/sys/sys/   (props changed)
  stable/8/sys/vm/   (props changed)

Modified: stable/8/sys/kern/kern_malloc.c
==============================================================================
--- stable/8/sys/kern/kern_malloc.c	Wed Aug 22 17:13:00 2012	(r239565)
+++ stable/8/sys/kern/kern_malloc.c	Wed Aug 22 17:16:05 2012	(r239566)
@@ -646,7 +646,7 @@ kmeminit(void *dummy)
 	init_param3(vm_kmem_size / PAGE_SIZE);
 
 #ifdef DEBUG_MEMGUARD
-	tmp = memguard_fudge(vm_kmem_size, vm_kmem_size_max);
+	tmp = memguard_fudge(vm_kmem_size, kernel_map);
 #else
 	tmp = vm_kmem_size;
 #endif

Modified: stable/8/sys/vm/memguard.c
==============================================================================
--- stable/8/sys/vm/memguard.c	Wed Aug 22 17:13:00 2012	(r239565)
+++ stable/8/sys/vm/memguard.c	Wed Aug 22 17:16:05 2012	(r239566)
@@ -156,16 +156,18 @@ SYSCTL_ULONG(_vm_memguard, OID_AUTO, fre
  * the kmem_map.  The memguard memory will be a submap.
  */
 unsigned long
-memguard_fudge(unsigned long km_size, unsigned long km_max)
+memguard_fudge(unsigned long km_size, const struct vm_map *parent_map)
 {
-	u_long mem_pgs = cnt.v_page_count;
+	u_long mem_pgs, parent_size;
 
 	vm_memguard_divisor = 10;
 	TUNABLE_INT_FETCH("vm.memguard.divisor", &vm_memguard_divisor);
 
+	parent_size = vm_map_max(parent_map) - vm_map_min(parent_map) +
+	    PAGE_SIZE;
 	/* Pick a conservative value if provided value sucks. */
 	if ((vm_memguard_divisor <= 0) ||
-	    ((km_size / vm_memguard_divisor) == 0))
+	    ((parent_size / vm_memguard_divisor) == 0))
 		vm_memguard_divisor = 10;
 	/*
 	 * Limit consumption of physical pages to
@@ -174,20 +176,19 @@ memguard_fudge(unsigned long km_size, un
 	 * This prevents memguard's page promotions from completely
 	 * using up memory, since most malloc(9) calls are sub-page.
 	 */
+	mem_pgs = cnt.v_page_count;
 	memguard_physlimit = (mem_pgs / vm_memguard_divisor) * PAGE_SIZE;
 	/*
 	 * We want as much KVA as we can take safely.  Use at most our
-	 * allotted fraction of kmem_max.  Limit this to twice the
-	 * physical memory to avoid using too much memory as pagetable
-	 * pages.
+	 * allotted fraction of the parent map's size.  Limit this to
+	 * twice the physical memory to avoid using too much memory as
+	 * pagetable pages (size must be multiple of PAGE_SIZE).
 	 */
-	memguard_mapsize = km_max / vm_memguard_divisor;
-	/* size must be multiple of PAGE_SIZE */
-	memguard_mapsize = round_page(memguard_mapsize);
+	memguard_mapsize = round_page(parent_size / vm_memguard_divisor);
 	if (memguard_mapsize / (2 * PAGE_SIZE) > mem_pgs)
 		memguard_mapsize = mem_pgs * 2 * PAGE_SIZE;
-	if (km_size + memguard_mapsize > km_max)
-		return (km_max);
+	if (km_size + memguard_mapsize > parent_size)
+		memguard_mapsize = 0;
 	return (km_size + memguard_mapsize);
 }
 

Modified: stable/8/sys/vm/memguard.h
==============================================================================
--- stable/8/sys/vm/memguard.h	Wed Aug 22 17:13:00 2012	(r239565)
+++ stable/8/sys/vm/memguard.h	Wed Aug 22 17:16:05 2012	(r239566)
@@ -35,7 +35,7 @@ struct malloc_type;
 struct vm_map;
 
 #ifdef DEBUG_MEMGUARD
-unsigned long	memguard_fudge(unsigned long, unsigned long);
+unsigned long	memguard_fudge(unsigned long, const struct vm_map *);
 void	memguard_init(struct vm_map *);
 void 	*memguard_alloc(unsigned long, int);
 void	*memguard_realloc(void *, unsigned long, struct malloc_type *, int);

Modified: stable/8/sys/vm/vm_map.h
==============================================================================
--- stable/8/sys/vm/vm_map.h	Wed Aug 22 17:13:00 2012	(r239565)
+++ stable/8/sys/vm/vm_map.h	Wed Aug 22 17:16:05 2012	(r239566)
@@ -198,13 +198,13 @@ struct vm_map {
 
 #ifdef	_KERNEL
 static __inline vm_offset_t
-vm_map_max(vm_map_t map)
+vm_map_max(const struct vm_map *map)
 {
 	return (map->max_offset);
 }
 
 static __inline vm_offset_t
-vm_map_min(vm_map_t map)
+vm_map_min(const struct vm_map *map)
 {
 	return (map->min_offset);
 }



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