DPDK无法分出连续大页面(contiguous hugepages)的几个解决方法
在使用DPDK或者SPDK的时候,需要在进程刚启动的时候使用rte_eal_init初始化Environment Abstract Layer,应用进程会通过这个函数告诉EAL为它映射多大的hugepages,这通常通过ealargs的-m参数来指定,就像下面这样:
char *ealargs[] = {
argv[0], // name
NULL, // core_mask(to be decided)
"-n 4", // number of memory channels per processor socket
"--proc-type=auto", // The type of process instance.
"-m 512",
};
// ....
int rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), ealargs);
if (rc < 0)
{
// error handles
}
需要注意的是,此处-m指定的hugepages的大小需要小于系统可用的hugepages大小(系统可用的Hugepages大小可以通过 `cat /proc/meminfo | grep Hugepage`查看。
但是!在系统运行一段时间后,就算是-m指定的hugepages的大小小于系统可用的Hugepages大小,EAL初始化的时候依然会panic掉,输出类似于下面的日志:
EAL: Detected 64 lcore(s)
EAL: Auto-detected process type: PRIMARY
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Can only reserve 927 pages from 4096 requested
Current CONFIG_RTE_MAX_MEMSEG=256 is not enough
Please either increase it or request less amount of memory.
PANIC in rte_eal_init():
Cannot init memory
本文简要介绍导致该问题的原因以及一些我尝试过的解法。
原因:通过阅读dpdk的代码可以发现,导致这个问题的原因,是EAL在初始化的时候,无法从操作系统的Hugepages中找到连续个数的大页面,这个连续个数,由宏RTE_MAX_MEMSEG,这个宏可以在编译dpdk的时候修改(修改config/common_base中的CONFIG_RTE_MAX_MEMSEG的值)。官方解释:These pages can be located anywhere in physical memory, and, although the DPDK EAL will attempt to allocate memory in contiguous blocks, it is possible that the pages will not be contiguous. In this case, the application is not able to allocate big memory pools. (自http://dpdk.readthedocs.io/en/v16.04/linux_gsg/build_sample_apps.html#running-a-sample-application)
解法一:
清空系统的hugepages,然后在重启应用进程:
rm -rf /dev/huagepages/*;
sh ./start_my_process.sh
一般情况下,这个解法就能解决。但是在有些场景下,这个方法无法解决。
解法二:
重新mount hagepage,然后再重启server:
umount /dev/hugepages
rm -rf /dev/hugepages
mkdir -p /dev/hugepages
mount -t hugetlbfs nodev /dev/hugepages
still not work
解法三:
源代码中看到EAL在初始化的时候,会使用/var/run/.rte_config和/var/run/.rte_hugepage_info来读取hugepage的信息,怀疑是EAL重启时如果这两个文件存在的话,直接从它们里面读取旧的hugepage信息,于是尝试umount hugepage的同时删除这个文件:
清理hugepages环境:
HUGE_MOUNT_POINT=`cat /proc/mounts | grep hugetlbfs | cut -d ' ' -f 2` # Removes hugepage filesystem.
remove_mnt_huge()
{
echo "Unmounting ${HUGE_MOUNT_POINT} and removing directory"
grep -s '${HUGE_MOUNT_POINT}' /proc/mounts > /dev/null
if [ $? -eq 0 ] ; then
sudo umount ${HUGE_MOUNT_POINT}
fi
sleep 2
if [ -d ${HUGE_MOUNT_POINT} ] ; then
sudo rm -rf ${HUGE_MOUNT_POINT}
fi
} # Removes all reserved hugepages.
clear_huge_pages()
{
echo > .echo_tmp
for d in /sys/devices/system/node/node? ; do
echo "echo 0 > $d/hugepages/hugepages-${HUGE_PAGE_SIZE}/nr_hugepages" >> .echo_tmp
done
echo "Removing currently reserved hugepages"
sudo sh .echo_tmp
rm -f .echo_tmp rm -rf /var/run/.rte_config
rm -rf /var/run/.rte_hugepage_info remove_mnt_huge
}
重建hugepage:
create_hugepages()
{
echo 8192 > /proc/sys/vm/nr_hugepages echo "Creating /mnt/huge and mounting as hugetlbfs"
sudo mkdir -p /dev/hugepages grep -s '/dev/hugepages' /proc/mounts > /dev/null
if [ $? -ne 0 ] ; then
sudo mount -t hugetlbfs nodev /dev/hugepages
fi
}
解法四:
看到EAL在初始化的时候,使用RTE_MAX_MEMSEG来判断连续大页面个数,可以将RTE_MAX_MEMSEG更改成一个更宽松的值(大于默认值256)重新编译DPDK。
实际上,这不是一个好的解法,因为你无法知道RTE_MAX_MEMSEG调整成多少合适,而且,每次调整宏,都需要重新编译DPDK,这会给调试工作带来不必要的时间负担。
解法五:
上面的解法一、二、三其实都基于一个假设,那就是你使用dpdk的进程独占了操作系统的Hugepages,一旦这个假设不成立,那么解法一、二、三就都不一定能成功解掉这个问题。解法五脱离这个假设,从整个系统的角度去考虑Hugepages的问题。
我使用的基于3.10内核的操作系统,默认打开了透明大页面功能(Transparent Hugepages),这个功能会使操作系统看到有大页面存在的时候,会在应用进程或者内核进程申请大块内存的时候,优先为它们分配大页面,大页面无法分配时,才会分配传统的4KB页面,对透明大页面感兴趣的同学请移步上两篇博文。
使用下面的命令查看哪些进程占用了系统的大页面:
# grep -e AnonHugePages /proc/*/smaps | awk '{ if($2>4) print $0} ' | awk -F "/" '{print $0; system("ps -fp " $3)} '
如果操作系统打开了透明大页面功能,同时应用进程机器上有其他耗内存的应用,上面的命令会看到很多大页面都被耗内存应用占用了。这也就是为什么使用dpdk的进程在启动的时候无法分配出连续的大页面的原因,大页面不是某个进程独占的,它是一个系统资源,如果透明大页面功能被打开,那么大页面会为所有进程服务。
到这里,问题就迎刃而解了,要么关闭透明大页面功能,这需要评估关闭后对其他应用的影响;要么暂时停掉那些使用了很多大页面的进程,重启使用dpdk的进程后,再启动它们(这不是一个好的解法);要么为系统分配更多的大页面;要么使用dpdk的进程通过-m申请更少的大页面。
在有透明大页面功能的操作系统中,有个内核进程khugepaged,它也会定期地回收大页面,整理大页面。
关闭透明大页面的方法:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
本文所有的讨论和解法,都是基于dpdk-16.07,更新或更旧的版本是否有这个问题,是否也能这么解,不得而知。
DPDK无法分出连续大页面(contiguous hugepages)的几个解决方法的更多相关文章
- DPDK无法分出大页面:EAL: No free hugepages reported in hugepages-2048kB 解决方法
参考: [dpdk-users] Fw: DPDK Error --> EAL: No free hugepages reported in hugepages-2048kB DPDK无法分出连 ...
- eclipse中的出现在打包一次后,后面新建的项目都出错了,出现support_v7下面出现红线及解决方法及为什么eclipse中项目继承ActionBarActivity解决方法一样
第一次写博客,有什么问题或者想法的希望各位可以进行评论交流,望大家多多包涵! 遇到的问题是在新建的项目都出错了,出现support_v7下面出现红线及解决方法及为什么eclipse中项目继承Actio ...
- ckfinder在IE10,IE9中的弹出框不能选择,或者不能上传解决方法
在IE9,或IE10中ckfinder在IE10,IE9中的弹出框不能选择,或者不能上传解决方法 把弹出框嵌入到jquery dialog中.可以解决 I did: // javascript f ...
- Eclipse 新建.jsp页面后,页面头部标签报错的解决方法
Eclipse 新建.jsp页面后,页面头部标签报错的解决方法 1.报错地方: 2.解决方法: .jsp页面右键==>BUild Path ==>Configure Build Path. ...
- 页面按F5重复提交数据解决方法
在Web开发中,必须面对的问题就是表单的重复提交问题(这里仅指F5刷新造成的重复提交),.NET中处理这个问题似乎没有什么好的方法. 在网上搜索得到的解决方法主要有两种,一种是直接让表单按钮失效,从而 ...
- 2、vuex页面刷新数据不保留,解决方法(转)
今天这个问题又跟页面的刷新有一定的关系,虽然说跟页面刷新的关系不大,但确实页面刷新引起的这一个问题. 场景: VueX里存储了 this.$store.state.PV这样一个变量,这个变量是在app ...
- bootstrap弹出模态框会给body加padding的解决方法
bootstrap弹出模态框会给body加padding,导致页面缩放的解决方法: 在页面或是css文件里加上($paddingSize为less变量,需要改成像素或是其他单位,如12px,1rem) ...
- 页面渲染时js阻塞的解决方法
一般地,一个包含外部样式表文件和外部脚本文件的HTML载入和渲染过程是这样的: 浏览器下载HTML文件并开始解析DOM. 遇到样式表文件link[rel=stylesheet]时,将其加入资源文件下载 ...
- 只有图片拼接的html页面图片之间有白条的解决方法
有时候会有这样的页面,整个页面也就是几张切好的图片组成,但是把这些图片使用代码拼接好,又总会出现图片间有白条的问题,如下图: 解决方法:给图片的父容器添加 line-height: 0; 就好了,因为 ...
随机推荐
- C# 简单日志文本输出
第一种 直接文件IO流写日志文件 using System.IO; public static void WriteLog(string strLog) { string sFilePath=&qu ...
- {{jQuery源码分析}}jQuery对象初始化的多种传参数形式
jQuery对象初始化的传参方式包括:1.$(DOMElement)2.$('<h1>...</h1>'), $('#id'), $('.class') 传入字符串, 这是最常 ...
- 漂亮的CSS3提交意见输入框样式
做了个输入框样式,如图: CSS代码如下: <喎�"http://www.2cto.com/kf/ware/vc/" target="_blank" cl ...
- 怎样修改SQL Server 2005/2008的系统存储过程(转)
我们知道,SQL Server 2005/2008的系统存储过程在正常情况下是无法直接修改的. 尽管本文是介绍怎样修改它的,但在这里,我还是建议大家尽量不要去修改它.(好像有点绕哈...) OK,闲话 ...
- linux邮件系统的优势和便利性
国内知名企业邮箱系统品牌商U-Mail张工在接受有关媒体采访时,特别推荐Linux版本的邮件系统.有利于与移动平台整合在Linux的U-Mail邮件服务器软件后台添加了微信版管理模块,可以查看列表,而 ...
- yield python
原文:http://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html 3. (译)Python关键字yield ...
- Springmvc 服务器端文件下载
转自:http://blog.csdn.net/boneix/article/details/51303280 业务场景:点击下载后直接保存而不是打开 解决代码:前端传入url /** * 返回流 * ...
- PowerDesigner添加表注释
之前同事用PowerDesigner 建立数据模型后,生成到数据库中,没有注释.这导致数据库使用起来不是很方便,特别是对数据表结构不熟悉的同事. 其实,可以添加注释(并且可以逆向,即从数据库中反向更新 ...
- keytab生成不了
vim /var/kerberos/krb5kdc/kadm5.acl 将*e改成* /etc/init.d/kadmin restart 重启kadmin
- 求两个有序数组的中位数或者第k小元素
问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 设两个数组分别是vec1和vec2,元素数目分别是n1.n2. 算法1:最简单的办法就是把两个数 ...