MBIND - Linux手册页

时间:2019-08-20 17:58:58  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-06-09

名称

mbind-为内存范围设置内存策略

语法

#include <numaif.h>

long mbind(void *addr, unsigned long len, int mode,
           const unsigned long *nodemask, unsigned long maxnode,
           unsigned flags);

Link with -lnuma.

说明

mbind()设置NUMA内存策略,该内存策略由策略模式和零个或多个节点组成,用于以addr开头并持续len个字节的内存范围。内存策略定义从哪个节点分配内存。

如果由addr和len参数指定的内存范围包括内存的"匿名"区域-即使用mmap(2)系统调用和MAP_ANONYMOUS创建的内存区域-或内存映射文件,使用mmap(2)系统调用(带有MAP_PRIVATE标志)映射时,仅在应用程序将页面写入(存储)时才根据指定的策略分配页面。对于匿名区域,初始读取访问将使用内核中包含全零的共享页面。对于使用MAP_PRIVATE映射的文件,初始读取访问将根据导致分配页面的线程的内存策略分配页面。这可能不是调用mbind()的线程。

对于指定内存范围内的任何MAP_SHARED映射,将忽略指定的策略。而是将根据导致分配页面的线程的内存策略分配页面。同样,这可能不是调用mbind()的线程。

如果指定的内存范围包括使用shmget(2)系统调用创建并使用shmat(2)系统调用附加的共享内存区域,则将根据指定的策略分配为匿名或共享内存区域分配的页面,无论附加到共享内存段的哪个进程导致分配。但是,如果共享内存区域是使用SHM_HUGETLB标志创建的,则仅当页面分配是由对该区域调用mbind()的过程引起的时,才会根据指定的策略分配大页面。

默认情况下,mbind()仅对新分配有效。如果在设置策略之前已经触及范围内的页面,则该策略无效。此默认行为可以被下面描述的MPOL_MF_MOVE和MPOL_MF_MOVE_ALL标志覆盖。

模式参数必须指定MPOL_DEFAULTMPOL_BINDMPOL_INTERLEAVE,MPOL_PREFERRED或MPOL_LOCAL中的一种(在下面进行详细说明)。除MPOL_DEFAULT以外的所有策略模式都要求调用者通过nodemask参数指定该模式适用的一个或多个节点。

模式参数也可以包括可选的模式标志。支持的模式标志是:

MPOL_F_STATIC_NODES(since Linux-2.6.26)
非空节点掩码指定物理节点ID。当线程移至其他cpuset上下文时,或者线程的当前cpuset上下文所允许的节点集发生更改时,Linux都不会重新映射节点掩码。
MPOL_F_RELATIVE_NODES(since Linux-2.6.26)
非空节点掩码指定相对于线程当前cpuset允许的节点ID集合的节点ID。

nodemask指向最多包含maxnode位的节点的位掩码。位掩码的大小四舍五入为sizeof(无符号长整数)的下一个倍数,但是内核将仅使用最大maxnode的位。 nodemask的NULL值或maxnode的零值指定了空的节点集。如果maxnode的值为零,则将忽略nodemask参数。在需要节点掩码的情况下,它必须包含至少一个在线的节点,该节点由线程的当前cpuset上下文允许(除非指定了MPOL_F_STATIC_NODES模式标志),并包含内存。

mode参数必须包含以下值之一:

MPOL_DEFAULT
此模式要求删除所有非默认策略,以恢复默认行为。通过mbind()应用于内存范围时,这意味着使用线程内存策略,该策略可能已通过set_mempolicy(2)进行了设置。如果线程内存策略的模式也为MPOL_DEFAULT,则将使用系统范围的默认策略。系统范围的默认策略在触发分配的CPU节点上分配页面。对于MPOL_DEFAULT,必须将nodemask和maxnode参数指定为空节点集。
MPOL_BIND
此模式指定了严格的策略,该策略将内存分配限制为在nodemask中指定的节点。如果nodemask指定多个节点,则页面分配将来自具有足够空闲内存的节点,该可用内存最接近发生分配的节点。页面不会从IR节点掩码中未指定的任何节点分配。 (在Linux 2.6.26之前,页面分配首先来自具有最低数字节点ID的节点,直到该节点不包含可用内存。然后分配来自来自节点掩码中指定的第二高节点ID的节点,依此类推,直到没有指定的节点中包含可用内存。)
MPOL_INTERLEAVE
此模式指定页面分配在节点掩码中指定的节点集之间交错。通过在多个节点之间分散页面和对这些页面的内存访问,可以优化带宽而不是延迟。为了有效发挥作用,内存区域应相当大,至少1 MB或更大,并具有相当统一的访问模式。对该区域的单个页面的访问仍将限于单个节点的内存带宽。
MPOL_PREFERRED
此模式设置要分配的首选节点。如果首选节点的可用内存不足,则内核将尝试首先从该节点分配页面,然后回退到其他节点。如果nodemask指定多个节点ID,则将选择掩码中的第一个节点作为首选节点。如果nodemask和maxnode参数指定了空集,那么将在触发分配的CPU节点上分配内存。
MPOL_LOCAL(since Linux 3.8)
此模式指定"本地分配";内存分配在触发分配的CPU的节点上("本地节点")。 nodemask和maxnode参数必须指定空集。如果"本地节点"的可用内存不足,则内核将尝试从其他节点分配内存。只要该节点的内存可用,内核就会从"本地节点"分配内存。如果线程的当前cpuset上下文不允许使用"本地节点",则内核将尝试从其他节点分配内存。只要线程的当前cpuset上下文允许,内核就会从"本地节点"分配内存。相比之下,MPOL_DEFAULT恢复为线程的内存策略(可以通过set_mempolicy(2)设置);该政策可能不是"本地分配"。

如果在标志中传递了MPOL_MF_STRICT,并且模式不是MPOL_DEFAULT,则如果内存范围中的现有页面未遵循该策略,则调用将失败,并显示错误EIO。

如果在标志中指定了MPOL_MF_MOVE,则内核将尝试移动内存范围内的所有现有页面,以便它们遵循该策略。与其他进程共享的页面将不会移动。如果还指定了MPOL_MF_STRICT,则如果无法移动某些页面,则调用将失败,并显示错误EIO。

如果在标志中传递了MPOL_MF_MOVE_ALL,则内核将尝试移动内存范围内的所有现有页面,而不管其他进程是否使用这些页面。调用线程必须具有特权(CAP_SYS_NICE)才能使用此标志。如果还指定了MPOL_MF_STRICT,则如果无法移动某些页面,则调用将失败,并显示错误EIO。

返回值

成功时,mbind()返回0;否则,返回0。如果出现错误,则返回-1并将errno设置为指示错误。

错误说明

EFAULT
由nodemask和maxnode点指定的部分或全部内存范围在可访问的地址空间之外。或者,在由addr和len指定的指定内存范围内有一个未映射的孔。
EINVAL
为标志或模式指定了无效的值;或者addr + len小于addr;或addr不是系统页面大小的倍数。或者,模式是MPOL_DEFAULT,而nodemask指定了一个非空集;或模式为MPOL_BIND或MPOL_INTERLEAVE,并且节点掩码为空。或者,maxnode超过了内核施加的限制。或者,nodemask指定一个或多个大于最大支持节点ID的节点ID。或者,nodemask指定的所有节点ID都不在线且线程当前的cpuset上下文允许,或者指定的节点均不包含内存。或者,模式参数同时指定了MPOL_F_STATIC_NODES和MPOL_F_RELATIVE_NODES。
EIO
指定了MPOL_MF_STRICT,并且现有页面已经在不遵循该策略的节点上;或MPOL_MF_MOVE或MPOL_MF_MOVE_ALL被指定,内核无法移动范围中的所有现有页面。
ENOMEM
内核内存不足。
EPERM
flags参数包括MPOL_MF_MOVE_ALL标志,并且调用方没有CAP_SYS_NICE特权。

版本

mbind()系统调用已添加到2.6.7版的Linux内核中。

遵循规范

此系统调用是特定于Linux的。

备注

有关库支持的信息,请参见numa(7)。

使用MAP_SHARED标志映射的内存映射文件范围不支持NUMA策略。

MPOL_DEFAULT模式对mbind()和set_mempolicy(2)可能具有不同的影响。为set_mempolicy(2)指定MPOL_DEFAULT时,线程的内存策略将还原为系统默认策略或本地分配。当使用mbind()为某个内存范围指定MPOL_DEFAULT时,随后为该范围分配的所有页面都将使用由set_mempolicy(2)设置的线程的内存策略。这样可以有效地将显式策略从指定范围中删除,"回退"到可能为非默认策略。要为内存范围选择显式的"本地分配",请指定MPOL_LOCAL或MPOL_PREFERRED的模式,其中包含一组空节点。此方法也适用于set_mempolicy(2)。

2.6.16添加了对大页面策略的支持。为了使交织策略在大型页面映射上有效,策略内存必须为数十兆字节或更大。

在Linux 5.7之前。 MPOL_MF_STRICT在大型页面映射上被忽略。

MPOL_MF_MOVE和MPOL_MF_MOVE_ALL仅在Linux 2.6.16和更高版本上可用。

另外参见

get_mempolicy(2),getcpu(2),mmap(2),set_mempolicy(2),shmat(2),shmget(2),numa(3),cpuset(7),numa(7),numactl(8)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/