diff options
author | bms <bms@FreeBSD.org> | 2003-08-11 07:14:08 +0000 |
---|---|---|
committer | bms <bms@FreeBSD.org> | 2003-08-11 07:14:08 +0000 |
commit | 44aa51e3ae83444b49c68887ca2969af90e1b889 (patch) | |
tree | 594ff099f60d71f34f1fbafb587388aa871cb06b /sys/vm/vm_map.c | |
parent | 09ab42f3bdd2cb5549d00378979cccfecdad4cfc (diff) | |
download | FreeBSD-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.c | 51 |
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); } |