vm_pattr System Call and kvm_pattr Kernel Service

Purpose

Queries or modifies virtual memory attributes.

Library

Standard C Library (libc.a)

Syntax

#include <sys/vmpattr.h>

int vm_pattr (
long cmd,
pid_t pid,
void * attr,
size_t attr_size );

int kvm_pattr (
long cmd,
pid_t pid,
void * attr,
size_t attr_size );

Description

The vm_pattr system call queries or modifies memory attributes of the calling process's address space or that of another user process.

The kvm_pattr kernel service provides the same function to kernel subsystems (kernel extensions, kernel processes and so on) except that it cannot modify another kernel process' memory attributes.

Parameters

Item Description
cmd The following commands can be passed in:
VM_PA_SET_PSIZE or VM_PA_GET_PSIZE
These commands set or retrieve the page size used for a specified memory range.
VM_PA_GET_RMUSAGE
This command retrieves the amount of the real memory in bytes being used for a specified memory range.
VM_PA_SET_PSPA or VM_PA_GET_PSPA
These commands set or retrieve the page size promotion aggressiveness factor for a specified memory range.
VM_PA_GET_PSPA_ALIGN
This command retrieves the minimum memory alignment necessary for memory ranges specified to the vm_pattr kernel service when using the VM_PA_SET_PSPA command.
VM_PA_CHECK_PSIZE
This command reports if a specified page size can be used for a memory range.
VM_PA_SET_LSA_POLICY
This command allows the shared memory address space allocator to be tuned according to a process requirements. This command should be run before any shared memory regions are created.
VM_PA_SET_PSIZE_EXTENDED or VM_PA_GET_PSIZE_EXTENDED
These commands provide variable large page size segment support.
pid Specifies the ID of the process whose memory attributes are to be queried or modified. A value of -1 specifies the calling process. The root user can specify any process ID, but other users can only specify processes they own (that is, the target process's user ID must match the calling process's user ID).

The vm_pattr system call is only supported on user processes while the kvm_pattr kernel service can target user processes or its own kernel process (for example, pid = -1).

attr A pointer to a structure describing the effective address range for the memory being queried or modified and additional data depending on the command.
The range is specified through the following vm_pa_range structure:
 struct vm_pa_range
              {
                     ptr64_t  rng_start;
                     size64_t rng_size;
              };
The range specified must be in the target process's address space and must correspond to one of these process areas:
  • Main program data (initialized, bss, or heap).
  • Shared library data or private module load area data.
  • Privately loaded text.
  • Initial thread stack area.
  • Anonymous shared memory (System V shared memory, extended System V shared through EXTSHM, and POSIX real-time shared memory). The target process must have write access to the memory in order to change the attributes of the shared memory range.
  • Anonymous mmap memory.
If the memory range specified includes shared memory or mmap memory, the calling process must have write access to the memory according to the shared memory descriptor or mapping attributes in order to change the attributes of the range. The range can have additional restrictions based on the following commands.
The structure specified through the attr parameter must be a pointer to one of the following structures:
VM_PA_SET_PSIZE or VM_PA_GET_PSIZE
These commands take a pointer to the following structure:
struct vm_pa_psize
              {
                     struct vm_pa_range pa_range;
                     psize_t            pa_psize;
              };
For the VM_PA_SET_PSIZE command, the pa_psize parameter is the page size (in bytes) to use for the given range. This is an advisory setting that might or might not be used at the operating system's discretion. This must be a valid page size between the minimum and maximum page sizes of all segments in the range. Additionally, the range must start and end on a multiple of the specified page size. If an error occurs during the processing of this command, any successfully altered page size settings can remain set.

For the VM_PA_GET_PSIZE command, the page size (in bytes) backing the specified memory range is returned in the pa_psize parameter. The range must start and end on a multiple of the smallest page size supported as reported by the sysconf(_SC_PAGE_SIZE) subroutine. If the range is using multiple page sizes, the smallest page size in the range is reported. Unlike the VM_PAGE_INFO command of the vmgetinfo subroutine that reports the segment's base page size, the page size reported by the VM_PA_GET_PSIZE command is the actual page size being used at the time the vm_pattr system call was called. The page size reported is transient because the operating system can change the backing page size at any time. Therefore, the page size reported must be for informational purposes only.

VM_PA_SET_PSIZE_EXTENDED
This command takes a pointer to the following structure:
struct vm_pa_psize_extended
				{
					struct vm_pa_range   pa_range;
					psize_t              pa_psize;
					size_t               pa_info_size;
					uint64_t            *pa_info;
				}

This command is essentially the same as VM_PA_SET_PSIZE except that pa_psize must be 16 MB and, if not NULL, pa_info can be used to pass additional information specifying one or more affinity domains.

The info passed by the parameter is advisory request, and the system might choose to ignore it.

The pa_range is scanned for subregions that begin and end on a 16 MB boundary, are fully backed with 4 KB or 64 KB pages, and have uniform page attributes. The page attributes include read or write page protection, storage key protection, and no-execute protection.

The data in qualifying 16 MB subregions is colocated to a 16 MB contiguous block of physical memory, and it uses 16 MB hardware translations.

If the pa_info pointer is NULL, the memory for collocation is allocated from any memory SRAD, affinity domain chosen by the operating system.

If parameter value is not NULL, pa_info must point to an rsethandle_t that describes a set of affinity domains from which the physical memory for the collocation must be allocated. The object should be allocated by a call to rs_alloc (RS_EMPTY). It must then be initialized with one rs_op(RS_ADDRESOURCE, ..., R_MEMPS, srad#) call per affinity domain being requested.

This command can potentially affect system performance and is not generally recommended; therefore, this command requires you to have either the CAP_BYPASS_RAC_VMM and CAP_PROPAGATE capabilities or root authority.

VM_PA_GET_PSIZE_EXTENDED
This command is essentially the same as the VM_PA_GET_PSIZE command except that it can also return the 64 KB and 16 MB subregions that are using an hardware translation page size different from the underlying segments default page size.

If the pa_info field is NULL, this command is identical to the VM_PA_GET_PSIZE command.

The pa_info field should point to an array containing two 64 bit integers. The pa_info_size field should be set to the size of the array.

In the first 64-bit integer, this command reports the number of 64-KB sized and aligned subregions in the specified pa_range range that consist of 16 contiguous 4-KB pages that are promoted to using a 64-KB page size hardware translation. In the second 64-bit integer, this command reports the number of 16 MB sized and aligned subregions in the specified range that consist of either 4096 4 KB or 256 64-KB contiguous pages that are promoted to using a 16-MB page size hardware translation.

The pa_psize field reports the smallest page size found for the specified range.

The information reported is transient because the operating system can change the backing page size at any time. Therefore, the page size reported must be for informational purposes only.

attr (continued)
VM_PA_GET_RMUSAGE
This command takes a pointer to the following structure:
struct vm_pa_rmusage
              {
                     struct vm_pa_range pa_range;
                     size64_t           pa_rbytes;
              };
This command reports the amount of real memory (in bytes) used for the given range in the pa_rbytes field. This can help an application decide whether it needs to use a large page size for a specific range based on how much real memory the range is using. For example, if a 64KB range is only using 4KB of real memory, then it does not make sense to try to use a 64KB page size for that range. But if it is using all 64KB or some large percentage of it, then the application might decide to use a 64KB page size. The range specified for this command has no alignment requirements for this command, and the command includes only those bytes in the range that are using real memory.
VM_PA_SET_PSPA or VM_PA_GET_PSPA
These commands take a pointer to the following structure:
struct vm_pa_pspa
              {
                     struct vm_pa_range pa_range;
                     int    pa_pspa;
              };
The VM_PA_SET_PSPA command can set the page size promotion aggressiveness for the specified range. The pa_pspa setting is in the same units as the vmm_default_pspa vmo tunable. This setting is the inverse of the real memory occupancy threshold needed to promote to a large page size and ranges from -1 to 100. The value of -1 indicates that no page promotion can occur regardless of the occupancy of the memory range. A value of 0 indicates a page size promotion can only be done when the memory range is fully occupied. A value of 100 indicates a page promotion must be done at the first reference to the memory range.

This setting is only supported at a segment granularity, so the range must start and end on a segment boundary. The alignment requirement for the range can be found using the VM_PA_GET_PSPA_ALIGN command with the vm_pattr system call.

If an error occurs during the processing of the VM_PA_SET_PSPA command, the vm_pattr system call can return after altering the page size promotion thresholds for part of the specified range.

The VM_PA_GET_PSPA command retrieves the page size promotion aggressiveness factor for the specified range. If the range spans multiple segments consisting of different page promotion thresholds, the pa_pspa field is updated with the least aggressive PSPA setting (the smallest PSPA setting across all of the segments).

The PSPA commands are not supported on mmap or EXTSHM memory ranges.

attr (continued)
VM_PA_GET_PSPA_ALIGN
This command takes a pointer to the following structure:
 struct vm_pa_pspa_align
              {
                     struct vm_pa_range pa_range;
                     size64_t pa_pspa_align;
              };
The VM_PA_GET_PSPA_ALIGN command returns the minimum memory alignment requirements of a memory range for the VM_PA_SET_PSPA command in the pa_pspa_align field based on what segments are contained in the specified memory range. If a memory range spans segments with different alignment requirements, this command returns the largest of the alignment requirements.

The alignment requirements for the VM_PA_SET_PSPA command are as follows:

attr (continued)
VM_PA_SET_LSA_POLICY
This command takes a pointer to the following structure:
struct vm_pa_lsa_options
 {
 u_int64_t setting;
 size64_t value;
 };
The following settings are allowed:
VM_PA_SHM_1TB_SHARED
This setting controls the threshold of the number of 256 MB segments required before a SHM object is considered big enough to be placed in its own 1 TB region to be promoted to the large alias segments. Values can range from 0 to 4 KB.
VM_PA_SHM_1TB_UNSHARED
This setting controls the threshold of the number of 256 MB segments required before a group of SHM object packed in a 1 TB aligned group is promoted to the large alias segments. Values can range from 0 to 4 KB.

Process's Memory Area Minimum Alignment

Main process data 256 MB

Process stack 256 MB

Shared Library data 256 MB

Privately loaded module data 256 MB

Privately loaded module text 256 MB

POSIX Real-Time Shared Memory 256 MB

Anonymous MMAP 256 MB

Anonymous Extended System V Shared memory 256 MB

Anonymous System V Shared memory with page sizes less than or equal to 256 MB 256 MB

Anonymous System V shared memory backed with 16 GB page size 1 TB

 
VM_PA_CHECK_PSIZE
This command takes a pointer to the following structure:
struct vm_pa_psize_check
              {
                     struct vm_pa_range pa_range;
                     psize_t            pa_psize;
                     int                pa_reason;
              };
The VM_PA_CHECK_PSIZE command determines if a specific page size is allowed by the VM_PA_SET_PSIZE command for a specified memory range. The VM_PA_CHECK_PSIZE command can be used when the application wants more detailed information about why a VM_PA_SET_PSIZE operation fails, or to check if a VM_PA_SET_PSIZE operation will successfully modify the page size for the range specified.

This command must be used on a memory range that spans a single page and is aligned to the page size specified by the pa_psize parameter. If the page size can be used for that range, the pa_reason parameter is set to 0. Otherwise, it is set to a reason code defined in the vmpattr.h header file.

VMPATTR_SET_PSIZE_VALID The specified page size can be used for the specified range.

VMPATTR_INVALID_MPSS_PSIZE The specified page size is not supported in mixed page size segments.

VMPATTR_NON_MPSS_SEGMENT The address range specified is from a segment that does not support mixed page sizes.

VMPATTR_NON_MPSS_PAGE The size of the target page cannot be modified. For example, this reason code can be returned when trying to set an address range to a 64 KB page size if a portion of the range has page protection settings that do not match the rest of the range.

VMPATTR_RDONLY_MEM The target range cannot be modified because the caller does not have write access to the memory specified.

VMPATTR_PAGE_ATTRIBUTES The address range specified does not have uniform page attributes.

VMPATTR_NOT_FULLY_POPULATED The address range specified does not fully reside in memory.

VMPATTR_PHYSICAL_ATTACHMENTS The address range specified has memory affinity attachments that specify more than one affinity domain.

VMPATTR_MEMORY_TYPE_UNSUPPORTED The address range contains a memory object that does not support the requested page size in a mixed page size segment.

attr_size The attr_size parameter must be the size of the structure needed, or greater for the specified command.

Return Values

When successful, these commands return 0. Otherwise, they return -1 and set the errno global variable to indicate the error.

Error Codes

Item Description
EPERM The calling process does not have the appropriate privilege to perform the requested operation.
ESRCH The target process does not exist or is not in a valid state.
ENOMEM The range specified contains a hole. A hole is any part of the target process's address space that is not backed by a virtual memory segment or is outside of the valid range of the virtual memory segment specified.
ENOTSUP Any of the following situations can cause the ENOTSUP error:
  • The target process is a kernel process other than the calling process.
  • The command specified was the VM_PA_SET_PSIZE command and the page size specified is not supported for multiple page size segments.
  • The command specified was either the VM_PA_GET_PSPA or the VM_PA_SET_PSPA command and the specified memory range includes mmap or EXTSHM segment(s).
EINVAL Any of the following situations can cause the EINVAL error:
  • The attr_size parameter specified is less than the size of the structure needed for this command.
  • The range specified is outside the process's address space (for example, global kernel memory).
  • The command specified was the VM_PA_SET_PSIZE command and the page size specified was not a valid page size supported by the system.
  • The command specified was the VM_PA_SET_PSPA command and the address range specified was not aligned to the segment size backing the range.
  • The command specified was the VM_PA_SET_PSPA command and the page promotion aggressiveness factor specified was not valid.
  • The command specified was the VM_PA_CHECK_PSIZE command and the address range specified was not aligned to the page size specified.
ENOMEM The command specified was VM_PA_SET_PSIZE_EXTENDED, and the system was unable to allocate memory from the set of affinity domains specified by the pa_info object or the entire set of system affinity domains without potentially causing a performance degradation.
EFAULT The command specified was either VM_PA_SET_PSIZE_EXTENDED, or VM_PA_GET_PSIZE_EXTENDED and the pa_info address is not valid and is not NULL.
EINVAL The command specified was either VM_PA_SET_PSIZE_EXTENDED, or VM_PA_GET_PSIZE_EXTENDED and the pa_info field is not-NULL, but the pa_info_size field is 0.
ENODEV The command specified was VM_PA_SET_PSIZE_EXTENDED, and an invalid sradid was specified in pa_info.