3

通过阅读 Documentation/sysctl/vm.txt 中的解释,我无法理解变量“lowmem_reserve_ratio”的含义。我也试过用谷歌搜索它,但找到的所有解释都与 vm.txt 中的完全相似。

如果某人解释它或提及一些关于它的链接,这将非常有帮助。这是原始解释:-

The lowmem_reserve_ratio is an array. You can see them by reading this file.
-
% cat /proc/sys/vm/lowmem_reserve_ratio
256     256     32
-
Note: # of this elements is one fewer than number of zones. Because the highest
      zone's value is not necessary for following calculation.

But, these values are not used directly. The kernel calculates # of protection
pages for each zones from them. These are shown as array of protection pages
in /proc/zoneinfo like followings. (This is an example of x86-64 box).
Each zone has an array of protection pages like this.

-
Node 0, zone      DMA
  pages free     1355
        min      3
        low      3
        high     4
        :
        :
    numa_other   0
        protection: (0, 2004, 2004, 2004)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  pagesets
    cpu: 0 pcp: 0
        :
-
These protections are added to score to judge whether this zone should be used
for page allocation or should be reclaimed.

In this example, if normal pages (index=2) are required to this DMA zone and
watermark[WMARK_HIGH] is used for watermark, the kernel judges this zone should
not be used because pages_free(1355) is smaller than watermark + protection[2]
(4 + 2004 = 2008). If this protection value is 0, this zone would be used for
normal page requirement. If requirement is DMA zone(index=0), protection[0]
(=0) is used.
zone[i]'s protection[j] is calculated by following expression.

(i < j):
  zone[i]->protection[j]
  = (total sums of present_pages from zone[i+1] to zone[j] on the node)
    / lowmem_reserve_ratio[i];
(i = j):
   (should not be protected. = 0;
(i > j):
   (not necessary, but looks 0)

The default values of lowmem_reserve_ratio[i] are
    256 (if zone[i] means DMA or DMA32 zone)
    32  (others).
As above expression, they are reciprocal number of ratio.
256 means 1/256. # of protection pages becomes about "0.39%" of total present
pages of higher zones on the node.

If you would like to protect more pages, smaller values are effective.
The minimum value is 1 (1/1 -> 100%).
4

3 回答 3

4

和你有同样的问题,我用谷歌搜索(很多)并偶然发现这个页面可能(或可能不会)比内核文档更容易理解。

(我不在这里引用,因为它不可读)

于 2011-05-12T15:02:18.913 回答
2

我发现该文件中的措辞也很混乱。查看源代码mm/page_alloc.c有助于清除它,所以让我尝试更直接的解释:

正如您引用的页面中所说,这些数字“是比率的倒数”。措辞不同:这些数字是除数。因此,在计算节点中给定区域的保留页面时,您需要将该节点中高于该区域的页面总和除以提供的除数,这就是您为该区域保留的页面数。

示例:假设一个 1 GiB 节点,Normal 区域中有 768 MiB,HighMem 区域中有 256 MiB(假设没有区域 DMA)。让我们假设默认的 highmem 保留“比率”(除数)为 32。让我们假设典型的 4 KiB 页面大小。现在我们可以计算正常区域的保留区域:

  1. “更高”区域的总和比区域 Normal(仅 HighMem):256 MiB = (1024 KiB / 1 MiB) * (1 page / 4 KiB) = 65536 pages
  2. 此节点在 Normal 区域中保留的区域:65536 页 / 32 = 2048 页 = 8 MiB。

当您添加更多区域和节点时,概念保持不变。请记住,保留的大小是以页面为单位的——您永远不会保留页面的一小部分。

于 2014-10-24T07:52:04.353 回答
0

我发现内核源代码解释得非常清楚。

    /*
 * setup_per_zone_lowmem_reserve - called whenever
 *  sysctl_lowmem_reserve_ratio changes.  Ensures that each zone
 *  has a correct pages reserved value, so an adequate number of
 *  pages are left in the zone after a successful __alloc_pages().
 */
static void setup_per_zone_lowmem_reserve(void)
{
    struct pglist_data *pgdat;
    enum zone_type j, idx;

for_each_online_pgdat(pgdat) {
    for (j = 0; j < MAX_NR_ZONES; j++) {
        struct zone *zone = pgdat->node_zones + j;
        unsigned long managed_pages = zone->managed_pages;

        zone->lowmem_reserve[j] = 0;

        idx = j;
        while (idx) {
            struct zone *lower_zone;

            idx--;

            if (sysctl_lowmem_reserve_ratio[idx] < 1)
                sysctl_lowmem_reserve_ratio[idx] = 1;

            lower_zone = pgdat->node_zones + idx;
            lower_zone->lowmem_reserve[j] = managed_pages /
                sysctl_lowmem_reserve_ratio[idx];
            managed_pages += lower_zone->managed_pages;
        }
    }
}

/* update totalreserve_pages */
calculate_totalreserve_pages();
}

这里甚至列出了一个演示。

    /*
 * results with 256, 32 in the lowmem_reserve sysctl:
 *  1G machine -> (16M dma, 800M-16M normal, 1G-800M high)
 *  1G machine -> (16M dma, 784M normal, 224M high)
 *  NORMAL allocation will leave 784M/256 of ram reserved in the ZONE_DMA
 *  HIGHMEM allocation will leave 224M/32 of ram reserved in ZONE_NORMAL
 *  HIGHMEM allocation will leave (224M+784M)/256 of ram reserved in ZONE_DMA
 *
 * TBD: should special case ZONE_DMA32 machines here - in those we normally
 * don't need any ZONE_NORMAL reservation
 */
int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = {
#ifdef CONFIG_ZONE_DMA
     256,
#endif
#ifdef CONFIG_ZONE_DMA32
     256,
#endif
#ifdef CONFIG_HIGHMEM
     32,
#endif
     32,
};

总之,表达式看起来像,

zone[1]->lowmem_reserve[2] =  zone[2]->managed_pages / sysctl_lowmem_reserve_ratio[1] 
zone[0]->lowmem_reserve[2] =  (zone[1] + zone[2])->managed_pages / sysctl_lowmem_reserve_ratio[0] 
于 2019-12-07T14:49:37.070 回答