svn commit: r195329 - head/sys/vm

Konstantin Belousov kib at FreeBSD.org
Fri Jul 3 22:17:38 UTC 2009


Author: kib
Date: Fri Jul  3 22:17:37 2009
New Revision: 195329
URL: http://svn.freebsd.org/changeset/base/195329

Log:
  When forking a vm space that has wired map entries, do not forget to
  charge the objects created by vm_fault_copy_entry. The object charge
  was set, but reserve not incremented.
  
  Reported by:	Greg Rivers <gcr+freebsd-current tharned org>
  Reviewed by:	alc (previous version)
  Approved by:	re (kensmith)

Modified:
  head/sys/vm/vm_extern.h
  head/sys/vm/vm_fault.c
  head/sys/vm/vm_map.c

Modified: head/sys/vm/vm_extern.h
==============================================================================
--- head/sys/vm/vm_extern.h	Fri Jul  3 21:51:44 2009	(r195328)
+++ head/sys/vm/vm_extern.h	Fri Jul  3 22:17:37 2009	(r195329)
@@ -55,7 +55,8 @@ vm_map_t kmem_suballoc(vm_map_t, vm_offs
 void swapout_procs(int);
 int useracc(void *, int, int);
 int vm_fault(vm_map_t, vm_offset_t, vm_prot_t, int);
-void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t);
+void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t,
+    vm_ooffset_t *);
 void vm_fault_unwire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t);
 int vm_fault_wire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t);
 int vm_forkproc(struct thread *, struct proc *, struct thread *, struct vmspace *, int);

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c	Fri Jul  3 21:51:44 2009	(r195328)
+++ head/sys/vm/vm_fault.c	Fri Jul  3 22:17:37 2009	(r195329)
@@ -1126,11 +1126,9 @@ vm_fault_unwire(vm_map_t map, vm_offset_
  *		entry corresponding to a main map entry that is wired down).
  */
 void
-vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
-	vm_map_t dst_map;
-	vm_map_t src_map;
-	vm_map_entry_t dst_entry;
-	vm_map_entry_t src_entry;
+vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
+    vm_map_entry_t dst_entry, vm_map_entry_t src_entry,
+    vm_ooffset_t *fork_charge)
 {
 	vm_object_t backing_object, dst_object, object;
 	vm_object_t src_object;
@@ -1161,13 +1159,16 @@ vm_fault_copy_entry(dst_map, src_map, ds
 #endif
 
 	VM_OBJECT_LOCK(dst_object);
+	KASSERT(dst_entry->object.vm_object == NULL,
+	    ("vm_fault_copy_entry: vm_object not NULL"));
 	dst_entry->object.vm_object = dst_object;
 	dst_entry->offset = 0;
-	if (dst_entry->uip != NULL) {
-		dst_object->uip = dst_entry->uip;
-		dst_object->charge = dst_entry->end - dst_entry->start;
-		dst_entry->uip = NULL;
-	}
+	dst_object->uip = curthread->td_ucred->cr_ruidinfo;
+	uihold(dst_object->uip);
+	dst_object->charge = dst_entry->end - dst_entry->start;
+	KASSERT(dst_entry->uip == NULL,
+	    ("vm_fault_copy_entry: leaked swp charge"));
+	*fork_charge += dst_object->charge;
 	prot = dst_entry->max_protection;
 
 	/*

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Fri Jul  3 21:51:44 2009	(r195328)
+++ head/sys/vm/vm_map.c	Fri Jul  3 22:17:37 2009	(r195329)
@@ -2909,7 +2909,8 @@ vm_map_copy_entry(
 		 * Cause wired pages to be copied into the new map by
 		 * simulating faults (the new pages are pageable)
 		 */
-		vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry);
+		vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry,
+		    fork_charge);
 	}
 }
 
@@ -3073,6 +3074,7 @@ vmspace_fork(struct vmspace *vm1, vm_oof
 			    MAP_ENTRY_IN_TRANSITION);
 			new_entry->wired_count = 0;
 			new_entry->object.vm_object = NULL;
+			new_entry->uip = NULL;
 			vm_map_entry_link(new_map, new_map->header.prev,
 			    new_entry);
 			vmspace_map_entry_forked(vm1, vm2, new_entry);


More information about the svn-src-head mailing list