aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2015-03-21 17:56:55 +0000
committerAlan Cox <alc@FreeBSD.org>2015-03-21 17:56:55 +0000
commit3d653db063e2227a567121b6361676e839ec5ca0 (patch)
tree165f4dc5d1f1dbe912f22d0117840f1b5a196514 /sys/vm
parent28e1e3e25045da6975a52345e7c7af1e50197461 (diff)
downloadsrc-3d653db063e2227a567121b6361676e839ec5ca0.tar.gz
src-3d653db063e2227a567121b6361676e839ec5ca0.zip
Introduce vm_object_color() and use it in mmap(2) to set the color of
named objects to zero before the virtual address is selected. Previously, the color setting was delayed until after the virtual address was selected. In rtld, this delay effectively prevented the mapping of a shared library's code section using superpages. Now, for example, we see the first 1 MB of libc's code on armv6 mapped by a superpage after we've gotten through the initial cold misses that bring the first 1 MB of code into memory. (With the page clustering that we perform on read faults, this happens quickly.) Differential Revision: https://reviews.freebsd.org/D2013 Reviewed by: jhb, kib Tested by: Svatopluk Kraus (armv6) MFC after: 6 weeks
Notes
Notes: svn path=/head/; revision=280327
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_fault.c7
-rw-r--r--sys/vm/vm_mmap.c20
-rw-r--r--sys/vm/vm_object.h24
-rw-r--r--sys/vm/vnode_pager.c5
4 files changed, 44 insertions, 12 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index ff18a157298f..536076a0d57c 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -522,11 +522,8 @@ fast_failed:
fs.m = NULL;
if (!vm_page_count_severe() || P_KILLED(curproc)) {
#if VM_NRESERVLEVEL > 0
- if ((fs.object->flags & OBJ_COLORED) == 0) {
- fs.object->flags |= OBJ_COLORED;
- fs.object->pg_color = atop(vaddr) -
- fs.pindex;
- }
+ vm_object_color(fs.object, atop(vaddr) -
+ fs.pindex);
#endif
alloc_req = P_KILLED(curproc) ?
VM_ALLOC_SYSTEM : VM_ALLOC_NORMAL;
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 5c312220a5e9..a9ff2482b9cd 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include "opt_hwpmc_hooks.h"
+#include "opt_vm.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -1387,17 +1388,22 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
objsize = round_page(va.va_size);
if (va.va_nlink == 0)
flags |= MAP_NOSYNC;
- if (obj->type == OBJT_VNODE)
+ if (obj->type == OBJT_VNODE) {
obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff,
cred);
- else {
+ if (obj == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ } else {
KASSERT(obj->type == OBJT_DEFAULT || obj->type == OBJT_SWAP,
("wrong object type"));
- vm_object_reference(obj);
- }
- if (obj == NULL) {
- error = ENOMEM;
- goto done;
+ VM_OBJECT_WLOCK(obj);
+ vm_object_reference_locked(obj);
+#if VM_NRESERVLEVEL > 0
+ vm_object_color(obj, 0);
+#endif
+ VM_OBJECT_WUNLOCK(obj);
}
*objp = obj;
*flagsp = flags;
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index d80b1d8aacf6..731c9e3e8d71 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -257,6 +257,30 @@ vm_object_set_flag(vm_object_t object, u_short bits)
object->flags |= bits;
}
+/*
+ * Conditionally set the object's color, which (1) enables the allocation
+ * of physical memory reservations for anonymous objects and larger-than-
+ * superpage-sized named objects and (2) determines the first page offset
+ * within the object at which a reservation may be allocated. In other
+ * words, the color determines the alignment of the object with respect
+ * to the largest superpage boundary. When mapping named objects, like
+ * files or POSIX shared memory objects, the color should be set to zero
+ * before a virtual address is selected for the mapping. In contrast,
+ * for anonymous objects, the color may be set after the virtual address
+ * is selected.
+ *
+ * The object must be locked.
+ */
+static __inline void
+vm_object_color(vm_object_t object, u_short color)
+{
+
+ if ((object->flags & OBJ_COLORED) == 0) {
+ object->pg_color = color;
+ object->flags |= OBJ_COLORED;
+ }
+}
+
void vm_object_clear_flag(vm_object_t object, u_short bits);
void vm_object_pip_add(vm_object_t object, short i);
void vm_object_pip_subtract(vm_object_t object, short i);
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 36234941d4cb..c12b83d63020 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -53,6 +53,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_vm.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
@@ -242,6 +244,9 @@ retry:
VI_UNLOCK(vp);
} else {
object->ref_count++;
+#if VM_NRESERVLEVEL > 0
+ vm_object_color(object, 0);
+#endif
VM_OBJECT_WUNLOCK(object);
}
vref(vp);