我的低水位线和高水位线似乎高于 Documentation/sysctl/vm.txt 的预测

我的低水位线和高水位线似乎高于 Documentation/sysctl/vm.txt 的预测

动机

我在这里写了一个答案:我的系统上的“水印”内存预留有多大? “正常”区域的“最小”水印显示为 31449 页。这是 125796 KiB - 比我的整个min_free_kbytes(67584) 还要大。

重置将此区域的水印min_free_kbytes设置min为预期级别(例如9582 页)。但过了一段时间,又回到了更高的水平。

我确信这是由于boost_watermark()。它增强了“最小”、“低”和“高”水印相同数量水印升压因子是15000,所以最大提升应该是原来“高”水印的150%......

问题

为什么我的“高”水印一开始就这么高? (还有“低”水印):

自从我的水印比例因子为 10,“min”、“low”和“high”之间的距离应该仅为区域大小的 0.1%。但如果我在重置后立即查看min_free_kbytes,“min”和“low”之间的差异是区域大小的 2%。为什么?

(“低”和“高”之间的差异是区域大小的 0.2%。所以这也不是我们所期望的!)。

我认为设置水印的代码位于__setup_per_zone_wmarks()

内核版本:5.0.17-200.fc29.x86_64

/proc/zoneinfo

Node 0, zone   Normal
  pages free     74597
        min      9582
        low      34505
        high     36900
        spanned  1173504
        present  1173504
        managed  1140349

我在 DMA32 区域中没有看到如此巨大的差异。看起来“最小”水印在 DMA32 区域中也没有得到提升,可能是因为内核更喜欢从“正常”区域分配。

Node 0, zone      DMA
...
  pages free     3961
        min      33
        low      41
        high     49
        spanned  4095
        present  3996
        managed  3961
...
Node 0, zone    DMA32
  pages free     334671
        min      7280
        low      9100
        high     10920
        spanned  1044480
        present  888973
        managed  866356

答案1

我弄清楚了为什么水印之间的距离与 0.1% 的数字不匹配。

在“小型系统”上,水印之间的距离是(未增强的)“最小”水印的四分之一。即,如果记录的距离managed * watermark_scale_factor / 10000小于min / 4(对于给定区域),则不使用该距离。

    } else {
        /*
         * If it's a lowmem zone, reserve a number of pages
         * proportionate to the zone's size.
         */
        zone->_watermark[WMARK_MIN] = tmp;
    }

    /*
     * Set the kswapd watermarks distance according to the
     * scale factor in proportion to available memory, but
     * ensure a minimum size on small systems.
     */
    tmp = max_t(u64, tmp >> 2,
            mult_frac(zone_managed_pages(zone),
                  watermark_scale_factor, 10000));

    zone->_watermark[WMARK_LOW]  = min_wmark_pages(zone) + tmp;
    zone->_watermark[WMARK_HIGH] = min_wmark_pages(zone) + tmp * 2;
    zone->watermark_boost = 0;

tmp >> 2相当于tmp / 4.

源码链接:linux-5.0.17/mm/page_alloc.c:7531

我还注意到这里最近有一个错误。 “高-低”和“低-最小值”之间不应该有区别!这种情况可能会发生,因为min_wmark_pages(zone)取决于zone->watermark_boost是否已设置,但在发生之前会调用它。我有报道将错误交给维护人员。

相关内容