searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

ctyunos内存watermark优化详解

2023-07-03 07:53:15
83
0

ctyunos内存watermark优化详解

内存watermark对内存的使用至关重要。设置过高不能充分使用内存,造成还剩余很多时就造成OOM,设置过低时明明内存已经不足了,还不能触发kswapd回收cache内存,再次缓存巨大,且系统内存严重不足等问题。

    那内核是怎么确定默认的watermark的呢,碰到watermark,又应该怎么调整参数使其针对特定环境最优呢?

    首先我们来看看watermark在linux中计算过程,在ctyunos2中(默认内核4.19),watermark计算有两次,第一次在init_per_zone_wmark_min函数中,先通过nr_free_buffer_pages函数获取ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL区中高于high水位的总页数:

nr_free_buffer_pages = managed_pages - high_pages

再计算高于high水位的总内存大小

lowmem_kbytes = nr_free_buffer_pages * (PAGE_SHIFT-10); //4K页PAGE_SHIFT为12

最终计算出总的min大小

min_free_kbytes = 4 * sqrt(lowmem_kbytes)

且min_free_kbytes不能超过65536,超65536会被截断成65536。

第一次计算代码如图-1所示

图-1

第一次计算在配置有大页时其实还有一个问题,如果大页大小为1G时, 由于分配是通过cma, 此时的managed_pages还不包括1G大页的数量,所以min_free_kbytes的计算不会将大页内存计算在managed_pages内,但如果是2M大页,此时计算min_free_kbytes的计算会将大页内存计算在managed_pages内。所以在配置2M大页第一次计算watermark会偏大,配置1G大页时,第一次计算的watermark会偏小。

页如果内核开启透明大页则重新计算第二次(抛弃第一次计算):

在set_recommended_min_free_kbytes函数中计算所有node中ZONE_DMA/ZONE_DMA32和ZONE_NORMAL的zone总数量nr_zones,并为每个zone保留11个pageblock,

先为每个zone保留2个pageblock

recommended_min = pageblock_nr_pages * nr_zones * 2;

再为每个zone保留9个pageblock(MIGRATE_PCPTYPES=3)

recommended_min += pageblock_nr_pages * nr_zones *

              MIGRATE_PCPTYPES * MIGRATE_PCPTYPES;

计算出的recommended_min必须小于nr_free_buffer_pages的5% (即ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL区中高于high水位的总页数的5%)。

recommended_min为page数量,再转换为min_free_kbytes,需要再乘(PAGE_SHIFT-10);

第二次计算如图-2

图-2

在了解了现有的watermark两次计算方法后,再来看现有watermark存在的问题,主要存在以下4个问题:

1、在nr_free_buffer_pages中,是否排除hugepage的影响不统一,比如宿主机系统总共有1T 内存,但分配给guest的hugepage有900G,宿主机真正能使用的内存其实只有100G,但在计算min_free_kbytes时还是2M大页按照1T计算,造成min_free_kbytes过大,1G大页安装100G计算比较合理。min_free_kbytes也进一步影响watermark_min, watermark_low, watermark_high的计算。

2、在numa数量过多的cpu上,开启了透明大页时(ctyunos默认开启),由于numa过多,造成recommended_min非常巨大,但最后判断时只要不超过nr_free_buffer_pages的5%就会设置成功,进一步造成min_free_kbytes巨大。

3、通过echo xx >/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages的方式修改大页数量后,min_free_kbytes并不会同步更新,造成大页数量修改后,水线不更新。

现有的watermark计算只计算了ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL中的页,但watermark-min, watermark-low,watermark-high的设置时又包括了其他zone,比如配置了ZONE_MOVEABLE时,moveable zone也会占用min_free_kbytes。

 

针对以上问题,内核组提出了以下watermark优化:

1、对于在grub中配置的hugepage,在启动阶段分配hugepage时记录各种规格大小的hugepage在每个zone中的分布,在计算watermark时在lowmem_kbytes的基础上减去ZONE_DMA和ZONE_NORMAL中2M hugepage的大小,再以剩余大小计算总的watermark, 从而避免hugepage的影响。

2、对于开启透明大页时watermark的计算,计算完recommended_min后,从之前的recommended_min不超过可用内存(lowmem_kbytes)大小的5%,改为recommended_min不超过可用内存减去1G和2M hugapage总大小后的5%。

3、对于启动后手动调节hugepage的情况,采用记录各种规格大小的hugepage在每个zone中的分布,重新计算watermark,方法同第一次计算,在lowmem_kbytes的基础上减去ZONE_DMA和ZONE_NORMAL中各种规格大小的hugepage的大小, 再以剩下内存大小乘以16,在开平方计算总的watermark数, 从而避免hugepage对watermark的影响。

4、现有的watermark计算只计算了ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL中的页,但watermark-min, watermark-low,watermark-high的设置时又包括了其他zone,比如配置了ZONE_MOVEABLE时,moveable zone也会占用min_free_kbytes的问题,在修改相关问题的同时,也向社区提交了向patch,并以合入到mm-unstable branch(https://lore.kernel.org/all/20230702232645.BF034C433C7@smtp.kernel.org/),待进一步合入linux kernel。

    后续我们将进一步对ctyunos中的内存问题提出优化方案,使其更好的服务与天翼云各部门,对客户提供更优质的服务。

0条评论
0 / 1000
刘强
6文章数
2粉丝数
刘强
6 文章 | 2 粉丝
原创

ctyunos内存watermark优化详解

2023-07-03 07:53:15
83
0

ctyunos内存watermark优化详解

内存watermark对内存的使用至关重要。设置过高不能充分使用内存,造成还剩余很多时就造成OOM,设置过低时明明内存已经不足了,还不能触发kswapd回收cache内存,再次缓存巨大,且系统内存严重不足等问题。

    那内核是怎么确定默认的watermark的呢,碰到watermark,又应该怎么调整参数使其针对特定环境最优呢?

    首先我们来看看watermark在linux中计算过程,在ctyunos2中(默认内核4.19),watermark计算有两次,第一次在init_per_zone_wmark_min函数中,先通过nr_free_buffer_pages函数获取ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL区中高于high水位的总页数:

nr_free_buffer_pages = managed_pages - high_pages

再计算高于high水位的总内存大小

lowmem_kbytes = nr_free_buffer_pages * (PAGE_SHIFT-10); //4K页PAGE_SHIFT为12

最终计算出总的min大小

min_free_kbytes = 4 * sqrt(lowmem_kbytes)

且min_free_kbytes不能超过65536,超65536会被截断成65536。

第一次计算代码如图-1所示

图-1

第一次计算在配置有大页时其实还有一个问题,如果大页大小为1G时, 由于分配是通过cma, 此时的managed_pages还不包括1G大页的数量,所以min_free_kbytes的计算不会将大页内存计算在managed_pages内,但如果是2M大页,此时计算min_free_kbytes的计算会将大页内存计算在managed_pages内。所以在配置2M大页第一次计算watermark会偏大,配置1G大页时,第一次计算的watermark会偏小。

页如果内核开启透明大页则重新计算第二次(抛弃第一次计算):

在set_recommended_min_free_kbytes函数中计算所有node中ZONE_DMA/ZONE_DMA32和ZONE_NORMAL的zone总数量nr_zones,并为每个zone保留11个pageblock,

先为每个zone保留2个pageblock

recommended_min = pageblock_nr_pages * nr_zones * 2;

再为每个zone保留9个pageblock(MIGRATE_PCPTYPES=3)

recommended_min += pageblock_nr_pages * nr_zones *

              MIGRATE_PCPTYPES * MIGRATE_PCPTYPES;

计算出的recommended_min必须小于nr_free_buffer_pages的5% (即ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL区中高于high水位的总页数的5%)。

recommended_min为page数量,再转换为min_free_kbytes,需要再乘(PAGE_SHIFT-10);

第二次计算如图-2

图-2

在了解了现有的watermark两次计算方法后,再来看现有watermark存在的问题,主要存在以下4个问题:

1、在nr_free_buffer_pages中,是否排除hugepage的影响不统一,比如宿主机系统总共有1T 内存,但分配给guest的hugepage有900G,宿主机真正能使用的内存其实只有100G,但在计算min_free_kbytes时还是2M大页按照1T计算,造成min_free_kbytes过大,1G大页安装100G计算比较合理。min_free_kbytes也进一步影响watermark_min, watermark_low, watermark_high的计算。

2、在numa数量过多的cpu上,开启了透明大页时(ctyunos默认开启),由于numa过多,造成recommended_min非常巨大,但最后判断时只要不超过nr_free_buffer_pages的5%就会设置成功,进一步造成min_free_kbytes巨大。

3、通过echo xx >/sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages的方式修改大页数量后,min_free_kbytes并不会同步更新,造成大页数量修改后,水线不更新。

现有的watermark计算只计算了ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL中的页,但watermark-min, watermark-low,watermark-high的设置时又包括了其他zone,比如配置了ZONE_MOVEABLE时,moveable zone也会占用min_free_kbytes。

 

针对以上问题,内核组提出了以下watermark优化:

1、对于在grub中配置的hugepage,在启动阶段分配hugepage时记录各种规格大小的hugepage在每个zone中的分布,在计算watermark时在lowmem_kbytes的基础上减去ZONE_DMA和ZONE_NORMAL中2M hugepage的大小,再以剩余大小计算总的watermark, 从而避免hugepage的影响。

2、对于开启透明大页时watermark的计算,计算完recommended_min后,从之前的recommended_min不超过可用内存(lowmem_kbytes)大小的5%,改为recommended_min不超过可用内存减去1G和2M hugapage总大小后的5%。

3、对于启动后手动调节hugepage的情况,采用记录各种规格大小的hugepage在每个zone中的分布,重新计算watermark,方法同第一次计算,在lowmem_kbytes的基础上减去ZONE_DMA和ZONE_NORMAL中各种规格大小的hugepage的大小, 再以剩下内存大小乘以16,在开平方计算总的watermark数, 从而避免hugepage对watermark的影响。

4、现有的watermark计算只计算了ZONE_DMA(包括ZONE_DMA32)和ZONE_NORMAL中的页,但watermark-min, watermark-low,watermark-high的设置时又包括了其他zone,比如配置了ZONE_MOVEABLE时,moveable zone也会占用min_free_kbytes的问题,在修改相关问题的同时,也向社区提交了向patch,并以合入到mm-unstable branch(https://lore.kernel.org/all/20230702232645.BF034C433C7@smtp.kernel.org/),待进一步合入linux kernel。

    后续我们将进一步对ctyunos中的内存问题提出优化方案,使其更好的服务与天翼云各部门,对客户提供更优质的服务。

文章来自个人专栏
内核
6 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0