memory_allocation(3K) DG/UX R4.11MU05 memory_allocation(3K)
NAME
memory_allocation: vm_check_access_and_wire_memory,
vm_get_physical_byte_address, vm_get_unwired_memory,
vm_get_wired_memory, vm_map_physical_memory,
vm_mark_and_unwire_memory, vm_mark_mod_and_ref_and_unwire_memory,
vm_mark_ref_and_unwire_memory, vm_perhaps_get_unwired_memory,
vm_perhaps_get_wired_memory, vm_release_unwired_memory,
vm_release_wired_memory, vm_unmap_physical_memory, vm_unwire_memory,
vm_wire_memory - allocate and deallocate wired and unwired memory
SYNOPSIS
#include "/usr/src/uts/aviion/ii/i_vm.h"
status_type vm_check_access_and_wire_memory (
pointer_to_any_type start_ptr READ ONLY
boolean_type is_user_address READ ONLY
uint32_type bytes_to_wire READ ONLY
sc_access_mode_type access_requested READ ONLY )
void vm_get_physical_byte_address (logical_address,
is_user_address, physical_addr_ptr)
pointer_to_any_type logical_address; /*READ ONLY*/
boolean_type is_user_address; /*READ ONLY*/
physical_address_ptr_type *physical_addr_ptr; /*WRITE ONLY*/
pointer_to_any_type vm_get_unwired_memory (bytes, alignment)
uint32_type bytes; /*READ ONLY*/
uint32_type alignment; /*READ ONLY*/
pointer_to_any_type vm_get_wired_memory (bytes, alignment)
uint32_type bytes; /*READ ONLY*/
uint32_type alignment; /*READ ONLY*/
status_type vm_map_physical_memory (logical_addr, physical_addr,
num_bytes, access_mode, sharing, control_flags)
pointer_to_any_type logical_addr; /*READ ONLY*/
physical_address_type physical_addr; /*READ ONLY*/
uint32_type num_bytes; /*READ ONLY*/
bit32_type access_mode; /*READ ONLY*/
int32_type sharing; /*READ ONLY*/
bit32_type control_flags; /*READ ONLY*/
void vm_mark_and_unwire_memory (
pointer_to_any_type start_ptr READ ONLY
boolean_type is_user_address READ ONLY
uint32_type bytes_to_unwire READ ONLY
sc_access_mode_type access_performed READ ONLY )
void vm_mark_mod_and_ref_and_unwire_memory (start_ptr,
is_user_address, bytes_to_unwire)
pointer_to_any_type start_ptr; /*READ ONLY*/
boolean_type is_user_address; /*READ ONLY*/
uint32_type bytes_to_unwire; /*READ ONLY*/
void vm_mark_ref_and_unwire_memory (start_ptr,
is_user_address, bytes_to_unwire)
pointer_to_any_type start_ptr; /*READ ONLY*/
boolean_type is_user_address; /*READ ONLY*/
uint32_type bytes_to_unwire; /*READ ONLY*/
pointer_to_any_type vm_perhaps_get_unwired_memory (bytes, alignment)
uint32_type bytes; /*READ ONLY*/
uint32_type alignment; /*READ ONLY*/
pointer_to_any_type vm_perhaps_get_wired_memory (bytes, alignment)
uint32_type bytes; /*READ ONLY*/
uint32_type alignment; /*READ ONLY*/
void vm_release_unwired_memory (memory_ptr, bytes)
pointer_to_any_type memory_ptr; /*READ ONLY*/
uint32_type bytes; /*READ ONLY*/
void vm_release_wired_memory (memory_ptr, bytes)
pointer_to_any_type memory_ptr; /*READ ONLY*/
uint32_type bytes; /*READ ONLY*/
status_type vm_unmap_physical_memory (logical_addr, num_bytes,
control_flags )
pointer_to_any_type logical_addr; /*READ ONLY*/
uint32_type num_bytes; /*READ ONLY*/
bit32_type control_flags; /*READ ONLY*/
void vm_unwire_memory (start_ptr, is_user_address,
bytes_to_unwire)
pointer_to_any_type start_ptr; /*READ ONLY*/
boolean_type is_user_address; /*READ ONLY*/
uint32_type bytes_to_unwire; /*READ ONLY*/
status_type vm_wire_memory (start_ptr, is_user_address,
bytes_to_wire)
pointer_to_any_type start_ptr; /*READ ONLY*/
boolean_type is_user_address; /*READ ONLY*/
uint32_type bytes_to_wire; /*READ ONLY*/
where:
access_mode The bitwise OR of all appropriate access modes:
PROT_READ, PROT_WRITE, and/or PROT_EXEC, from
sys/mman.h. No checking is performed as to the ap
propriateness of the specified modes, and it is as
sumed that privilege violations will not occur, or
be enforced by higher level routines.
access_performed The type of access performed on the memory region.
access_requested The type of access that the caller needs on the
memory: SC_READ_ACCESS or SC_WRITE_ACCESS
alignment The byte alignment of the allocated space. Rele
vant constants are defined in i_vm.h.
bytes The number of bytes to be allocated or released;
bytes must be a positive value. When you release
bytes, bytes must be the same number of bytes as
given to the vm_get_unwired_memory or
vm_perhaps_get_unwired_memory call when memory was
originally requested.
bytes_to_wire The number of bytes to be wired.
bytes_to_unwire The number of bytes to be unwired.
control_flags A bit field used for special control information.
The bit positions of the currently supported flags
are as follows (bit 0 is the lowest order bit):
Bit 0 Specify whether the logical address is in us
er or kernel address space. To specify ker
nel addresses, use
VM_MMAP_IS_KERNEL_ADDRESS_SPACE_MASK or
VM_MUNMAP_IS_KERNEL_ADDRESS_SPACE_MASK; the
default is user address space.
Bit 1 For mapping, specify whether to write through
or inhibit caching which should be passed on
to the page table entries of the mapped phys
ical memory. To specify write-through
caching on architectures that support it, use
VM_MMAP_WRITE_THROUGH_MASK; the default is to
inhibit caching. For unmapping, this bit is
unused and reserved for later expansion.
Bits 2-31 All other bits are unused and reserved.
is_user_address A boolean value indicating whether the logical ad
dress specified is a user or kernel address. TRUE
indicates a user address; FALSE indicates a kernel
address.
logical_addr The first logical address in a contiguous block of
num_bytes to be mapped or unmapped. This address
must be on a page boundary.
logical_address The logical address for which a physical address is
needed.
memory_ptr A byte pointer to the start of the memory to be re
leased. memory_ptr must be the same pointer that
was returned by the vm_get_unwired_memory or
vm_perhaps_get_unwired_memory call when memory was
originally requested.
num_bytes The total number of bytes to be mapped or unmapped,
which must be an integral multiple of the logical
page size. For unmapping, it does not need to be
identical to the number originally mapped.
physical_addr The first physical address in a contiguous block of
num_bytes to which the logical_addr will be mapped.
This address also must be on a page boundary.
physical_addr_ptr A pointer to the physical address corresponding to
a given logical address. If the logical address
was invalid, this address is set to
VM_INVALID_PHYSICAL_ADDRESS.
sharing MAP_SHARED. MAP_PRIVATE is not yet supported.
start_ptr A pointer to a byte address indicating the start of
memory to be unwired or wired. The value in
start_ptr is rounded down to a page boundary.
DESCRIPTION
The following routines are described in this man page:
vm_check_access_and_wire_memory Wire the indicated memory
vm_get_physical_byte_address Return the physical address of given
logical address
vm_get_unwired_memory Allocate unwired memory
vm_get_wired_memory Allocate wired memory
vm_map_physical_memory Map logical address space to physical
memory
vm_mark_and_unwire_memory Unwire the indicated memory
vm_mark_mod_and_ref_and_unwire_memory*
Mark and unwire memory frames
vm_mark_ref_and_unwire_memory* Mark and unwire memory frames
vm_perhaps_get_unwired_memory Allocate unwired memory
vm_perhaps_get_wired_memory Allocate wired memory
vm_release_unwired_memory Release unwired memory
vm_release_wired_memory Release wired memory
vm_unmap_physical_memory Unmap physical memory
vm_unwire_memory Unwire the indicated memory
vm_wire_memory* Wire the indicated memory
__________
*obsolescent
Overview to Using Memory Management Routines
As described in Chapter 3 of Programming in the DG/UX Kernel Environ
ment, there are two basic types of kernel memory: wired (memory that
will not be paged out) and unwired (memory that may be paged out).
Hence, kernel memory management routines come in two corresponding
versions, _wired_ and _unwired_ referred to in short hand as
_(un)wired_ (for example, vm_get_(un)wired_memory refers to both
vm_get_wired_memory and vm_get_unwired_memory). In general, you
should allocate unwired memory because wired memory is a limited re
source. However, you must allocate wired memory for data structures
that are referenced at interrupt level or for code that may be refer
enced during a page fault (for example, disk driver code).
The kernel provides two different ways to allocate memory: a demand
version and a perhaps version. The perhaps version
(vm_perhaps_get_(un)wired_memory) returns a pointer to a space of the
required number of bytes or a VM_INVALID_MEMORY_PTR pointer if no
more (un)wired memory is available. The demand version
(vm_get_(un)wired_memory) should be used only for critical data seg
ments. Like the perhaps version, the demand version returns a point
er to the allocated space if it's successful. However, if the re
quested number of bytes are not available, the demand version causes
a system halt.
Memory is deallocated using vm_release_(un)wired_memory. Note that
you must match the get and release calls. For example, on release,
you must supply the same number of bytes to the release call as spec
ified in the get call. You must also release the memory in the same
type as which it was originally allocated. Thus, you cannot allocate
wired memory, unwire it, then release it as unwired memory--or allo
cate as unwired memory, wire it, then release it as wired memory.
Once you have allocated memory, you may switch its type by calling
vm_check_access_and_wire_memory or vm_unwire_memory. However, there
are certain restrictions on this conversion. The system keeps a
"wire-count" which it increments for each wire and decrements for
each unwire. You may wire (increment) and unwire (decrement) a memo
ry area as much as you want as long as you do not take its wire count
below its initial value: 0 for wired; 1 for unwired.
Memory-mapped I/O requires special allocation routines. Normally, a
driver works within a logical address space and does not know or care
what physical addresses are being used. However, in memory-mapped
I/O, the device's registers are fixed to physical memory addresses.
To make sure that the logical addresses the driver uses map to the
correct physical addresses, you must direct a particular logical-to-
physical mapping for the device's control registers. To do this you
first reserve logical address space by allocating memory (that is
calling one of the "get" routines). Then you call
vm_map_physical_memory to map the logical address space to particular
physical memory addresses. The device driver can now access the de
vice registers through its logical address space.
The kernel also provides a number of routines to help drivers trans
fer data between the host and a device. To start a data transfer,
the driver must have a buffer set up in wired memory. If the buffer
was allocated out of wired kernel memory, then there is no need to
wire the memory. Otherwise, if the buffer is in user space or was
allocated out of unwired kernel memory, then the driver must wire the
buffer memory using vm_check_access_and_wire_memory. To start the
transfer (read or write), the driver must give the device the
buffer's physical address. The driver gets the physical address of
the buffer using vm_get_physical_byte_address. You cannot assume
that the pages occupied by the buffer are physically contiguous.
Thus, you must call vm_get_physical_byte_address for each page in the
wired buffer.
After the I/O operation completes, you should unwire the previously
wired memory. After completion the driver must also inform the ker
nel about the state of the memory. The kernel must know whether the
memory was referenced and/or modified; DMA transfers do not set the
referenced or modified bits in the page tables. This is accomplished
by calling vm_mark_and_unwire_memory with the appropriate
sc_access_mode_type parameters. Failure to appropriately set the
reference and/or modified bits can cause new buffer data to be lost.
Constants and Data Structures
This subsection describes constants and data structures defined in
the include files cited in the SYNOPSIS section and used by the rou
tines documented in this man page.
Try to avoid dependencies on the specifics of these structures, such
as size or location of fields, because these specifics may change in
later releases of the software. You can verify exact variable defi
nitions in the appropriate include file. The best way to avoid such
dependencies is to use kernel-supplied routines to manipulate these
structures.
Page Alignment Literals
The following literals (constants) specify alignment when "getting"
memory:
VM_DOUBLE_WORD_ALIGNED
Request double word alignment (64-bit)
VM_WORD_ALIGNED
Request word alignment (32-bit)
VM_BYTE_ALIGNED
Request byte alignment
VM_DEFAULT_ALIGNMENT
Request the most efficient alignment for use when allocating
strings and structures. The default is double word alignment
(64-bit) because, in most cases, the system deals with double
word alignment most efficiently. Use this constant whenever
possible.
After memory has been aligned, you cannot ask for a quantity
smaller than the specified alignment. To ask for page align
ment for more than one page, use VM_PAGE_ALIGNED shown below.
To ask for page alignment for less than one page, use
VM_DEFAULT_ALIGNMENT_NO_PAGE_CROSS (shown below).
VM_PAGE_ALIGNED
Request page alignment. Don't use this alignment when
VM_DEFAULT_ALIGNMENT_NO_PAGE_CROSS is sufficient, because it
will result in wasted space.
VM_DEFAULT_ALIGNMENT_NO_PAGE_CROSS
Request an alignment that is default-aligned and guaranteed
not to cross a page boundary. Allocations that use this
alignment are restricted to one page or less.
VM_INVALID_MEMORY_PTR
This constant is returned by vm_perhaps_get_wired_memory and
vm_perhaps_get_unwired_memory when the memory allocation
fails.
sc_access_mode_type
typedef bit16_type sc_access_mode_type;
This type contains the access modes that can be specified to the
functions that perform user data validation.
You may use the following defines with this type. They are defined
in i_sc.h.
SC_READ_ACCESS
SC_WRITE_ACCESS
SC_EXECUTE_ACCESS
SC_NO_ACCESS
SC_ACCESS_MODE_MASK
vm_check_access_and_wire_memory
This routine wires the memory indicated by the starting address
(rounded down to a page boundary) for the number of bytes indicated
(rounded up to a page boundary). The calling process must have the
necessary permissions to access the memory in the way that it has re
quested.
vm_get_physical_byte_address
This routine returns the physical address that corresponds to the
given logical byte address.
vm_get_unwired_memory
This routine allocates a user-specified amount of unwired memory from
available address space and on the alignment you specify. If the al
location fails, the system halts.
vm_get_wired_memory
This routine allocates a user-specified amount of wired memory from
available address space and on the alignment you specify. If the al
location fails, the system halts.
vm_map_physical_memory
This routine supports the mmap(2) system call. It provides the ker
nel data structure modifications to map an area of a process's ad
dress space to real physical memory. Basically, this is done by
searching for a contiguous region of a process's data area and set
ting pointers to the appropriate physical memory frame. It can be
called by either user or kernel processes; that is, the passed logi
cal_addr can be either a kernel or user address. A bit in the con
trol_flags parameter controls this distinction. The logical_addr
passed, offset by num_bytes, must be part of the current address
space before this call is made. Kernel processes should have already
allocated unwired memory, while users should valloc() the appropriate
range before making the mapping call.
The range of addresses to be mapped must have referred to an existing
region of a process's data area, or else an error will result. Any
existing data that was addressed in this range will be discarded. No
other explicit cleanup is needed for an address space that has been
mapped. If the process that called mmap(2) exits, its mapped region
will be implicitly unmapped by the exit path. Likewise, if the pro
cess calls any version of exec(2), the mapped region will also be im
plicitly unmapped before the new program begins to execute. Finally,
in the case of a fork(2), the new child will implicitly inherit the
parent's mapped address space.
vm_mark_and_unwire_memory
This routine unwires the memory indicated by the starting address
(rounded down to a page boundary) for the number of bytes indicated
(rounded up to a page boundary).
The pages are marked according to the access_performed parameter.
vm_mark_mod_and_ref_and_unwire_memory
This routine marks the frames indicated as having been referenced and
modified, and then unwires the frames. Because of the new interface
to the wire and unwire memory routines due to new features, you
should replace calls to this routine with the routine
vm_mark_and_unwire_memory.
This routine marks frames as having been referenced and modified and
then unwires them. It starts at start_ptr, and goes for
bytes_to_unwire number of bytes.
Memory needs to be marked as modified if it has been wired and then
used as an I/O buffer for a read operation. I/O uses direct memory
access, which does not cause the frame to be marked as modified auto
matically. Therefore, this routine will set the modified bit explic
itly.
vm_mark_ref_and_unwire_memory
This routine marks the indicated frames as having been referenced and
then unwires them. Because of the new interface to the wire and un
wire memory routines due to new features, you should replace calls to
this routine with the routine vm_mark_and_unwire_memory.
This routine marks the frames as having been referenced and then un
wires them. It starts at start_ptr and goes for bytes_to_unwire num
ber of bytes.
Memory needs to be marked as referenced if it has been wired and then
used as an I/O buffer for a write operation. I/O uses direct memory
access, which does not cause the frame to be marked as referenced au
tomatically. Therefore, this routine will set the referenced bit ex
plicitly.
vm_perhaps_get_unwired_memory
This routine allocates unwired memory.
Memory is allocated from unwired memory on the alignment specified by
the user. The amount of memory allocated is specified by the bytes
parameter.
vm_perhaps_get_wired_memory
This routine allocates wired memory.
Memory is allocated from wired memory on the alignment specified by
the user. The amount of memory to be allocated is specified by the
bytes parameter.
vm_release_unwired_memory
This routine releases unwired memory that was previously obtained via
a vm_get_unwired_memory or vm_perhaps_get_unwired_memory call.
This routine releases the given number of bytes of unwired memory,
starting at the given byte address. This memory must have been ob
tained via a vm_get_unwired_memory or vm_perhaps_get_unwired_memory
call.
vm_release_wired_memory
This routine releases wired memory that was previously obtained via a
vm_get_wired_memory or vm_perhaps_get_wired_memory call.
This routine releases the given number of bytes of wired memory,
starting at the given byte address. This memory must have been ob
tained via a vm_get_wired_memory or vm_perhaps_get_wired_memory call.
vm_unmap_physical_memory
This routine supports the munmap(2) system call. It unmaps an area
of a process's address space that was previously mapped by mmap(2).
Only previously mapped areas can be unmapped. Upon unmapping, the
appropriate address space will be reset to be non-resident but will
still be a valid area of the data area.
It can be called by either user or kernel processes and still work
properly; that is, the passed logical_addr can be either a kernel or
user address. A bit in the parameter control_flags makes this dis
tinction.
vm_unwire_memory
This routine unwires the memory indicated by start_ptr for the number
of bytes indicated by bytes_to_unwire. Unwiring is done only on
blocks of a complete page. Therefore, if start_ptr is not the start
of a page, vm_unwire_memory starts at the next lowest page boundary.
Similarly, if bytes_to_unwire does not end on a page boundary, un
wiring continues into the next higher page boundary.
vm_wire_memory
This routine wires the memory indicated by start_ptr for the number
of bytes indicated by bytes_to_wire. Because of the new interface to
the wire and unwire memory routines due to new features, you should
replace calls to this routine with the routine
vm_check_access_and_wire_memory.
This routine wires the memory indicated by start_ptr for the number
of bytes indicated by bytes_to_wire. Wiring is done only on blocks
of a complete page. Therefore, if start_ptr is not the start of a
page, vm_wire_memory starts at the next lowest page boundary. Simi
larly, if bytes_to_wire does not end on a page boundary, wiring con
tinues into the next higher page boundary.
DIAGNOSTICS
Return Value
For vm_check_access_and_wire_memory:
OK The memory was successfully wired.
VM_EFAULT_INVALID_ADDRESS
The requested number of bytes could not be transferred
and a NULL was not encountered.
VM_STATUS_PROCESS_HAS_NO_VM
The specified process has no user address space at the
given address.
VM_EFAULT_ACCESS_DENIED
The specified process does not have the access permis
sions to access the memory region it the way it has re
quested.
VM_EFAULT_UNWIRE_AND_VALIDATE_REGIONS
The specified region cannot be validated because of
previously wired memory.
bad I/O status
A hard I/O error occurred which prevented a page from
being brought in.
For vm_get_unwired_memory and vm_get_wired_memory:
memory_ptr A byte pointer to the allocated space
For vm_map_physical_memory:
OK All frames were mapped successfully. (See Abort Condi
tions.)
For vm_perhaps_get_unwired_memory and vm_perhaps_get_wired_memory:
memory_ptr
The memory was allocated successfully.
VM_INVALID_MEMORY_PTR
The memory could not be allocated.
For vm_unmap_physical_memory:
OK All frames were unmapped successfully. (See Abort Con
ditions.)
For vm_wire_memory:
OK The memory was successfully wired.
other error statuses
A hard I/O error occurred that prevented a page from
being brought in. The specific list of possible errors
is too long to give here. You can decode any status
returned here using the error status decoding methods
described in the status_code_macros(3K) man page.
For the other routines: None.
Abort Conditions
The vm_get_unwired_memory routine may invoke the sc_panic routine
with the following error code:
VM_PANIC_GET_UNWIRED_MEMORY
The requested memory could not be allocated.
The vm_get_wired_memory routine may invoke the sc_panic routine with
the following error code:
VM_PANIC_GET_WIRED_MEMORY
The requested memory could not be allocated.
For the following return values, vm_map_physical_memory aborts before
any modifications are made:
VM_EINVAL_MMAP_UNSUPPORTED
The parameter sharing is set to MAP_PRIVATE; currently,
only MAP_SHARING is supported.
VM_EINVAL_MMAP_BYTES_NOT_MULTIPLE
The parameter num_bytes is not an integral multiple
(greater than zero) of the size of a physical page.
VM_EINVAL_MMAP_BAD_ADDR_BOUNDARY
Either of the address parameters, physical_addr or log
ical_addr, is not aligned on a page boundary.
VM_EINVAL_MMAP_SPACE_UNALLOCATED
The logical_addr is not part of the current process's
address space.
VM_EINVAL_MMAP_ADDRESS_NOT_DATA
The logical_addr is not a part of the calling process's
data area. Only regions of a process's address space
of the data variety are accepted for mapping.
VM_EINVAL_MMAP_BAD_REGION
The range of addresses to be mapped is inappropriate.
For example: when logical_addr offset by the num_bytes
is greater than the maximum address (4G); or when the
region of addresses to be mapped, logical_addr to logi
cal_addr+num_bytes, does not fit in the size of the
process's current data area; or when logical_addr can
not be located in any address area.
VM_EINVAL_MMAP_ALREADY_MAPPED
Data contained within the passed range of addresses
(logical_addr through logical_addr+num_bytes) is al
ready mapped. A region of a process's data area can be
remapped, but only if an explicit munmap(2) is done be
fore the remap attempt.
For the following return values, vm_unmap_physical_memory aborts be
fore any modifications are made:
VM_EINVAL_MUNMAP_BYTES_NOT_MULTIPLE
The parameter num_bytes is not an integral multiple of
the physical page size.
VM_EINVAL_MUNMAP_BAD_ADDR_BOUNDARY
The address parameter, logical_addr, is not aligned on
a page boundary.
VM_EINVAL_MUNMAP_BAD_REGION
One of the following situations occurred: the range of
addresses to unmap (logical_addr through logi
cal_addr+num_bytes) was not entirely valid; or the
starting address could not be found in the process's
data area; or the address range overflowed beyond the
4G upper limit.
VM_EINVAL_MUNMAP_DATA_NOT_MAPPED
An attempt was made to unmap a portion of an address
space that was not previously mapped. Only previously
mapped regions can be unmapped.
For other routines: none.
SEE ALSO
exec(2), fork(2), mmap(2), munmap(2), sc_panic(3K), sta
tus_code_macros(3K).
Programming in the DG/UX Kernel Environment.
Licensed material--property of copyright holder(s)