From patchwork Sun Feb 23 18:53:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiwen Qi X-Patchwork-Id: 13987189 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 3DB98C021B2 for ; Sun, 23 Feb 2025 18:54:06 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7F5A6280001; Sun, 23 Feb 2025 13:54:05 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 7A54D6B0085; Sun, 23 Feb 2025 13:54:05 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 66C95280001; Sun, 23 Feb 2025 13:54:05 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 43BA76B0083 for ; Sun, 23 Feb 2025 13:54:05 -0500 (EST) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 56FBC12019E for ; Sun, 23 Feb 2025 18:54:04 +0000 (UTC) X-FDA: 83152109208.16.5E58D42 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) by imf07.hostedemail.com (Postfix) with ESMTP id 7858040007 for ; Sun, 23 Feb 2025 18:54:02 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=WWmM9bBo; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf07.hostedemail.com: domain of jiwen7.qi@gmail.com designates 209.85.128.46 as permitted sender) smtp.mailfrom=jiwen7.qi@gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1740336842; a=rsa-sha256; cv=none; b=hQSaIKZqlcn3krPV5TKmXiUCq6zWFqA6ssxMvALIpFjzKM22UddEWqZDVr+5+weDDNw4yK WQu5KIaeIM+uPJvwwssKBvZvMkkF3m51pygeV9GTsdTY1tlfosrot4UI151IVz6bMKlLct yMwgpnq2IclGOrzxvxd1+o2rT1GOCkA= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=WWmM9bBo; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf07.hostedemail.com: domain of jiwen7.qi@gmail.com designates 209.85.128.46 as permitted sender) smtp.mailfrom=jiwen7.qi@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1740336842; 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:references:dkim-signature; bh=gYta+DLZiUeLkHIWrvvwJBHUyubLAgb6F/kyuT3eWew=; b=2aiBcTTjC1aiz+Jo/HNH34DEDrZXpZtx56Wet+gwqJZuO3fUa5rEku2u9sauq5e6kIdwCc aEQ5mwbH53TErs9xua3Lva5qyh0PtE0Dxx2Cc08+NJeaJe34dzZkOF9+aSSkQ6OJGbg7ps ixjJe2xOwEmwIDl/67jsvLoQxU1RNTc= Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-439a4fc2d65so34674205e9.3 for ; Sun, 23 Feb 2025 10:54:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1740336841; x=1740941641; darn=kvack.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=gYta+DLZiUeLkHIWrvvwJBHUyubLAgb6F/kyuT3eWew=; b=WWmM9bBoGbc/jEpAAyQ5IEkZexvpjrSN5ryi0O72WZaahG0S1uRfk2958MyuUy5s+N lcVpc8q5dXb5zW2L4xXVuInzIsF+SNIgNv5optcy/f/m76hJPRvW4jv4Y5fadYRpM8C7 Njo/maO7FU5dk+e0Nc8zs4CLEOcvsYBPyIBvRgMz3PK5A4A4UEJYSNjvTW61zc5zdr+Q elQJwyNSYWK68+7BgavhHQCx+D1h1OCJhjc/prbUkCSDuSwKcMQWDVJHzluIpjoQ51Mp cPjkW1ElXXodjlvwLXE9AOGr3E3x7Au7ujBc3MQWDoODYc72RDuiRGa+wNv7O62a6TqA OAJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1740336841; x=1740941641; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=gYta+DLZiUeLkHIWrvvwJBHUyubLAgb6F/kyuT3eWew=; b=CE9b1qRG95CzWqdpU+LxE5j0OHO1uqUfO++QhNY4QogwDrcoQ4MJ9L9WXe8rWqJcv9 OFqLIv9WQKY2Jh5o98ppWt/d5N8sXn10uhXqZJJ03lvg66gjfif95Ibo7EUi5XdkyWqe 2ulHnw9VLBh8IbqqipPidwiCeqELpTnh0eSgLVH30nXjdi/y13WsbF4zH3+Un7JL91jZ 0uhukvBiE5rQh6yEa/S5AAPAAqET8m6qcTzYoNj91QBJeaFec78teM9WyL/ly38ISkDW taL+KQxXj47Az3MDGICPp5tIvX3mNupEYx2HEJ7MgqdTccOUzyJh2F/0XJe+8CMrRF6V 8Exg== X-Forwarded-Encrypted: i=1; AJvYcCUImZZaVf6y/03xX7i1elnYFqFsxDLc9lP2fdR2Z97VmbITH6LH5djq1dwHpadbZzI04DtZQNVxdA==@kvack.org X-Gm-Message-State: AOJu0YyqpVfpiVhZHZAs3Rfvkm0bOeWKgDI+eOm/Qcf1A1zGlVhzltoX WhO2ePmFo9NikoIyN7bywUez6xhYvNtrVqNC6vYLgOCUQOSwfzmN X-Gm-Gg: ASbGncvHHOulT3PyXjKZ5mAVYkKJouvtUm1u4deEghggZe7HKowP8Tmnn5HKhr001Ry kpe+1yf++Y5V0s8RFA/C5UcLdsraCIt+932V9Bv4c9Y2O+/jea6CxZZNJMgO8ZM5lyR6RQsG8Xs ks/PVNYDDPZIJpESUr1pBOqSdDAw9y+yy8gmwKAqQhG6+efE82apqiGRF9lU5Lr2+awbISY1o1Y cEPufIcmw3hL6fNIsIFPyz0ig3o/WFC1ltR6NFbV5GUpqbTTTzu7banAtXUN97blkeYmWfF3QZk uUYnBS5jKnRDxWS1ze6SiqEWrpfjMbWZWPbHQcNO47l5D3BYY6TpwwZQSs5od1IQStmbs8RuU7c c X-Google-Smtp-Source: AGHT+IGKQH5RhyYsJgGEfcxrvNkfynXTyBuxAPgyuslN1rcIBJJcu8B/LN9mMUuyk8Cp9+OpaoF3Zw== X-Received: by 2002:a05:600c:524a:b0:439:86c4:a8ec with SMTP id 5b1f17b1804b1-439ae1f1147mr95843765e9.15.1740336840341; Sun, 23 Feb 2025 10:54:00 -0800 (PST) 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-439b02f3e26sm85098165e9.23.2025.02.23.10.53.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Feb 2025 10:53:59 -0800 (PST) From: Jiwen Qi To: akpm@linux-foundation.org Cc: corbet@lwn.net, linux-mm@kvack.org, linux-doc@vger.kernel.org Subject: [PATCH] docs/mm: Physical Memory: Populate the "Zones" section Date: Sun, 23 Feb 2025 18:53:59 +0000 Message-Id: <20250223185359.338647-1-jiwen7.qi@gmail.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Rspamd-Server: rspam02 X-Rspamd-Queue-Id: 7858040007 X-Stat-Signature: qhzmtywz8hfsioo6rhr9jmzha6yfhmgh X-Rspam-User: X-HE-Tag: 1740336842-457824 X-HE-Meta: U2FsdGVkX1/Vkl3nkbQ9Zh94GKyFg41ePGXftz2YuO/RxRPdQHiRh+Tnhnnu5O1R5MGg0WVxtKnPtVYgfb2AuNFwrtZjPRgiRPgmoIYw6pyLDxbSvyPD8BtghwqBZ3KL/GktkAiMIBFE0UCutD6ckJu3kBLZ3ubZScdhxScN0vBAk35AkcEQJqFWn/Nz9Tr42G6jivs552maXm9mwCK2CQb1yc2WHRrDGARq4BE5QBxoHGNugcgNdeoLiyMioCvAMZl+ATXwvLhNXYI0HO6HPFKZRrC9+MZSH/MD0o53qIoq6pdnJYX5EI/k/ZWkbdOLeGaxSez1w5ioM05dolIURGADsJIw9M/IItUS+032uLMi6RJgIOojMkbQfuHVzFCjDGbOIiRWujBxPNJLf/WBzu9vZMlOQAjK1p9R9PwU0XEBzRrfl5sS664tSrBF7J1A/uLsJOzh/hMsksRBg7f6g28+1BaOpWdLUDVZS/vfkQmrsLRg9UYuZJ10VTc1oIqzefP4K8/BV3aVrwScG+qY/SEw8tUTpcHlX1LLlF8VJH1stW+gefIgbxRTAfKHb3YwXejXnoiGaMpHkW7Kke4G+PG68JUVP4CwaWsRBq9AFHY57cHGejopyNL/lJppSvCgSVgxI56Y0wOfNjGL3XOOCYXc63F62rGFPYnw5LL1kMEPw5cOQESxWfQC8pl2edlrsHAl9Oh/fuWWzpszGuaFTyN+9htTHBqxhiHAtptkmczlHfXuJddUanwScPdu8jpMSP+B22N3vjXF0CaTBns409c4/4FQSjCkDNAO2sfrZMxT9Q081b6Ep1VGLT/9YHwmrzqHtr7NQBNnTZj+bMcHlO6Mkpu3INQe4nuVWhZXAyXTTjlxEjkqIvlOEmobN6B0jyhGK6QW13cwqxP2HWrQ6+J6qeronWmTKqoRkh7DwveR5pDERmHdMqTTC+OTy+I2d9jstJqb3RiAIvN/pFR JnVJfSyw 4SxDXRNpKGoyLDLph9iBz52mHZ/I5SVCrbvW1Lq1BpLfSwzNKnRklO/wF6qtjrueNRpd6CMNWaM1X4yJPjhFujfcmY3EB+1g45+QjIoM0K3ut7yMA0Wj9uO0BTEuAtW2eA17YET5HVJ74Ex8oTc4jo97iwY6hOga71jAqolyax5KyjS/QM2PU+DISKvrtNdTWWTFbiwY1vfU2p9BWTq50Gd+k1KObnKoWxQVVDiU6JOlG0jyG1C02DlcB5Zj89Hu8bqeyumNg5ibxpv5UCbRJ/2aG72pnWkJIxJ0Twp1OuOrynmS2e5CoXBteOphSxPq1K9bJYTB/qeCUX3pJtkR/Cm1i7aWQkh/D6VB4Hbq9d9PhlAnx7108hD4uYVIQldptE8zlUni/rfBUszfZtBwWdTanDLIH7SStRaMFzkbVAdkNqO8BlZnKSpNxEOtvmc7QovPfo1tMoiXy1vM= 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 --- Documentation/mm/physical_memory.rst | 259 ++++++++++++++++++++++++++- 1 file changed, 257 insertions(+), 2 deletions(-) base-commit: 0ad2507d5d93f39619fc42372c347d6006b64319 diff --git a/Documentation/mm/physical_memory.rst b/Documentation/mm/physical_memory.rst index 71fd4a6acf42..227997694851 100644 --- a/Documentation/mm/physical_memory.rst +++ b/Documentation/mm/physical_memory.rst @@ -338,10 +338,265 @@ Statistics Zones ===== +As we have mentioned, each zone in memory is described by a ``struct zone`` +which is an element of the ``node_zones`` field of the node it belongs to. A +zone represents a range of physical memory. A zone may have holes. The +``spanned_pages`` field represents the total pages spanned by the zone, +the ``present_pages`` field represents the physical pages existing within the +zone and the managed_page field represents the pages managed by the buddy system. + +Linux uses the GFP flags, see ``include/linux/gfp_types.h``, specified by +a memory allocation to determine the highest zone in a node from which +the memory allocation can allocate memory. Linux first allocates memory from +that zone, if Linux 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 Linux +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 is pointed by the ``per_cpu_pageset`` filed. +The free areas is pointed by the ``free_area`` field. The Per-CPU Pagesets are +a vital mechanism in the Linux 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 Linux 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. Free areas in +a zone are represented by an array of ``free_area``, where each element +corresponds to a specific order which is a power of two." + +Architecture specific code calls free_area_init() to initializes zones. + +Zone structure +-------------- -.. admonition:: Stub +The zones structure ``struct zone`` is declared in ``include/linux/mmzone.h``. +Here we briefly describe fields of this structure: - This section is incomplete. Please list and describe the appropriate fields. +General +~~~~~~~ + +``_watermark`` + The watermarks for this zone. The min watermark is the point where boosting is + ignored and an allocation may trigger direct reclaim and direct compaction. + It is also used to throttle direct reclaim. The low watermark is the point + where kswapd is woken up. The high watermark is the point where 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. It is the point where 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 is caculated according + to ``vm.watermark_scale_factor`` sysctl. + +``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. The reason is that we don't know + if the memory that we're going to allocate will be freeable or/and it will be + released eventually, so to avoid totally wasting several GB of ram we must + reserve some of the lower zone memory (otherwise we risk to run OOM on the + lower zones despite there being tons of freeable ram on the higher 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 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, the Per-CPU Pagesets improve 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 system. See + ``include/linux/pageblock-flags.h``. 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. But, it 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`` + Free areas of different sizes. 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, + the other 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<