使用 O_TMPFILE 清理大页面...或其他方法?
using O_TMPFILE to clean up huge pages... or other methods?
我的程序正在使用大页面。为此,它打开文件如下:
oflags = O_RDWR | O_CREAT | O_TRUNC;
fd = open(filename, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
其中 filename
在 hugetlb 文件系统中。
这样可行。然后我的程序可以 mmap()
创建的文件描述符。但是如果我的程序被杀死,文件仍然存在......并且在大页面文件系统中,剩余的文件是阻塞内存,如以下命令所示(876!= 1024):
cat /proc/meminfo | grep Huge
AnonHugePages: 741376 kB
HugePages_Total: 1024
HugePages_Free: 876
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
因此,由于我的程序不与其他任何人共享文件,因此使用 O_TMPFILE 标志创建临时文件对我来说很有意义。
所以我尝试了:
oflags = O_RDWR | O_TMPFILE;
fd = open(pathname, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
其中路径名是 hugetlbfs 挂点。
失败(由于我无法解释的原因)并出现以下错误:
open failed for /dev/hugepages: Operation not supported
为什么?更重要的是:我如何保证我的程序正在使用的所有大页面都得到释放?
是的:我可以捕捉到一些信号(例如SIGTERM
);但不是全部 (SIGKILL
)
是:我可以使用第一种方法尽快 unlink()
文件,但是如果在 open()
和 unlink()
之间收到 SIGKILL
怎么办。
内核喜欢保证。我也是。无论我的程序何时或如何终止,保证 100% 清理的正确方法是什么。
看起来 O_TMPFILE 还没有为 hugetlbfs 实现;事实上,这个选项需要底层文件系统的支持:
O_TMPFILE requires support by the underlying filesystem; only a subset of Linux filesystems provide that support. In the initial implementation, support was provided in the ex2, ext3, ext4, UDF, Minix, and shmem filesystems. XFS support was added
in Linux 3.15.
这可以通过查看内核源代码来确认,其中在 hugetlbfs 中没有 inode_ops->tmpfile() 实现。
我认为这里的正确答案是致力于此实施...
我注意到您对 unlink() 选项的评论,但是,也许以下方法风险不大:
- 使用 TRUNCATE 打开文件(按名称)(因此您可以假设其大小为 0)
- 取消链接
- mmap() 它与你的目标大小
如果你的程序在中途被杀死,最坏的情况是留下一个空文件。
我的程序正在使用大页面。为此,它打开文件如下:
oflags = O_RDWR | O_CREAT | O_TRUNC;
fd = open(filename, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
其中 filename
在 hugetlb 文件系统中。
这样可行。然后我的程序可以 mmap()
创建的文件描述符。但是如果我的程序被杀死,文件仍然存在......并且在大页面文件系统中,剩余的文件是阻塞内存,如以下命令所示(876!= 1024):
cat /proc/meminfo | grep Huge
AnonHugePages: 741376 kB
HugePages_Total: 1024
HugePages_Free: 876
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
因此,由于我的程序不与其他任何人共享文件,因此使用 O_TMPFILE 标志创建临时文件对我来说很有意义。 所以我尝试了:
oflags = O_RDWR | O_TMPFILE;
fd = open(pathname, oflag, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
其中路径名是 hugetlbfs 挂点。 失败(由于我无法解释的原因)并出现以下错误:
open failed for /dev/hugepages: Operation not supported
为什么?更重要的是:我如何保证我的程序正在使用的所有大页面都得到释放?
是的:我可以捕捉到一些信号(例如SIGTERM
);但不是全部 (SIGKILL
)
是:我可以使用第一种方法尽快 unlink()
文件,但是如果在 open()
和 unlink()
之间收到 SIGKILL
怎么办。
内核喜欢保证。我也是。无论我的程序何时或如何终止,保证 100% 清理的正确方法是什么。
看起来 O_TMPFILE 还没有为 hugetlbfs 实现;事实上,这个选项需要底层文件系统的支持:
O_TMPFILE requires support by the underlying filesystem; only a subset of Linux filesystems provide that support. In the initial implementation, support was provided in the ex2, ext3, ext4, UDF, Minix, and shmem filesystems. XFS support was added in Linux 3.15.
这可以通过查看内核源代码来确认,其中在 hugetlbfs 中没有 inode_ops->tmpfile() 实现。
我认为这里的正确答案是致力于此实施...
我注意到您对 unlink() 选项的评论,但是,也许以下方法风险不大:
- 使用 TRUNCATE 打开文件(按名称)(因此您可以假设其大小为 0)
- 取消链接
- mmap() 它与你的目标大小
如果你的程序在中途被杀死,最坏的情况是留下一个空文件。