Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_map.c
Show First 20 Lines • Show All 448 Lines • ▼ Show 20 Lines | vmspace_acquire_ref(struct proc *p) | ||||
} | } | ||||
PROC_VMSPACE_UNLOCK(p); | PROC_VMSPACE_UNLOCK(p); | ||||
return (vm); | return (vm); | ||||
} | } | ||||
/* | /* | ||||
* Switch between vmspaces in an AIO kernel process. | * Switch between vmspaces in an AIO kernel process. | ||||
* | * | ||||
* The AIO kernel processes switch to and from a user process's | * The new vmspace is either the vmspace of a user process obtained | ||||
* vmspace while performing an I/O operation on behalf of a user | * from an active AIO request or the initial vmspace of the AIO kernel | ||||
* process. The new vmspace is either the vmspace of a user process | * process (when it is idling). Because user processes will block to | ||||
* obtained from an active AIO request or the initial vmspace of the | * drain any active AIO requests before proceeding in exit() or | ||||
* AIO kernel process (when it is idling). Because user processes | * execve(), the reference count for vmspaces from AIO requests can | ||||
* will block to drain any active AIO requests before proceeding in | * never be 0. Similarly, AIO kernel processes hold an extra | ||||
* exit() or execve(), the vmspace reference count for these vmspaces | * reference on their initial vmspace for the life of the process. As | ||||
* can never be 0. This allows for a much simpler implementation than | * a result, the 'newvm' vmspace always has a non-zero reference | ||||
* the loop in vmspace_acquire_ref() above. Similarly, AIO kernel | * count. This permits an additional reference on 'newvm' to be | ||||
* processes hold an extra reference on their initial vmspace for the | * acquired via a simple atomic increment rather than the loop in | ||||
* life of the process so that this guarantee is true for any vmspace | * vmspace_acquire_ref() above. | ||||
* passed as 'newvm'. | |||||
*/ | */ | ||||
void | void | ||||
vmspace_switch_aio(struct vmspace *newvm) | vmspace_switch_aio(struct vmspace *newvm) | ||||
{ | { | ||||
struct vmspace *oldvm; | struct vmspace *oldvm; | ||||
/* XXX: Need some way to assert that this is an aio daemon. */ | /* XXX: Need some way to assert that this is an aio daemon. */ | ||||
KASSERT(newvm->vm_refcnt > 0, | KASSERT(newvm->vm_refcnt > 0, | ||||
("vmspace_switch_aio: newvm unreferenced")); | ("vmspace_switch_aio: newvm unreferenced")); | ||||
oldvm = curproc->p_vmspace; | oldvm = curproc->p_vmspace; | ||||
if (oldvm == newvm) | if (oldvm == newvm) | ||||
return; | return; | ||||
/* | /* | ||||
* Point to the new address space and refer to it. | * Point to the new address space and refer to it. | ||||
*/ | */ | ||||
curproc->p_vmspace = newvm; | curproc->p_vmspace = newvm; | ||||
atomic_add_int(&newvm->vm_refcnt, 1); | atomic_add_int(&newvm->vm_refcnt, 1); | ||||
/* Activate the new mapping. */ | /* Activate the new mapping. */ | ||||
pmap_activate(curthread); | pmap_activate(curthread); | ||||
/* Remove the daemon's reference to the old address space. */ | |||||
KASSERT(oldvm->vm_refcnt > 1, | |||||
("vmspace_switch_aio: oldvm dropping last reference")); | |||||
vmspace_free(oldvm); | vmspace_free(oldvm); | ||||
} | } | ||||
void | void | ||||
_vm_map_lock(vm_map_t map, const char *file, int line) | _vm_map_lock(vm_map_t map, const char *file, int line) | ||||
{ | { | ||||
if (map->system_map) | if (map->system_map) | ||||
▲ Show 20 Lines • Show All 4,377 Lines • Show Last 20 Lines |