memory_allocation(3K) SDK R4.11 memory_allocation(3K)
NAME
memoryallocation: vmcheckaccessandwirememory,
vmgetphysicalbyteaddress, vmgetunwiredmemory,
vmgetwiredmemory, vmmapphysicalmemory,
vmmarkandunwirememory, vmmarkmodandrefandunwirememory,
vmmarkrefandunwirememory, vmperhapsgetunwiredmemory,
vmperhapsgetwiredmemory, vmreleaseunwiredmemory,
vmreleasewiredmemory, vmunmapphysicalmemory, vmunwirememory,
vmwirememory - allocate and deallocate wired and unwired memory
SYNOPSIS
#include "/usr/src/uts/aviion/ii/ivm.h"
statustype vmcheckaccessandwirememory (
pointertoanytype startptr READ ONLY
booleantype isuseraddress READ ONLY
uint32type bytestowire READ ONLY
scaccessmodetype accessrequested READ ONLY )
void vmgetphysicalbyteaddress (logicaladdress,
isuseraddress, physicaladdrptr)
pointertoanytype logicaladdress; /*READ ONLY*/
booleantype isuseraddress; /*READ ONLY*/
physicaladdressptrtype *physicaladdrptr; /*WRITE ONLY*/
pointertoanytype vmgetunwiredmemory (bytes, alignment)
uint32type bytes; /*READ ONLY*/
uint32type alignment; /*READ ONLY*/
pointertoanytype vmgetwiredmemory (bytes, alignment)
uint32type bytes; /*READ ONLY*/
uint32type alignment; /*READ ONLY*/
statustype vmmapphysicalmemory (logicaladdr, physicaladdr,
numbytes, accessmode, sharing, controlflags)
pointertoanytype logicaladdr; /*READ ONLY*/
physicaladdresstype physicaladdr; /*READ ONLY*/
uint32type numbytes; /*READ ONLY*/
bit32type accessmode; /*READ ONLY*/
int32type sharing; /*READ ONLY*/
bit32type controlflags; /*READ ONLY*/
void vmmarkandunwirememory (
pointertoanytype startptr READ ONLY
booleantype isuseraddress READ ONLY
uint32type bytestounwire READ ONLY
scaccessmodetype accessperformed READ ONLY )
void vmmarkmodandrefandunwirememory (startptr,
isuseraddress, bytestounwire)
pointertoanytype startptr; /*READ ONLY*/
booleantype isuseraddress; /*READ ONLY*/
uint32type bytestounwire; /*READ ONLY*/
void vmmarkrefandunwirememory (startptr,
isuseraddress, bytestounwire)
pointertoanytype startptr; /*READ ONLY*/
booleantype isuseraddress; /*READ ONLY*/
uint32type bytestounwire; /*READ ONLY*/
pointertoanytype vmperhapsgetunwiredmemory (bytes, alignment)
uint32type bytes; /*READ ONLY*/
uint32type alignment; /*READ ONLY*/
pointertoanytype vmperhapsgetwiredmemory (bytes, alignment)
uint32type bytes; /*READ ONLY*/
uint32type alignment; /*READ ONLY*/
void vmreleaseunwiredmemory (memoryptr, bytes)
pointertoanytype memoryptr; /*READ ONLY*/
uint32type bytes; /*READ ONLY*/
void vmreleasewiredmemory (memoryptr, bytes)
pointertoanytype memoryptr; /*READ ONLY*/
uint32type bytes; /*READ ONLY*/
statustype vmunmapphysicalmemory (logicaladdr, numbytes,
controlflags )
pointertoanytype logicaladdr; /*READ ONLY*/
uint32type numbytes; /*READ ONLY*/
bit32type controlflags; /*READ ONLY*/
void vmunwirememory (startptr, isuseraddress,
bytestounwire)
pointertoanytype startptr; /*READ ONLY*/
booleantype isuseraddress; /*READ ONLY*/
uint32type bytestounwire; /*READ ONLY*/
statustype vmwirememory (startptr, isuseraddress,
bytestowire)
pointertoanytype startptr; /*READ ONLY*/
booleantype isuseraddress; /*READ ONLY*/
uint32type bytestowire; /*READ ONLY*/
where:
accessmode The bitwise OR of all appropriate access modes:
PROTREAD, PROTWRITE, and/or PROTEXEC, 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.
accessperformed The type of access performed on the memory region.
accessrequested 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 ivm.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 vmgetunwiredmemory or
vmperhapsgetunwiredmemory call when memory was
originally requested.
bytestowire The number of bytes to be wired.
bytestounwire The number of bytes to be unwired.
controlflags 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
VMMMAPISKERNELADDRESSSPACEMASK or
VMMUNMAPISKERNELADDRESSSPACEMASK; 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
VMMMAPWRITETHROUGHMASK; 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.
isuseraddress 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.
logicaladdr The first logical address in a contiguous block of
numbytes to be mapped or unmapped. This address
must be on a page boundary.
logicaladdress The logical address for which a physical address is
needed.
memoryptr A byte pointer to the start of the memory to be re
leased. memoryptr must be the same pointer that
was returned by the vmgetunwiredmemory or
vmperhapsgetunwiredmemory call when memory was
originally requested.
numbytes 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.
physicaladdr The first physical address in a contiguous block of
numbytes to which the logicaladdr will be mapped.
This address also must be on a page boundary.
physicaladdrptr A pointer to the physical address corresponding to
a given logical address. If the logical address
was invalid, this address is set to
VMINVALIDPHYSICALADDRESS.
sharing MAPSHARED. MAPPRIVATE is not yet supported.
startptr A pointer to a byte address indicating the start of
memory to be unwired or wired. The value in
startptr is rounded down to a page boundary.
DESCRIPTION
The following routines are described in this man page:
vmcheckaccessandwirememory Wire the indicated memory
vmgetphysicalbyteaddress Return the physical address of given
logical address
vmgetunwiredmemory Allocate unwired memory
vmgetwiredmemory Allocate wired memory
vmmapphysicalmemory Map logical address space to physical
memory
vmmarkandunwirememory Unwire the indicated memory
vmmarkmodandrefandunwirememory*
Mark and unwire memory frames
vmmarkrefandunwirememory* Mark and unwire memory frames
vmperhapsgetunwiredmemory Allocate unwired memory
vmperhapsgetwiredmemory Allocate wired memory
vmreleaseunwiredmemory Release unwired memory
vmreleasewiredmemory Release wired memory
vmunmapphysicalmemory Unmap physical memory
vmunwirememory Unwire the indicated memory
vmwirememory* 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, vmget(un)wiredmemory refers to both
vmgetwiredmemory and vmgetunwiredmemory). 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
(vmperhapsget(un)wiredmemory) 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
(vmget(un)wiredmemory) 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 vmrelease(un)wiredmemory. 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
vmcheckaccessandwirememory or vmunwirememory. 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
vmmapphysicalmemory 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 vmcheckaccessandwirememory. 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 vmgetphysicalbyteaddress. You cannot assume
that the pages occupied by the buffer are physically contiguous.
Thus, you must call vmgetphysicalbyteaddress 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 vmmarkandunwirememory with the appropriate
scaccessmodetype 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:
VMDOUBLEWORDALIGNED
Request double word alignment (64-bit)
VMWORDALIGNED
Request word alignment (32-bit)
VMBYTEALIGNED
Request byte alignment
VMDEFAULTALIGNMENT
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).
VMPAGEALIGNED
Request page alignment. Don't use this alignment when
VM_DEFAULT_ALIGNMENT_NO_PAGE_CROSS is sufficient, because it
will result in wasted space.
VMDEFAULTALIGNMENTNOPAGECROSS
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.
VMINVALIDMEMORYPTR
This constant is returned by vmperhapsgetwiredmemory and
vmperhapsgetunwiredmemory when the memory allocation
fails.
scaccessmodetype
typedef bit16type scaccessmodetype;
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 isc.h.
SCREADACCESS
SCWRITEACCESS
SCEXECUTEACCESS
SCNOACCESS
SCACCESSMODEMASK
vmcheckaccessandwirememory
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.
vmgetphysicalbyteaddress
This routine returns the physical address that corresponds to the
given logical byte address.
vmgetunwiredmemory
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.
vmgetwiredmemory
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.
vmmapphysicalmemory
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
caladdr can be either a kernel or user address. A bit in the con
trolflags parameter controls this distinction. The logicaladdr
passed, offset by numbytes, 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.
vmmarkandunwirememory
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 accessperformed parameter.
vmmarkmodandrefandunwirememory
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
vmmarkandunwirememory.
This routine marks frames as having been referenced and modified and
then unwires them. It starts at startptr, and goes for
bytestounwire 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.
vmmarkrefandunwirememory
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 vmmarkandunwirememory.
This routine marks the frames as having been referenced and then un
wires them. It starts at startptr and goes for bytestounwire 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.
vmperhapsgetunwiredmemory
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.
vmperhapsgetwiredmemory
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.
vmreleaseunwiredmemory
This routine releases unwired memory that was previously obtained via
a vmgetunwiredmemory or vmperhapsgetunwiredmemory 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 vmgetunwiredmemory or vmperhapsgetunwiredmemory
call.
vmreleasewiredmemory
This routine releases wired memory that was previously obtained via a
vmgetwiredmemory or vmperhapsgetwiredmemory 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 vmgetwiredmemory or vmperhapsgetwiredmemory call.
vmunmapphysicalmemory
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 logicaladdr can be either a kernel or
user address. A bit in the parameter controlflags makes this dis
tinction.
vmunwirememory
This routine unwires the memory indicated by startptr for the number
of bytes indicated by bytestounwire. Unwiring is done only on
blocks of a complete page. Therefore, if startptr is not the start
of a page, vmunwirememory starts at the next lowest page boundary.
Similarly, if bytestounwire does not end on a page boundary, un
wiring continues into the next higher page boundary.
vmwirememory
This routine wires the memory indicated by startptr for the number
of bytes indicated by bytestowire. 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
vmcheckaccessandwirememory.
This routine wires the memory indicated by startptr for the number
of bytes indicated by bytestowire. Wiring is done only on blocks
of a complete page. Therefore, if startptr is not the start of a
page, vmwirememory starts at the next lowest page boundary. Simi
larly, if bytestowire does not end on a page boundary, wiring con
tinues into the next higher page boundary.
DIAGNOSTICS
Return Value
For vmcheckaccessandwirememory:
OK The memory was successfully wired.
VMEFAULTINVALIDADDRESS
The requested number of bytes could not be transferred
and a NULL was not encountered.
VMSTATUSPROCESSHASNOVM
The specified process has no user address space at the
given address.
VMEFAULTACCESSDENIED
The specified process does not have the access permis
sions to access the memory region it the way it has re
quested.
VMEFAULTUNWIREANDVALIDATEREGIONS
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 vmgetunwiredmemory and vmgetwiredmemory:
memoryptr A byte pointer to the allocated space
For vmmapphysicalmemory:
OK All frames were mapped successfully. (See Abort Condi
tions.)
For vmperhapsgetunwiredmemory and vmperhapsgetwiredmemory:
memoryptr
The memory was allocated successfully.
VMINVALIDMEMORYPTR
The memory could not be allocated.
For vmunmapphysicalmemory:
OK All frames were unmapped successfully. (See Abort Con
ditions.)
For vmwirememory:
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 statuscodemacros(3K) man page.
For the other routines: None.
Abort Conditions
The vmgetunwiredmemory routine may invoke the scpanic routine
with the following error code:
VMPANICGETUNWIREDMEMORY
The requested memory could not be allocated.
The vmgetwiredmemory routine may invoke the scpanic routine with
the following error code:
VMPANICGETWIREDMEMORY
The requested memory could not be allocated.
For the following return values, vmmapphysicalmemory aborts before
any modifications are made:
VMEINVALMMAPUNSUPPORTED
The parameter sharing is set to MAPPRIVATE; currently,
only MAPSHARING is supported.
VMEINVALMMAPBYTESNOTMULTIPLE
The parameter numbytes is not an integral multiple
(greater than zero) of the size of a physical page.
VMEINVALMMAPBADADDRBOUNDARY
Either of the address parameters, physicaladdr or log
icaladdr, is not aligned on a page boundary.
VMEINVALMMAPSPACEUNALLOCATED
The logicaladdr is not part of the current process's
address space.
VMEINVALMMAPADDRESSNOTDATA
The logicaladdr 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.
VMEINVALMMAPBADREGION
The range of addresses to be mapped is inappropriate.
For example: when logicaladdr offset by the numbytes
is greater than the maximum address (4G); or when the
region of addresses to be mapped, logicaladdr to logi
caladdr+numbytes, does not fit in the size of the
process's current data area; or when logicaladdr can
not be located in any address area.
VMEINVALMMAPALREADYMAPPED
Data contained within the passed range of addresses
(logicaladdr through logicaladdr+numbytes) 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, vmunmapphysicalmemory aborts be
fore any modifications are made:
VMEINVALMUNMAPBYTESNOTMULTIPLE
The parameter numbytes is not an integral multiple of
the physical page size.
VMEINVALMUNMAPBADADDRBOUNDARY
The address parameter, logicaladdr, is not aligned on
a page boundary.
VMEINVALMUNMAPBADREGION
One of the following situations occurred: the range of
addresses to unmap (logicaladdr through logi
caladdr+numbytes) 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.
VMEINVALMUNMAPDATANOTMAPPED
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), scpanic(3K), sta
tuscodemacros(3K).
Programming in the DG/UX Kernel Environment.
Licensed material--property of copyright holder(s)