From patchwork Sat Mar 15 21:13:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiwen Qi X-Patchwork-Id: 14018252 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96B52C28B28 for ; Sat, 15 Mar 2025 21:13:24 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 24C0A280002; Sat, 15 Mar 2025 17:13:23 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1D6E8280001; Sat, 15 Mar 2025 17:13:23 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 028A6280002; Sat, 15 Mar 2025 17:13:22 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id D0894280001 for ; Sat, 15 Mar 2025 17:13:22 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 32B7EC023F for ; Sat, 15 Mar 2025 21:13:23 +0000 (UTC) X-FDA: 83225036286.19.48C6B42 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by imf22.hostedemail.com (Postfix) with ESMTP id 4BAC5C0003 for ; Sat, 15 Mar 2025 21:13:21 +0000 (UTC) Authentication-Results: imf22.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=EBd7wIg7; spf=pass (imf22.hostedemail.com: domain of jiwen7.qi@gmail.com designates 209.85.221.42 as permitted sender) smtp.mailfrom=jiwen7.qi@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1742073201; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=/tJKat2QAckBOZxJUWt5rfLHO+YRyqVbSCaW0dLLlwE=; b=72S1qjR8izvdeuEjsCFgA1yB8U5BTiab/7LnNXDXEkiTt4AqDI8YrAkXiSlp4CHnxmORLA e1s2FLdkVGt7UBDASMB4Fgbf02egZaKOGvWLuBiRmGg9yAIBZudF7f8ezfqo5TQxddvqvr 3AVH0+jmubLW2lzjYVD+p/GB0VoNzfo= ARC-Authentication-Results: i=1; imf22.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=EBd7wIg7; spf=pass (imf22.hostedemail.com: domain of jiwen7.qi@gmail.com designates 209.85.221.42 as permitted sender) smtp.mailfrom=jiwen7.qi@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1742073201; a=rsa-sha256; cv=none; b=fwK8+cSIACjmBUXRkzlMRircPTq13oKZotR9VNjeBK7lHMmuwhtbJ2AiR5FAkg18Ur8ccF royjY3bTtYkKBtGFD1ht8AeFvw8IdUZ4aIqTXNXKgO1cUrNJpomQOOY2b7b3LYBzFDx17z Hxw/OsfYOOqxA2rIVuSvttoG94mAgkM= Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-39127512371so1951425f8f.0 for ; Sat, 15 Mar 2025 14:13:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742073200; x=1742678000; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/tJKat2QAckBOZxJUWt5rfLHO+YRyqVbSCaW0dLLlwE=; b=EBd7wIg7bcQG1wlwqDOteBLzodGsNgHTsCZAyY7TyShIXd9TpHPNQ7P33u7JBCUOqc I9TggiDm32SjRkc1VnGMbuehnZ676vX9P5Crmq/aX7m86p4t2JtEwAFvTvZXNBe2oClw SY490UcfHK9OA/ymgfGLUlKfhPFidX8nk2kn342i4UzdY5KZEr8gX4FROi3DZbDDjRiO XQouot6j7NFVHNX8yDsgeK+TEUDuZYQnD38zGguICIv7LGbogc5+QfsxYb3kUyZkUESd 8g0G9m1TCLC7xR8Wyye66y0SoNei7FSrDEF6GbfzU2E//CjXf/oQttpkVI66jI9Fl383 0Dmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742073200; x=1742678000; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/tJKat2QAckBOZxJUWt5rfLHO+YRyqVbSCaW0dLLlwE=; b=gmu5SAxhc7SqJ4SCJOJPj03kZxZgwaWpcRqXbB6eCw/Jv5hld0yTE1J0VuCDpoX3jZ FZoUC/y5mz9tcojC0kCkfo7PtNouyqnKcgWwZdGEtoL9cQ3umaMC9WabRPBexnkGQO3C /5J2JKcqUCO9APY7PppClJUm5Zq4+rFTDZNsc5YoH1bsOP7wcGljYJKpufK2P4k2+gNd fSstGDDNS9iIBoLgLg9anAWiXJY4YSePFZCgW4jskfyNej3CvMh9uPUzAOs9/BhRe9wh gwhRYLH5R/17hVKaSUMlr7rtASTNSnPhkaIQ1JQfN/sh1ulHgYkefEYrOskG9g12OvXg z0Mg== X-Gm-Message-State: AOJu0YwD7yONsoMc5EyaN6mJgH6/1/Cgv8Cqtl4Nthn17sqqbUZ5dyVJ v8GPge5E/CEcGc3ZMlBOpyk7xhvaXIIOgZulwVMpWB7D4no4CQdH X-Gm-Gg: ASbGncvSdvGySKwnyFl2iFpY3Ecr4BW5Szv1f86vwJXG9TFel5XQVwwHwsiDhRxNGTr ZMkzmZk8HB62Ykf5WlYg9NRzuZQCmxgBpRXUoLzv/AP18Y8gWosJ6nfdiSIzlBcZxdu6GhcoXqH TYSoiWHAEUerc67AY9eARVHdpUYDFTv0Qz9lqMMHRWyiY1I/k0ZUYMzuOHUBH6+QFEgyJpfrGOP DxEUaYJtBqhhT1CGgrypczAPgNLcbupTm2exQKIv9Yp3rTWoP8ZMpwJFI/XScwYm3t4MpAdwoCu 752TAseqqT7MwhsKHUKO4hkCzclcob7QimKJTc2fVs6yaO3raQsrEv18HB9fdxvi2zf+Jgjirp2 JVj96FNzyqxfuFC2dB+A= X-Google-Smtp-Source: AGHT+IFi7vyK+WpAf0ZG7Fr3tZKf0xhJnR3/jXSxxQVPaYi0mgkLkfGKJLlYCR2FlnWXmteR3vTSSQ== X-Received: by 2002:a05:6000:4020:b0:390:f902:f973 with SMTP id ffacd0b85a97d-3971d13629bmr8910290f8f.8.1742073199460; Sat, 15 Mar 2025 14:13:19 -0700 (PDT) Received: from localhost (cpc83567-brig19-2-0-cust951.3-3.cable.virginm.net. [86.9.27.184]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43d2010de59sm59386715e9.33.2025.03.15.14.13.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 15 Mar 2025 14:13:18 -0700 (PDT) From: Jiwen Qi To: akpm@linux-foundation.org Cc: linux-mm@kvack.org, corbet@lwn.net, linux-doc@vger.kernel.org, rppt@kernel.org, bagasdotme@gmail.com Subject: [PATCH v2] docs/mm: Physical Memory: Populate the "Zones" section Date: Sat, 15 Mar 2025 21:13:17 +0000 Message-Id: <20250315211317.27612-1-jiwen7.qi@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250223185359.338647-1-jiwen7.qi@gmail.com> References: <20250223185359.338647-1-jiwen7.qi@gmail.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 4BAC5C0003 X-Stat-Signature: goc95erwujawudsts1ykxpqbwwgdsrjg X-HE-Tag: 1742073201-145856 X-HE-Meta: U2FsdGVkX1+I6yiOjtZw6NoPq+Aew0sSQXpTN0GgFclYFPukORqhm2HF2ptPkr4VTIDsqoGTY6x5fy24nBp76Sbbh2m1uL7KqiY3If37EJhgiHGdeT//LD7VPt16qCI57xxJ3wB0MmTT4hrdrq2+z6cL0bxVv63vbcrCKjL/VuwIBEaHsJ1EQo7q92NRJG+B1UBm2Itx3Fm5pe60ITvMbqK60kZpQ4FqUPVsuuuS1GfNPHD/0+PCIizay/Yp8sncVcpudkPOry7aX+a7Ufn/oZNOkwz7c5h+3yxUS2bb+4pL8Xyz8fE1f/rFMB2INVsQgWzAJcbBLFlQby72RHTw4kHTe8q4DnOnsYp2BujYMhVfG9PzUVeksLPrOjvjf36Kr1CxbpZ9Dh5FFseHcOwBld/nHTHqtIlzhtxJHr0SMmYYo5auC2GThjklnmVisCq/k9LOYIaV9xOhVp4kT5ZxZ30VidXnetkRhdtfZxSSp7w+DruwIVurJN/Sg4Wrt9MXQZH90AUoMP00CtcNt7OnBPJ71kqyHNq4b7gVnRExAAQOwnvnc97NFQictvTbATKI8uN5OC6x8dHbCfxbgmvwE3GrjZCpJEtQYxSoNSK0m1NJE9J1GhtqCEGxD7+sERMfl8k7dt62sWT5wQZ5MqEDR+EPSv/vBBetTM9opoVQSgpEND8ZVUDsBDJfqXcJnaoWTuo7FUrbz8OT/BS1G2ZpCHoJThLUGmRIY+cgaXluJNIDgYQ2xBEXmQeyKE3Mhbk1iTn6C8nY/dz5fYxcxuK7kTVj82k/RjBXjfWirOEeAULHFhnSTM+v+QRyDYUEXctwcrbfNQN6AW8/HB/AqrHEjggNwmgRoRMaANDv5q2aU3D4NnyPTuhakAvSrgQEIvblTAgILo2gyrouWUhFgEIHOKSBEGLfJquDejhgieAwXKqh7iNHwO0msPm6jqIVNSZwe9LyI0GjtVDqy4bD1TX Z4Q/I6/O fBBvIpPSM9ufvy5wqA0ePiRqaIFazuXWTs/ecz3m5lEJ5WyeIcgVddK3GkPT01/MZ3aakq1ukaa2DalLzZv/K7/gqgGCbX+mSgdcYgkifLln8xE+kIyaSoRo/11wPmJSspMEnUtTBBqNqwJeky+z0+tmVWpRE+6EsMDwyFPh3Bl6GDs8u8sMNputAmKhnf3bvcTbXoln+8/2CmscX+GpUyzPtQemz0j2ocUHAtab2UouuEzEJdvpN2O//jalbQYclcCx6QZszdidt/2/ewXthTvEZ2fRF8y108E39vvUxobqoOl/kk/Upxsrn11o2kEO/JfWUolAQa8tI1H6qndW51jDBgQjZMXZwfR25/chkDhaQ+qHYFy6KvE2kiRQkfdYn37AYpj2JeQTiBh9+G7mmN5P6AmDFZQbPdrx6dj8tw63bz+7e5VoxJBk7vE5k2kley6Z4mj+oTEm02B4= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Briefly describe what zones are and the fields of struct zone. Signed-off-by: Jiwen Qi Acked-by: Mike Rapoport (Microsoft) --- Changes since v1: - Addressed review comments from Bagas Sanjaya. - Addressed review comments from Mike Rapoport. Documentation/mm/physical_memory.rst | 266 ++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 2 deletions(-) base-commit: 0ad2507d5d93f39619fc42372c347d6006b64319 diff --git a/Documentation/mm/physical_memory.rst b/Documentation/mm/physical_memory.rst index 71fd4a6acf42..d3ac106e6b14 100644 --- a/Documentation/mm/physical_memory.rst +++ b/Documentation/mm/physical_memory.rst @@ -338,10 +338,272 @@ Statistics Zones ===== +As we have mentioned, each zone in memory is described by a ``struct zone`` +which is an element of the ``node_zones`` array of the node it belongs to. +``struct zone`` is the core data structure of the page allocator. A zone +represents a range of physical memory and may have holes. + +The page allocator uses the GFP flags, see :ref:`mm-api-gfp-flags`, specified by +a memory allocation to determine the highest zone in a node from which the +memory allocation can allocate memory. The page allocator first allocates memory +from that zone, if the page allocator can't allocate the requested amount of +memory from the zone, it will allocate memory from the next lower zone in the +node, the process continues up to and including the lowest zone. For example, if +a node contains ``ZONE_DMA32``, ``ZONE_NORMAL`` and ``ZONE_MOVABLE`` and the +highest zone of a memory allocation is ``ZONE_MOVABLE``, the order of the zones +from which the page allocator allocates memory is ``ZONE_MOVABLE`` > +``ZONE_NORMAL`` > ``ZONE_DMA32``. + +At runtime, free pages in a zone are in the Per-CPU Pagesets (PCP) or free areas +of the zone. The Per-CPU Pagesets are a vital mechanism in the kernel's memory +management system. By handling most frequent allocations and frees locally on +each CPU, the Per-CPU Pagesets improve performance and scalability, especially +on systems with many cores. The page allocator in the kernel employs a two-step +strategy for memory allocation, starting with the Per-CPU Pagesets before +falling back to the buddy allocator. Pages are transferred between the Per-CPU +Pagesets and the global free areas (managed by the buddy allocator) in batches. +This minimizes the overhead of frequent interactions with the global buddy +allocator. + +Architecture specific code calls free_area_init() to initializes zones. + +Zone structure +-------------- +The zones structure ``struct zone`` is defined in ``include/linux/mmzone.h``. +Here we briefly describe fields of this structure: -.. admonition:: Stub +General +~~~~~~~ - This section is incomplete. Please list and describe the appropriate fields. +``_watermark`` + The watermarks for this zone. When the amount of free pages in a zone is below + the min watermark, boosting is ignored, an allocation may trigger direct + reclaim and direct compaction, it is also used to throttle direct reclaim. + When the amount of free pages in a zone is below the low watermark, kswapd is + woken up. When the amount of free pages in a zone is above the high watermark, + kswapd stops reclaiming (a zone is balanced) when the + ``NUMA_BALANCING_MEMORY_TIERING`` bit of ``sysctl_numa_balancing_mode`` is not + set. The promo watermark is used for memory tiering and NUMA balancing. When + the amount of free pages in a zone is above the promo watermark, kswapd stops + reclaiming when the ``NUMA_BALANCING_MEMORY_TIERING`` bit of + ``sysctl_numa_balancing_mode`` is set. The watermarks are set by + ``__setup_per_zone_wmarks()``. The min watermark is calculated according to + ``vm.min_free_kbytes`` sysctl. The other three watermarks are set according + to the distance between two watermarks. The distance itself is calculated + taking ``vm.watermark_scale_factor`` sysctl into account. + +``watermark_boost`` + The number of pages which are used to boost watermarks to increase reclaim + pressure to reduce the likelihood of future fallbacks and wake kswapd now + as the node may be balanced overall and kswapd will not wake naturally. + +``nr_reserved_highatomic`` + The number of pages which are reserved for high-order atomic allocations. + +``nr_free_highatomic`` + The number of free pages in reserved highatomic pageblocks + +``lowmem_reserve`` + The array of the amounts of the memory reserved in this zone for memory + allocations. For example, if the highest zone a memory allocation can + allocate memory from is ``ZONE_MOVABLE``, the amount of memory reserved in + this zone for this allocation is ``lowmem_reserve[ZONE_MOVABLE]`` when + attempting to allocate memory from this zone. This is a mechanism the page + allocator uses to prevent allocations which could use ``highmem`` from using + too much ``lowmem``. For some specialised workloads on ``highmem`` machines, + it is dangerous for the kernel to allow process memory to be allocated from + the ``lowmem`` zone. This is because that memory could then be pinned via the + ``mlock()`` system call, or by unavailability of swapspace. + ``vm.lowmem_reserve_ratio`` sysctl determines how aggressive the kernel is in + defending these lower zones. This array is recalculated by + ``setup_per_zone_lowmem_reserve()`` at runtime if ``vm.lowmem_reserve_ratio`` + sysctl changes. + +``node`` + The index of the node this zone belongs to. Available only when + ``CONFIG_NUMA`` is enabled because there is only one zone in a UMA system. + +``zone_pgdat`` + Pointer to the ``struct pglist_data`` of the node this zone belongs to. + +``per_cpu_pageset`` + Pointer to the Per-CPU Pagesets (PCP) allocated and initialized by + ``setup_zone_pageset()``. By handling most frequent allocations and frees + locally on each CPU, PCP improves performance and scalability on systems with + many cores. + +``pageset_high_min`` + Copied to the ``high_min`` of the Per-CPU Pagesets for faster access. + +``pageset_high_max`` + Copied to the ``high_max`` of the Per-CPU Pagesets for faster access. + +``pageset_batch`` + Copied to the ``batch`` of the Per-CPU Pagesets for faster access. The + ``batch``, ``high_min`` and ``high_max`` of the Per-CPU Pagesets are used to + calculate the number of elements the Per-CPU Pagesets obtain from the buddy + allocator under a single hold of the lock for efficiency. They are also used + to decide if the Per-CPU Pagesets return pages to the buddy allocator in page + free process. + +``pageblock_flags`` + The pointer to the flags for the pageblocks in the zone (see + ``include/linux/pageblock-flags.h`` for flags list). The memory is allocated + in ``setup_usemap()``. Each pageblock occupies ``NR_PAGEBLOCK_BITS`` bits. + Defined only when ``CONFIG_FLATMEM`` is enabled. The flags is stored in + ``mem_section`` when ``CONFIG_SPARSEMEM`` is enabled. + +``zone_start_pfn`` + The start pfn of the zone. It is initialized by + ``calculate_node_totalpages()``. + +``managed_pages`` + The present pages managed by the buddy system, which is calculated as: + ``managed_pages`` = ``present_pages`` - ``reserved_pages``, ``reserved_pages`` + includes pages allocated by the memblock allocator. It should be used by page + allocator and vm scanner to calculate all kinds of watermarks and thresholds. + It is accessed using ``atomic_long_xxx()`` functions. It is initialized in + ``free_area_init_core()`` and then is reinitialized when memblock allocator + frees pages into buddy system. + +``spanned_pages`` + The total pages spanned by the zone, including holes, which is calculated as: + ``spanned_pages`` = ``zone_end_pfn`` - ``zone_start_pfn``. It is initialized + by ``calculate_node_totalpages()``. + +``present_pages`` + The physical pages existing within the zone, which is calculated as: + ``present_pages`` = ``spanned_pages`` - ``absent_pages`` (pages in holes). It + may be used by memory hotplug or memory power management logic to figure out + unmanaged pages by checking (``present_pages`` - ``managed_pages``). Write + access to ``present_pages`` at runtime should be protected by + ``mem_hotplug_begin/done()``. Any reader who can't tolerant drift of + ``present_pages`` should use ``get_online_mems()`` to get a stable value. It + is initialized by ``calculate_node_totalpages()``. + +``present_early_pages`` + The present pages existing within the zone located on memory available since + early boot, excluding hotplugged memory. Defined only when + ``CONFIG_MEMORY_HOTPLUG`` is enabled and initialized by + ``calculate_node_totalpages()``. + +``cma_pages`` + The pages reserved for CMA use. These pages behave like ``ZONE_MOVABLE`` when + they are not used for CMA. Defined only when ``CONFIG_CMA`` is enabled. + +``name`` + The name of the zone. It is a pointer to the corresponding element of + the ``zone_names`` array. + +``nr_isolate_pageblock`` + Number of isolated pageblocks. It is used to solve incorrect freepage counting + problem due to racy retrieving migratetype of pageblock. Protected by + ``zone->lock``. Defined only when ``CONFIG_MEMORY_ISOLATION`` is enabled. + +``span_seqlock`` + The seqlock to protect ``zone_start_pfn`` and ``spanned_pages``. It is a + seqlock because it has to be read outside of ``zone->lock``, and it is done in + the main allocator path. However, the seqlock is written quite infrequently. + Defined only when ``CONFIG_MEMORY_HOTPLUG`` is enabled. + +``initialized`` + The flag indicating if the zone is initialized. Set by + ``init_currently_empty_zone()`` during boot. + +``free_area`` + The array of free areas, where each element corresponds to a specific order + which is a power of two. The buddy allocator uses this structure to manage + free memory efficiently. When allocating, it tries to find the smallest + sufficient block, if the smallest sufficient block is larger than the + requested size, it will be recursively split into the next smaller blocks + until the required size is reached. When a page is freed, it may be merged + with its buddy to form a larger block. It is initialized by + ``zone_init_free_lists()``. + +``unaccepted_pages`` + The list of pages to be accepted. All pages on the list are ``MAX_PAGE_ORDER``. + Defined only when ``CONFIG_UNACCEPTED_MEMORY`` is enabled. + +``flags`` + The zone flags. The least three bits are used and defined by + ``enum zone_flags``. ``ZONE_BOOSTED_WATERMARK`` (bit 0): zone recently boosted + watermarks. Cleared when kswapd is woken. ``ZONE_RECLAIM_ACTIVE`` (bit 1): + kswapd may be scanning the zone. ``ZONE_BELOW_HIGH`` (bit 2): zone is below + high watermark. + +``lock`` + The main lock that protects the internal data structures of the page allocator + specific to the zone, especially protects ``free_area``. + +``percpu_drift_mark`` + When free pages are below this point, additional steps are taken when reading + the number of free pages to avoid per-cpu counter drift allowing watermarks + to be breached. It is updated in ``refresh_zone_stat_thresholds()``. + +Compaction control +~~~~~~~~~~~~~~~~~~ + +``compact_cached_free_pfn`` + The PFN where compaction free scanner should start in the next scan. + +``compact_cached_migrate_pfn`` + The PFNs where compaction migration scanner should start in the next scan. + This array has two elements: the first one is used in ``MIGRATE_ASYNC`` mode, + and the other one is used in ``MIGRATE_SYNC`` mode. + +``compact_init_migrate_pfn`` + The initial migration PFN which is initialized to 0 at boot time, and to the + first pageblock with migratable pages in the zone after a full compaction + finishes. It is used to check if a scan is a whole zone scan or not. + +``compact_init_free_pfn`` + The initial free PFN which is initialized to 0 at boot time and to the last + pageblock with free ``MIGRATE_MOVABLE`` pages in the zone. It is used to check + if it is the start of a scan. + +``compact_considered`` + The number of compactions attempted since last failure. It is reset in + ``defer_compaction()`` when a compaction fails to result in a page allocation + success. It is increased by 1 in ``compaction_deferred()`` when a compaction + should be skipped. ``compaction_deferred()`` is called before + ``compact_zone()`` is called, ``compaction_defer_reset()`` is called when + ``compact_zone()`` returns ``COMPACT_SUCCESS``, ``defer_compaction()`` is + called when ``compact_zone()`` returns ``COMPACT_PARTIAL_SKIPPED`` or + ``COMPACT_COMPLETE``. + +``compact_defer_shift`` + The number of compactions skipped before trying again is + ``1<