1. HugePages
内核支持
内核需要打开以下编译开关。重新编译。
CONFIG_HUGETLBFS = y
CONFIG_HUGETLB_PAGE = y
2. HugePages
内核启动参数
HugePages
内存页是不会被系统交换出去(swapped out)的。
由于HugePages
需要更大的连续物理内存,所以在系统启动时更容易获得更多的HugePages
内存,并且还能尽量保证这些HugePages
内存页连续。
可以通过添加对应的内核启动参数来实现:
项目 | 描述 |
---|---|
hugepages | HugePages 个数 |
hugepagesz | 单个HugePages 字节大小 |
default_hugepagesz | 默认HugePages 字节大小 |
例子:
hugepages=10 hugepagesz=2M default_hugepagesz=4M
注意:
- 如果系统不支持设置的默认
HugePages
内存页大小,实际的HugePages
内存页大小会保持2M。
3. 总的HugePages
3.1. 总的HugePages
的查看
/proc/meminfo
有总的内存信息,可以通过查找Huge
关键字。得出HugePages
的信息。
例子:
cat /proc/meminfo | grep Huge
> AnonHugePages: 28672 kB
> HugePages_Total: 0
> HugePages_Free: 0
> HugePages_Rsvd: 0
> HugePages_Surp: 0
> Hugepagesize: 2048 kB
其中HugePages
内存信息的解释如下:
项目 | 描述 |
---|---|
HugePages_Total | 系统当前总共拥有的HugePages 个数。 |
HugePages_Free | 系统当前总共拥有的空闲HugePages 个数。 |
HugePages_Rsvd | (reserved)系统当前总共保留的HugePages 个数(备注1) |
HugePages_Surp | (surplus)实际使用的超发HugePages 个数。(备注2) |
Hugepagesize | 每一页HugePages 的字节大小。 |
备注1:
- 指程序已经向系统申请,但是由于程序还没有对
HugePages
实质的读写操作,系统尚未实际分配给程序的HugePages
个数。
备注2:
- 可以通过
/proc/sys/vm/nr_overcommit_hugepages
来控制最大超发的HugePages
个数。
3.2. HugePages
的在/proc/sys/vm
的接口
HugePages
的在/proc/sys/vm
,有/proc
系统接口用于调节HugePages
参数。
项目 | 描述 | 权限 |
---|---|---|
nr_hugepages | 写入常驻或读取实际的HugePages 个数 | 读写 |
nr_hugepages_mempolicy | NUMA node 的HugePages 个数 | 读写 |
nr_overcommit_hugepages | 超发的HugePages 个数 | 读写 |
ll . /proc/sys/vm/*huge*
> -rw-r--r-- 1 root root 0 Mar 2 12:03 /proc/sys/vm/hugepages_treat_as_movable
> -rw-r--r-- 1 root root 0 Mar 2 12:03 /proc/sys/vm/hugetlb_shm_group
> -rw-r--r-- 1 root root 0 Mar 2 12:03 /proc/sys/vm/nr_hugepages
> -rw-r--r-- 1 root root 0 Mar 2 12:03 /proc/sys/vm/nr_hugepages_mempolicy
> -rw-r--r-- 1 root root 0 Mar 2 12:03 /proc/sys/vm/nr_overcommit_hugepages
grep . /proc/sys/vm/*huge*
> /proc/sys/vm/hugepages_treat_as_movable:0
> /proc/sys/vm/hugetlb_shm_group:0
> /proc/sys/vm/nr_hugepages:0
> /proc/sys/vm/nr_hugepages_mempolicy:0
> /proc/sys/vm/nr_overcommit_hugepages:0
3.3. 总的HugePages
的分配
/proc/sys/vm/nr_hugepages
用于设定常驻的HugePages
个数,可读可写。
注意:
- 设定的之前先清零,重新生成
HugePages
页面。 - 设定的时候,系统会根据当前可用物理内存计算出可以组成的
HugePages
个数。 - 读取,就可以得到实际分配的
HugePages
个数。
# 清零
echo 0 > /proc/sys/vm/nr_hugepages
# 设置 100个 `HugePages`
echo 100 > /proc/sys/vm/nr_hugepages
# 查询实际`HugePages`的个数
cat /proc/sys/vm/nr_hugepages
> 100
3.4. HugePages
分配策略
注意:
这个接口相对落后,请使用单个NUMA node
的HugePages
的分配代替。
/proc/sys/vm/nr_hugepages_mempolicy
用于设定多个NUMA node
的HugePages
个数,可读可写。
注意:
- 默认情况下系统所有
NUMA node
平均分配所有HugePages
。 - 除非
NUMA node
本身没有足够的内存来生成HugePages
,那么将由另外一个生成。 - 指定
NUMA node
分配HugePages
,需要配合numactl -m
一起使用。
使用方法:
# 所有`NUMA node`平均分配所有`HugePages`
echo ${huge_page_count} > /proc/sys/vm/nr_hugepages_mempolicy
# 指定`${node-list}`分配`HugePages`
numactl -m ${node-list} echo ${huge_page_count} > /proc/sys/vm/nr_hugepages_mempolicy
例子:
# 清零
echo 0 > /proc/sys/vm/nr_hugepages
# 从`NUMA node0`分配。总数40 个`HugePages`
numactl -m 0 echo 40 > /proc/sys/vm/nr_hugepages_mempolicy
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`分配 新增40 个`HugePages`
> Node 0 HugePages_Total: 40
> Node 0 HugePages_Free: 40
> Node 0 HugePages_Surp: 0
> # `NUMA node1`保持 `HugePages` 不变
> Node 1 HugePages_Total: 0
> Node 1 HugePages_Free: 0
> Node 1 HugePages_Surp: 0
# 从`NUMA node1`分配。总数60 个`HugePages`
numactl -m 1 echo 60 > /proc/sys/vm/nr_hugepages_mempolicy
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`保持 `HugePages` 不变
> Node 0 HugePages_Total: 40
> Node 0 HugePages_Free: 40
> Node 0 HugePages_Surp: 0
> # `NUMA node1`分配 新增20 个`HugePages`
> Node 1 HugePages_Total: 20
> Node 1 HugePages_Free: 20
> Node 1 HugePages_Surp: 0
# 所有`NUMA node`平均分配。总数80 个`HugePages`
echo 80 >/proc/sys/vm/nr_hugepages_mempolicy
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`分配 新增10 个`HugePages`
> Node 0 HugePages_Total: 50
> Node 0 HugePages_Free: 50
> Node 0 HugePages_Surp: 0
> # `NUMA node1`分配 新增10 个`HugePages`
> Node 1 HugePages_Total: 30
> Node 1 HugePages_Free: 30
> Node 1 HugePages_Surp: 0
# 所有`NUMA node`平均分配。总数100 个`HugePages`
# 注意`/proc/sys/vm/nr_hugepages`无法配合`numactl`使用
numactl -m 1 echo 100 > /proc/sys/vm/nr_hugepages
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`分配 新增10 个`HugePages`
> Node 0 HugePages_Total: 60
> Node 0 HugePages_Free: 60
> Node 0 HugePages_Surp: 0
> # `NUMA node1`分配 新增10 个`HugePages`
> Node 1 HugePages_Total: 40
> Node 1 HugePages_Free: 40
> Node 1 HugePages_Surp: 0
# 所有`NUMA node`平均分配。总数80 个`HugePages`
# 注意`/proc/sys/vm/nr_hugepages`无法配合`numactl`使用
numactl -m 1 echo 80 > /proc/sys/vm/nr_hugepages
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`分配 减少10 个`HugePages`
> Node 0 HugePages_Total: 50
> Node 0 HugePages_Free: 50
> Node 0 HugePages_Surp: 0
> # `NUMA node1`分配 减少10 个`HugePages`
> Node 1 HugePages_Total: 30
> Node 1 HugePages_Free: 30
> Node 1 HugePages_Surp: 0
# 从`NUMA node1`分配。总数60 个`HugePages`
numactl -m 1 echo 60 > /proc/sys/vm/nr_hugepages_mempolicy
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`保持 `HugePages` 不变
> Node 0 HugePages_Total: 50
> Node 0 HugePages_Free: 50
> Node 0 HugePages_Surp: 0
> # `NUMA node1`分配 减少20 个`HugePages`
> Node 1 HugePages_Total: 10
> Node 1 HugePages_Free: 10
> Node 1 HugePages_Surp: 0
# 从`NUMA node0`分配。总数30 个`HugePages`
numactl -m 0 echo 30 > /proc/sys/vm/nr_hugepages_mempolicy
# 查看所有分配
cat /sys/devices/system/node/node*/meminfo | grep Huge
> # `NUMA node0`分配 减少20 个`HugePages`
> Node 0 HugePages_Total: 20
> Node 0 HugePages_Free: 20
> Node 0 HugePages_Surp: 0
> # `NUMA node1`保持 `HugePages` 不变
> Node 1 HugePages_Total: 10
> Node 1 HugePages_Free: 10
> Node 1 HugePages_Surp: 0
3.5. HugePages
超发
/proc/sys/vm/nr_overcommit_hugepages
,表示最大超发的HugePages
个数,可读可写。
例子:
# 清零
echo 0 > /proc/sys/vm/nr_hugepages
echo 0 > /proc/sys/vm/nr_overcommit_hugepages
# 设置常驻`HugePages`个数是4
echo 4 > /proc/sys/vm/nr_hugepages
# 设置超发`HugePages`个数是4
echo 4 > /proc/sys/vm/nr_overcommit_hugepages
# [没有使用`HugePages`]
cat /proc/meminfo | grep HugePages_
> HugePages_Total: 4
> HugePages_Free: 4
> HugePages_Rsvd: 0
> HugePages_Surp: 0
# [合计使用了3个`HugePages`。但是没有读写]
cat /proc/meminfo | grep HugePages_
> HugePages_Total: 4 # 总共分配了4个`HugePages`
> HugePages_Free: 4 # 由于没有读写。所以空闲4个`HugePages`
> HugePages_Rsvd: 3 # 由于没有读写。所以保留3个`HugePages`
> HugePages_Surp: 0 # 实际超发了0个`HugePages`
# [合计用了3个`HugePages`。并且已经读写]
cat /proc/meminfo | grep HugePages_
> HugePages_Total: 4 # 总共分配了4个`HugePages`
> HugePages_Free: 1 # 由于已经读写。所以空闲1个`HugePages`
> HugePages_Rsvd: 0 # 由于已经读写。所以没有保留`HugePages`
> HugePages_Surp: 0 # 实际超发了0个`HugePages`
# [合计用了6个`HugePages`。但是没有读写]
cat /proc/meminfo | grep HugePages_
> HugePages_Total: 6 # 总共分配了6个`HugePages`
> HugePages_Free: 6 # 由于没有读写。所以空闲6个`HugePages`
> HugePages_Rsvd: 6 # 由于没有读写。所以保留6个`HugePages`
> HugePages_Surp: 2 # 实际超发了2个`HugePages`
# [合计用了6个`HugePages`。并且已经读写]
cat /proc/meminfo | grep HugePages_
> HugePages_Total: 6 # 总共分配了6个`HugePages`
> HugePages_Free: 0 # 由于已经读写。所以没有空闲`HugePages`
> HugePages_Rsvd: 0 # 由于已经读写。所以没有保留`HugePages`
> HugePages_Surp: 2 # 实际超发了2个`HugePages`
3.6. 参数之间的关系式
以下是一般情况下,参数之间的关系式:
nr_hugepages <= HugePages_Total <= (nr_hugepages + nr_overcommit_hugepages)
HugePages_Rsvd <= HugePages_Free <= HugePages_Total
HugePages_Surp == (HugePages_Total - nr_hugepages) <= nr_overcommit_hugepages
3.7. HugePages
在/sys/kernel/mm/hugepages/
的接口
如果系统支持多种大小的HugePages
,就会有多个/sys/kernel/mm/hugepages/hugepages-${huge_page_size}
目录。
${huge_page_size}
为HugePages
的字节数。默认是2048kB
。
每一个目录下存在相同的的一些HugePages
系统文件。可用于设置或者查看系统信息。
项目 | 描述 | 权限 |
---|---|---|
nr_hugepages | 写入常驻或读取实际的HugePages 个数 | 读写 |
nr_hugepages_mempolicy | NUMA node 的HugePages 个数 | 读写 |
nr_overcommit_hugepages | 最大容许超发HugePages 个数 | 读写 |
free_hugepages | 空闲HugePages 个数 | 只读 |
resv_hugepages | 保留的HugePages 个数 | 只读 |
surplus_hugepages | 实际使用的超发HugePages 个数 | 只读 |
以下例子的系统只有一种大小的HugePages
,所以只有一个/sys/kernel/mm/hugepages/hugepages-2048kB
目录。
# 打印`HugePages`系统文件
ll /sys/kernel/mm/hugepages/ -R
> /sys/kernel/mm/hugepages/:
> total 0
> drwxr-xr-x 2 root root 0 Mar 2 09:57 hugepages-2048kB
>
> /sys/kernel/mm/hugepages/hugepages-2048kB:
> total 0
> -r--r--r-- 1 root root 4096 Mar 2 09:58 free_hugepages
> -rw-r--r-- 1 root root 4096 Mar 2 09:58 nr_hugepages
> -rw-r--r-- 1 root root 4096 Mar 2 09:58 nr_hugepages_mempolicy
> -rw-r--r-- 1 root root 4096 Mar 2 09:58 nr_overcommit_hugepages
> -r--r--r-- 1 root root 4096 Mar 2 09:58 resv_hugepages
> -r--r--r-- 1 root root 4096 Mar 2 09:58 surplus_hugepages
# 打印`HugePages`系统文件的数值
grep . -r /sys/kernel/mm/hugepages/
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:0
4. NUMA node
的HugePages
单个NUMA node
的HugePages
的/sys
接口,可以提供更加准确的配置和查看功能。
注意:
- 无法配置
nr_overcommit_hugepages
。 - 无法查看
resv_hugepages
4.1. 单个NUMA node
的HugePages
的/sys
接口
如果系统支持多种大小的HugePages
,每个NUMA node
就会有多个/sys/devices/system/node/node${numa_node_id}/hugepages/hugepages-${huge_page_size}
目录。
${numa_node_id}
的数值范围为整数,计数从零开始。${huge_page_size}
为HugePages
的字节数。默认是2048kB
。
每一个目录下存在相同的的一些HugePages
系统文件。可用于设置或者查看系统信息。
项目 | 描述 | 权限 |
---|---|---|
nr_hugepages | 写入常驻或读取实际的HugePages 个数 | 读写 |
free_hugepages | 空闲HugePages 个数 | 只读 |
surplus_hugepages | 实际使用的超发HugePages 个数 | 只读 |
例子:
l -R /sys/devices/system/node/node*/hugepages/
> # noed0
> /sys/devices/system/node/node0/hugepages/:
> total 0
> drwxr-xr-x 2 root root 0 Mar 2 09:44 hugepages-2048kB
>
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB:
> total 0
> -r--r--r-- 1 root root 4096 Mar 2 09:44 free_hugepages
> -rw-r--r-- 1 root root 4096 Mar 2 09:44 nr_hugepages
> -r--r--r-- 1 root root 4096 Mar 2 09:44 surplus_hugepages
>
> # node1
> /sys/devices/system/node/node1/hugepages/:
> total 0
> drwxr-xr-x 2 root root 0 Mar 2 09:44 hugepages-2048kB
>
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB:
> total 0
> -r--r--r-- 1 root root 4096 Mar 2 09:44 free_hugepages
> -rw-r--r-- 1 root root 4096 Mar 2 09:44 nr_hugepages
> -r--r--r-- 1 root root 4096 Mar 2 09:44 surplus_hugepages
grep . -r /sys/devices/system/node/node*/hugepages/
> # node0
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0
> # node1
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/free_hugepages:0
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages:0
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/surplus_hugepages:0
4.2. 单个NUMA node
的HugePages
的查看
/sys/devices/system/node/node${numa_node_id}/meminfo
,可以查看${numa_node_id}
的HugePages
内存信息。
${numa_node_id}
的数值范围为整数,计数从零开始。
例子:
grep Huge /sys/devices/system/node/node*/meminfo
# node0
> Node 0 HugePages_Total: 4
> Node 0 HugePages_Free: 4
> Node 0 HugePages_Surp: 0
# node1
> Node 1 HugePages_Total: 0
> Node 1 HugePages_Free: 0
> Node 1 HugePages_Surp: 0
以下的free_hugepages
和surplus_hugepages
也可以用于查看单个NUMA node
的HugePages
内存信息。
/sys/devices/system/node/node${numa_node_id}/hugepages/hugepages-${huge_page_size}/free_hugepages
/sys/devices/system/node/node${numa_node_id}/hugepages/hugepages-${huge_page_size}/surplus_hugepages
${numa_node_id}
的数值范围为整数,计数从零开始。${huge_page_size}
为HugePages
的字节数。默认是2048kB
。
4.3. 单个NUMA node
的HugePages
的分配
/sys/devices/system/node/node${numa_node_id}/hugepages/hugepages-${huge_page_size}/nr_hugepages
用于设置单个NUMA node
的HugePages
内存信息。可读可写。
${numa_node_id}
的数值范围为整数,计数从零开始。${huge_page_size}
为HugePages
的字节数。默认是2048kB
。
例子:
# 清零
echo 0 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
# `NUMA node0`分配 4 个 `HugePages`
echo 4 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
# 超发`HugePages`为 4
echo 4 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages
# [没有使用`HugePages`]
grep . -r /sys/kernel/mm/hugepages/
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:4
grep . -r /sys/devices/system/node/node*/hugepages/
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0
# [合计使用了3个`HugePages`。但是没有读写]
grep . -r /sys/kernel/mm/hugepages/
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:3
> /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:4
grep . -r /sys/devices/system/node/node*/hugepages/
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0
# [合计用了3个`HugePages`。并且已经读写]
grep . -r /sys/kernel/mm/hugepages/
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:1
> /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:4
grep . -r /sys/devices/system/node/node*/hugepages/
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:4
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:1
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:0
# [合计用了6个`HugePages`。但是没有读写]
grep . -r /sys/kernel/mm/hugepages/
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:6
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:6
> /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:6
> /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:2
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:6
grep . -r /sys/devices/system/node/node*/hugepages/
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:6
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:6
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:2
# [合计用了6个`HugePages`。并且已经读写]
grep . -r /sys/kernel/mm/hugepages/
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages:6
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_overcommit_hugepages:4
> /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/resv_hugepages:0
> /sys/kernel/mm/hugepages/hugepages-2048kB/surplus_hugepages:2
> /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages_mempolicy:6
grep . -r /sys/devices/system/node/node*/hugepages/
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages:6
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages:0
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/surplus_hugepages:2
5. 例程
以下的例程可以用于打开和读写HugePages
。
使用方法:
# 输入`HugePages`的个数。每一个`HugePages`为2048KB。
hugepage <hugepage_count_in_2048KB>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
/* ---------------------------------- */
/* hugepage defination */
/* ---------------------------------- */
#define HUGEPAGE_SIZE(count) ((count)*2UL*1024UL*1024UL)
struct hugepage {
key_t key;
int id;
size_t size;
void *address;
};
int hugepage_open(struct hugepage *hugepage, key_t key, size_t size);
void hugepage_close(struct hugepage *hugepage);
void hugepage_dump(struct hugepage *hugepage);
/* ---------------------------------- */
/* main */
/* ---------------------------------- */
#define DEFAULT_KEY (0x11111)
#define DEFAULT_COUNT (1)
int main(int argc, char *argv[])
{
struct hugepage hugepage;
int error_code;
int count;
size_t hugepage_count = DEFAULT_COUNT;
if (argc > 1) {
count = atoi(argv[1]);
if (count <= 0) {
printf("usage: %s <hugepage_count>\n", argv[0]);
goto fail_user_input;
}
hugepage_count = (size_t)count;
}
error_code = hugepage_open(&hugepage
, DEFAULT_KEY
, HUGEPAGE_SIZE(hugepage_count));
if (0 != error_code) {
goto fail_open;
}
printf("hugepage allocated: \n");
hugepage_dump(&hugepage);
printf("Press any key to access hugepage!\n");
getchar();
memset(hugepage.address, 0, hugepage.size);
printf("Press any key to free hugepage and exit!\n");
getchar();
hugepage_close(&hugepage);
return 0;
fail_open:
perror("hugepage open fail");
fail_user_input:
return -1;
}
/* ---------------------------------- */
/* hugepage implement */
/* ---------------------------------- */
int hugepage_open(struct hugepage *hugepage, key_t key, size_t size)
{
int id;
void *address;
if (NULL == hugepage) {
return -EINVAL;
}
/* create */
id = shmget(key
, size
, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W
);
if (id < 0) {
goto fail_create;
}
/* get address */
address = shmat(id, NULL, 0);
if ((void *)-1 == address) {
goto fail_get_address;
}
hugepage->key = key;
hugepage->id = id;
hugepage->size = size;
hugepage->address = address;
return 0;
/* error handle */
fail_get_address:
shmctl(id, IPC_RMID, NULL);
fail_create:
return -EAGAIN;
}
void hugepage_close(struct hugepage *hugepage)
{
if (NULL == hugepage
|| 0 == hugepage->id) {
return ;
}
shmctl(hugepage->id, IPC_RMID, NULL);
}
void hugepage_dump(struct hugepage *hugepage)
{
if (NULL == hugepage) {
return ;
}
printf(
"hugepage(%p) = {\n"
" key = 0x%x\n"
" id = %u\n"
" size = %llu\n"
" address = %p\n"
"}\n"
, hugepage
, hugepage->key
, hugepage->id
, hugepage->size
, hugepage->address
);
}