summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2003-08-11 07:14:08 +0000
committerbms <bms@FreeBSD.org>2003-08-11 07:14:08 +0000
commit44aa51e3ae83444b49c68887ca2969af90e1b889 (patch)
tree594ff099f60d71f34f1fbafb587388aa871cb06b /sys/vm/vm_map.c
parent09ab42f3bdd2cb5549d00378979cccfecdad4cfc (diff)
downloadFreeBSD-src-44aa51e3ae83444b49c68887ca2969af90e1b889.zip
FreeBSD-src-44aa51e3ae83444b49c68887ca2969af90e1b889.tar.gz
Add the mlockall() and munlockall() system calls.
- All those diffs to syscalls.master for each architecture *are* necessary. This needed clarification; the stub code generation for mlockall() was disabled, which would prevent applications from linking to this API (suggested by mux) - Giant has been quoshed. It is no longer held by the code, as the required locking has been pushed down within vm_map.c. - Callers must specify VM_MAP_WIRE_HOLESOK or VM_MAP_WIRE_NOHOLES to express their intention explicitly. - Inspected at the vmstat, top and vm pager sysctl stats level. Paging-in activity is occurring correctly, using a test harness. - The RES size for a process may appear to be greater than its SIZE. This is believed to be due to mappings of the same shared library page being wired twice. Further exploration is needed. - Believed to back out of allocations and locks correctly (tested with WITNESS, MUTEX_PROFILING, INVARIANTS and DIAGNOSTIC). PR: kern/43426, standards/54223 Reviewed by: jake, alc Approved by: jake (mentor) MFC after: 2 weeks
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index eddfc88..d4910cd 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -1604,19 +1604,24 @@ vm_map_inherit(vm_map_t map, vm_offset_t start, vm_offset_t end,
*/
int
vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
- boolean_t user_unwire)
+ int flags)
{
vm_map_entry_t entry, first_entry, tmp_entry;
vm_offset_t saved_start;
unsigned int last_timestamp;
int rv;
- boolean_t need_wakeup, result;
+ boolean_t need_wakeup, result, user_unwire;
+ user_unwire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
if (!vm_map_lookup_entry(map, start, &first_entry)) {
- vm_map_unlock(map);
- return (KERN_INVALID_ADDRESS);
+ if (flags & VM_MAP_WIRE_HOLESOK)
+ first_entry = map->header.next;
+ else {
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
+ }
}
last_timestamp = map->timestamp;
entry = first_entry;
@@ -1672,9 +1677,11 @@ vm_map_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
entry->eflags |= MAP_ENTRY_IN_TRANSITION;
/*
* Check the map for holes in the specified region.
+ * If VM_MAP_WIRE_HOLESOK was specified, skip this check.
*/
- if (entry->end < end && (entry->next == &map->header ||
- entry->next->start > entry->end)) {
+ if (((flags & VM_MAP_WIRE_HOLESOK) == 0) &&
+ (entry->end < end && (entry->next == &map->header ||
+ entry->next->start > entry->end))) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
goto done;
@@ -1733,19 +1740,24 @@ done:
*/
int
vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
- boolean_t user_wire)
+ int flags)
{
vm_map_entry_t entry, first_entry, tmp_entry;
vm_offset_t saved_end, saved_start;
unsigned int last_timestamp;
int rv;
- boolean_t need_wakeup, result;
+ boolean_t need_wakeup, result, user_wire;
+ user_wire = (flags & VM_MAP_WIRE_USER) ? TRUE : FALSE;
vm_map_lock(map);
VM_MAP_RANGE_CHECK(map, start, end);
if (!vm_map_lookup_entry(map, start, &first_entry)) {
- vm_map_unlock(map);
- return (KERN_INVALID_ADDRESS);
+ if (flags & VM_MAP_WIRE_HOLESOK)
+ first_entry = map->header.next;
+ else {
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
+ }
}
last_timestamp = map->timestamp;
entry = first_entry;
@@ -1856,9 +1868,11 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end,
}
/*
* Check the map for holes in the specified region.
+ * If VM_MAP_WIRE_HOLESOK was specified, skip this check.
*/
- if (entry->end < end && (entry->next == &map->header ||
- entry->next->start > entry->end)) {
+ if (((flags & VM_MAP_WIRE_HOLESOK) == 0) &&
+ (entry->end < end && (entry->next == &map->header ||
+ entry->next->start > entry->end))) {
end = entry->end;
rv = KERN_INVALID_ADDRESS;
goto done;
@@ -2394,6 +2408,10 @@ vmspace_fork(struct vmspace *vm1)
new_map = &vm2->vm_map; /* XXX */
new_map->timestamp = 1;
+ /* Do not inherit the MAP_WIREFUTURE property. */
+ if ((new_map->flags & MAP_WIREFUTURE) == MAP_WIREFUTURE)
+ new_map->flags &= ~MAP_WIREFUTURE;
+
old_entry = old_map->header.next;
while (old_entry != &old_map->header) {
@@ -2704,6 +2722,15 @@ Retry:
}
vm_map_unlock(map);
+ /*
+ * Heed the MAP_WIREFUTURE flag if it was set for this process.
+ */
+ if (rv == KERN_SUCCESS && (map->flags & MAP_WIREFUTURE))
+ vm_map_wire(map, addr, stack_entry->start,
+ (p->p_flag & P_SYSTEM ?
+ VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES :
+ VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES));
+
return (rv);
}
OpenPOWER on IntegriCloud