summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_exec.c5
-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
5 files changed, 45 insertions, 16 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 25335ce..388ed19 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -933,10 +933,7 @@ exec_map_first_page(imgp)
return (EACCES);
VM_OBJECT_WLOCK(object);
#if VM_NRESERVLEVEL > 0
- if ((object->flags & OBJ_COLORED) == 0) {
- object->flags |= OBJ_COLORED;
- object->pg_color = 0;
- }
+ vm_object_color(object, 0);
#endif
ma[0] = vm_page_grab(object, 0, VM_ALLOC_NORMAL);
if (ma[0]->valid != VM_PAGE_BITS_ALL) {
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index ff18a15..536076a 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 5c31222..a9ff248 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 d80b1d8..731c9e3 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 3623494..c12b83d 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);
OpenPOWER on IntegriCloud