Generalize vm_map_find(9)'s parameter "find_space". Specifically, add

support for VMFS_ALIGNED_SPACE, which requests the allocation of an
address range best suited to superpages.  The old options TRUE and FALSE
are mapped to VMFS_ANY_SPACE and VMFS_NO_SPACE, so that there is no
immediate need to update all of vm_map_find(9)'s callers.

While I'm here, correct a misstatement about vm_map_find(9)'s return
values in the man page.
This commit is contained in:
Alan Cox 2008-05-10 18:55:35 +00:00
parent b6642dadae
commit 26c538ffcd
3 changed files with 49 additions and 17 deletions

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 19, 2003
.Dd May 10, 2008
.Dt VM_MAP_FIND 9
.Os
.Sh NAME
@ -38,7 +38,7 @@
.Ft int
.Fo vm_map_find
.Fa "vm_map_t map" "vm_object_t object" "vm_ooffset_t offset"
.Fa "vm_offset_t *addr" "vm_size_t length" "boolean_t find_space"
.Fa "vm_offset_t *addr" "vm_size_t length" "int find_space"
.Fa "vm_prot_t prot" "vm_prot_t max" "int cow"
.Fc
.Sh DESCRIPTION
@ -70,11 +70,25 @@ by the caller before calling this function to account for the new entry.
.Pp
If
.Fa find_space
is
.Dv TRUE ,
is either
.Dv VMFS_ALIGNED_SPACE
or
.Dv VMFS_ANY_SPACE ,
the function will call
.Xr vm_map_findspace 9
to discover a free region.
Moreover, if
.Fa find_space
is
.Dv VMFS_ALIGNED_SPACE ,
the address of the free region will be optimized for the use of superpages.
Otherwise, if
.Fa find_space
is
.Dv VMFS_NO_SPACE ,
.Xr vm_map_insert 9
is called with the given address,
.Fa addr .
.Sh IMPLEMENTATION NOTES
This function acquires a lock on
.Fa map
@ -90,9 +104,14 @@ The
.Fn vm_map_find
function returns
.Dv KERN_SUCCESS
if space for the mapping could be found and
the mapping was successfully created.
If space could not be found in the map,
if the mapping was successfully created.
If space could not be found or
.Fa find_space
was
.Dv VMFS_NO_SPACE
and the given address,
.Fa addr ,
was already mapped,
.Dv KERN_NO_SPACE
will be returned.
If the discovered range turned out to be bogus,

View File

@ -1200,7 +1200,7 @@ vm_map_fixed(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
int
vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
vm_offset_t *addr, /* IN/OUT */
vm_size_t length, boolean_t find_space, vm_prot_t prot,
vm_size_t length, int find_space, vm_prot_t prot,
vm_prot_t max, int cow)
{
vm_offset_t start;
@ -1208,15 +1208,20 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset,
start = *addr;
vm_map_lock(map);
if (find_space) {
if (vm_map_findspace(map, start, length, addr)) {
vm_map_unlock(map);
return (KERN_NO_SPACE);
do {
if (find_space != VMFS_NO_SPACE) {
if (vm_map_findspace(map, start, length, addr)) {
vm_map_unlock(map);
return (KERN_NO_SPACE);
}
if (find_space == VMFS_ALIGNED_SPACE)
pmap_align_superpage(object, offset, addr,
length);
start = *addr;
}
start = *addr;
}
result = vm_map_insert(map, object, offset,
start, start + length, prot, max, cow);
result = vm_map_insert(map, object, offset, start, start +
length, prot, max, cow);
} while (result == KERN_NO_SPACE && find_space == VMFS_ALIGNED_SPACE);
vm_map_unlock(map);
return (result);
}

View File

@ -324,6 +324,13 @@ long vmspace_wired_count(struct vmspace *vmspace);
#define VM_FAULT_WIRE_MASK (VM_FAULT_CHANGE_WIRING|VM_FAULT_USER_WIRE)
#define VM_FAULT_DIRTY 8 /* Dirty the page */
/*
* The following "find_space" options are supported by vm_map_find()
*/
#define VMFS_NO_SPACE 0 /* don't find; use the given range */
#define VMFS_ANY_SPACE 1 /* find a range with any alignment */
#define VMFS_ALIGNED_SPACE 2 /* find a superpage-aligned range */
/*
* vm_map_wire and vm_map_unwire option flags
*/
@ -337,7 +344,8 @@ long vmspace_wired_count(struct vmspace *vmspace);
boolean_t vm_map_check_protection (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t);
vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t);
int vm_map_delete (vm_map_t, vm_offset_t, vm_offset_t);
int vm_map_find (vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t, boolean_t, vm_prot_t, vm_prot_t, int);
int vm_map_find(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t,
int, vm_prot_t, vm_prot_t, int);
int vm_map_fixed(vm_map_t, vm_object_t, vm_ooffset_t, vm_offset_t, vm_size_t,
vm_prot_t, vm_prot_t, int);
int vm_map_findspace (vm_map_t, vm_offset_t, vm_size_t, vm_offset_t *);