PERFORCE change 127732 for review

Peter Wemm peter at FreeBSD.org
Thu Oct 18 16:47:54 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=127732

Change 127732 by peter at peter_daintree on 2007/10/18 23:47:18

	Demote pmap_activate to an MD interface.  Create pmap_switch_vmspace()
	that allows pmap to see what the old vmspace was before it is too late.
	This saves (in theory) the baggage of having cpu_switch track the curpmap.
	XXX: unless lazypmap needs it, in which case this is a wild goose chase.

Affected files ...

.. //depot/projects/hammer/sys/amd64/amd64/pmap.c#163 edit
.. //depot/projects/hammer/sys/i386/i386/pmap.c#95 edit
.. //depot/projects/hammer/sys/kern/vfs_aio.c#51 edit
.. //depot/projects/hammer/sys/vm/pmap.h#28 edit
.. //depot/projects/hammer/sys/vm/vm_map.c#63 edit
.. //depot/projects/hammer/sys/vm/vm_map.h#21 edit

Differences ...

==== //depot/projects/hammer/sys/amd64/amd64/pmap.c#163 (text+ko) ====

@@ -3471,20 +3471,23 @@
 }
 
 void
-pmap_activate(struct thread *td)
+pmap_switch_vmspace(struct vmspace *vm)
 {
 	pmap_t	pmap, oldpmap;
+	struct thread *td;
 	u_int64_t  cr3;
 
+	td = curthread;
+	oldpmap = vmspace_pmap(td->td_proc->p_vmspace);
+	PROC_VMSPACE_LOCK(td->td_proc);
+	td->td_proc->p_vmspace = vm;
+	PROC_VMSPACE_UNLOCK(td->td_proc);
+	pmap = vmspace_pmap(vm);
 	critical_enter();
-	pmap = vmspace_pmap(td->td_proc->p_vmspace);
-	oldpmap = PCPU_GET(curpmap);
 #ifdef SMP
-if (oldpmap)	/* XXX FIXME */
 	atomic_clear_int(&oldpmap->pm_active, PCPU_GET(cpumask));
 	atomic_set_int(&pmap->pm_active, PCPU_GET(cpumask));
 #else
-if (oldpmap)	/* XXX FIXME */
 	oldpmap->pm_active &= ~PCPU_GET(cpumask);
 	pmap->pm_active |= PCPU_GET(cpumask);
 #endif

==== //depot/projects/hammer/sys/i386/i386/pmap.c#95 (text+ko) ====

@@ -3520,12 +3520,13 @@
 }
 
 void
-pmap_activate(struct thread *td)
+pmap_activate(struct vmspace *vm)
 {
 	pmap_t	pmap, oldpmap;
 	u_int32_t  cr3;
 
 	critical_enter();
+	td->td_proc->p_vmspace = vm;
 	pmap = vmspace_pmap(td->td_proc->p_vmspace);
 	oldpmap = PCPU_GET(curpmap);
 #if defined(SMP)

==== //depot/projects/hammer/sys/kern/vfs_aio.c#51 (text+ko) ====

@@ -1025,11 +1025,10 @@
 				 * Point to the new user address space, and
 				 * refer to it.
 				 */
-				mycp->p_vmspace = userp->p_vmspace;
-				atomic_add_int(&mycp->p_vmspace->vm_refcnt, 1);
+				atomic_add_int(&userp->p_vmspace->vm_refcnt, 1);
 
 				/* Activate the new mapping. */
-				pmap_activate(FIRST_THREAD_IN_PROC(mycp));
+				pmap_switch_vmspace(userp->p_vmspace);
 
 				/*
 				 * If the old address space wasn't the daemons
@@ -1071,11 +1070,8 @@
 			/* Get the user address space to disconnect from. */
 			tmpvm = mycp->p_vmspace;
 
-			/* Get original address space for daemon. */
-			mycp->p_vmspace = myvm;
-
-			/* Activate the daemon's address space. */
-			pmap_activate(FIRST_THREAD_IN_PROC(mycp));
+			/* Activate the daemon's original address space. */
+			pmap_switch_vmspace(myvm);
 #ifdef DIAGNOSTIC
 			if (tmpvm == myvm) {
 				printf("AIOD: vmspace problem -- %d\n",

==== //depot/projects/hammer/sys/vm/pmap.h#28 (text+ko) ====

@@ -84,6 +84,7 @@
 #ifdef _KERNEL
 struct proc;
 struct thread;
+struct vmspace;
 
 /*
  * Updates to kernel_vm_end are synchronized by the kernel_map's system mutex.
@@ -128,7 +129,7 @@
 void		 pmap_zero_page_area(vm_page_t, int off, int size);
 void		 pmap_zero_page_idle(vm_page_t);
 int		 pmap_mincore(pmap_t pmap, vm_offset_t addr);
-void		 pmap_activate(struct thread *td);
+void		 pmap_switch_vmspace(struct vmspace *vm);
 vm_offset_t	 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size);
 
 #define	pmap_resident_count(pm)	((pm)->pm_stats.resident_count)

==== //depot/projects/hammer/sys/vm/vm_map.c#63 (text+ko) ====

@@ -148,13 +148,6 @@
 static void vmspace_zdtor(void *mem, int size, void *arg);
 #endif
 
-/* 
- * PROC_VMSPACE_{UN,}LOCK() can be a noop as long as vmspaces are type
- * stable.
- */
-#define PROC_VMSPACE_LOCK(p) do { } while (0)
-#define PROC_VMSPACE_UNLOCK(p) do { } while (0)
-
 /*
  *	VM_MAP_RANGE_CHECK:	[ internal use only ]
  *
@@ -378,26 +371,17 @@
 		refcnt = vm->vm_refcnt;
 		if (refcnt > 1 && p->p_vmspace != &vmspace0) {
 			/* Switch now since other proc might free vmspace */
-			PROC_VMSPACE_LOCK(p);
-			p->p_vmspace = &vmspace0;
-			PROC_VMSPACE_UNLOCK(p);
-			pmap_activate(td);
+			pmap_switch_vmspace(&vmspace0);
 		}
 	} while (!atomic_cmpset_int(&vm->vm_refcnt, refcnt, refcnt - 1));
 	if (refcnt == 1) {
 		if (p->p_vmspace != vm) {
 			/* vmspace not yet freed, switch back */
-			PROC_VMSPACE_LOCK(p);
-			p->p_vmspace = vm;
-			PROC_VMSPACE_UNLOCK(p);
-			pmap_activate(td);
+			pmap_switch_vmspace(vm);
 		}
 		pmap_remove_pages(vmspace_pmap(vm));
 		/* Switch now since this proc will free vmspace */
-		PROC_VMSPACE_LOCK(p);
-		p->p_vmspace = &vmspace0;
-		PROC_VMSPACE_UNLOCK(p);
-		pmap_activate(td);
+		pmap_switch_vmspace(&vmspace0);
 		vmspace_dofree(vm);
 	}
 }
@@ -3007,6 +2991,7 @@
 	struct vmspace *oldvmspace = p->p_vmspace;
 	struct vmspace *newvmspace;
 
+	KASSERT(p == curthread->td_proc, ("vmspace_exec: not curthread"));
 	newvmspace = vmspace_alloc(minuser, maxuser);
 	newvmspace->vm_swrss = oldvmspace->vm_swrss;
 	/*
@@ -3016,11 +3001,7 @@
 	 * run it down.  Even though there is little or no chance of blocking
 	 * here, it is a good idea to keep this form for future mods.
 	 */
-	PROC_VMSPACE_LOCK(p);
-	p->p_vmspace = newvmspace;
-	PROC_VMSPACE_UNLOCK(p);
-	if (p == curthread->td_proc)		/* XXXKSE ? */
-		pmap_activate(curthread);
+	pmap_switch_vmspace(newvmspace);
 	vmspace_free(oldvmspace);
 }
 
@@ -3036,12 +3017,9 @@
 
 	if (oldvmspace->vm_refcnt == 1)
 		return;
+	KASSERT(p == curthread->td_proc, ("vmspace_exec: not curthread"));
 	newvmspace = vmspace_fork(oldvmspace);
-	PROC_VMSPACE_LOCK(p);
-	p->p_vmspace = newvmspace;
-	PROC_VMSPACE_UNLOCK(p);
-	if (p == curthread->td_proc)		/* XXXKSE ? */
-		pmap_activate(curthread);
+	pmap_switch_vmspace(newvmspace);
 	vmspace_free(oldvmspace);
 }
 

==== //depot/projects/hammer/sys/vm/vm_map.h#21 (text+ko) ====

@@ -251,6 +251,14 @@
 {
 	return &vmspace->vm_pmap;
 }
+
+/*
+ * PROC_VMSPACE_{UN,}LOCK() can be a noop as long as vmspaces are type
+ * stable.
+ */
+#define	PROC_VMSPACE_LOCK(p)	do { } while (0)
+#define	PROC_VMSPACE_UNLOCK(p)	do { } while (0)
+
 #endif	/* _KERNEL */
 
 #ifdef	_KERNEL


More information about the p4-projects mailing list