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