summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-01-19 21:37:51 +0000
committerjhb <jhb@FreeBSD.org>2016-01-19 21:37:51 +0000
commit897a9bc5d3677b3f9053d7e36e77e8dc0aa373e0 (patch)
tree487bad23399744527b32d7512d35abaf220f0d77 /sys/vm/vm_map.c
parentea0e31cb8f599c0dda524d10f320561820408aac (diff)
downloadFreeBSD-src-897a9bc5d3677b3f9053d7e36e77e8dc0aa373e0.zip
FreeBSD-src-897a9bc5d3677b3f9053d7e36e77e8dc0aa373e0.tar.gz
Various cleanups to the main function for AIO kernel processes:
- Pull the vmspace logic out into helper functions and reduce duplication. Operations on the vmspace are all isolated to vm_map.c, but it now exports a new 'vmspace_switch_aio' for use by AIO kernel processes. - When an AIO kernel process wants to exit, break out of the main loop and perform cleanup after the loop end. This reduces a lot of indentation and allows cleanup to more closely mirror setup actions before the loop starts. - Convert a DIAGNOSTIC to KASSERT(). - Replace mycp with more typical 'p'. Reviewed by: kib Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D4990
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 2e69b87..5fdc62f 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -451,6 +451,51 @@ vmspace_acquire_ref(struct proc *p)
return (vm);
}
+/*
+ * Switch between vmspaces in an AIO kernel process.
+ *
+ * The AIO kernel processes switch to and from a user process's
+ * vmspace while performing an I/O operation on behalf of a user
+ * process. The new vmspace is either the vmspace of a user process
+ * obtained from an active AIO request or the initial vmspace of the
+ * AIO kernel process (when it is idling). Because user processes
+ * will block to drain any active AIO requests before proceeding in
+ * exit() or execve(), the vmspace reference count for these vmspaces
+ * can never be 0. This allows for a much simpler implementation than
+ * the loop in vmspace_acquire_ref() above. Similarly, AIO kernel
+ * processes hold an extra reference on their initial vmspace for the
+ * life of the process so that this guarantee is true for any vmspace
+ * passed as 'newvm'.
+ */
+void
+vmspace_switch_aio(struct vmspace *newvm)
+{
+ struct vmspace *oldvm;
+
+ /* XXX: Need some way to assert that this is an aio daemon. */
+
+ KASSERT(newvm->vm_refcnt > 0,
+ ("vmspace_switch_aio: newvm unreferenced"));
+
+ oldvm = curproc->p_vmspace;
+ if (oldvm == newvm)
+ return;
+
+ /*
+ * Point to the new address space and refer to it.
+ */
+ curproc->p_vmspace = newvm;
+ atomic_add_int(&newvm->vm_refcnt, 1);
+
+ /* Activate the new mapping. */
+ 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);
+}
+
void
_vm_map_lock(vm_map_t map, const char *file, int line)
{
OpenPOWER on IntegriCloud