All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ryan Roberts <ryan.roberts@arm.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@redhat.com>,
	Matthew Wilcox <willy@infradead.org>,
	Huang Ying <ying.huang@intel.com>, Gao Xiang <xiang@kernel.org>,
	Yu Zhao <yuzhao@google.com>, Yang Shi <shy828301@gmail.com>,
	Michal Hocko <mhocko@suse.com>,
	Kefeng Wang <wangkefeng.wang@huawei.com>,
	Barry Song <21cnbao@gmail.com>, Chris Li <chrisl@kernel.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: [PATCH v4 0/6] Swap-out mTHP without splitting
Date: Mon, 11 Mar 2024 15:00:52 +0000	[thread overview]
Message-ID: <20240311150058.1122862-1-ryan.roberts@arm.com> (raw)

Hi All,

This series adds support for swapping out multi-size THP (mTHP) without needing
to first split the large folio via split_huge_page_to_list_to_order(). It
closely follows the approach already used to swap-out PMD-sized THP.

There are a couple of reasons for swapping out mTHP without splitting:

  - Performance: It is expensive to split a large folio and under extreme memory
    pressure some workloads regressed performance when using 64K mTHP vs 4K
    small folios because of this extra cost in the swap-out path. This series
    not only eliminates the regression but makes it faster to swap out 64K mTHP
    vs 4K small folios.

  - Memory fragmentation avoidance: If we can avoid splitting a large folio
    memory is less likely to become fragmented, making it easier to re-allocate
    a large folio in future.

  - Performance: Enables a separate series [4] to swap-in whole mTHPs, which
    means we won't lose the TLB-efficiency benefits of mTHP once the memory has
    been through a swap cycle.

I've done what I thought was the smallest change possible, and as a result, this
approach is only employed when the swap is backed by a non-rotating block device
(just as PMD-sized THP is supported today). Discussion against the RFC concluded
that this is sufficient.


Performance Testing
===================

I've run some swap performance tests on Ampere Altra VM (arm64) with 8 CPUs. The
VM is set up with a 35G block ram device as the swap device and the test is run
from inside a memcg limited to 40G memory. I've then run `usemem` from
vm-scalability with 70 processes, each allocating and writing 1G of memory. I've
repeated everything 6 times and taken the mean performance improvement relative
to 4K page baseline:

| alloc size |            baseline |       + this series |
|            |  v6.6-rc4+anonfolio |                     |
|:-----------|--------------------:|--------------------:|
| 4K Page    |                0.0% |                1.4% |
| 64K THP    |              -14.6% |               44.2% |
| 2M THP     |               87.4% |               97.7% |

So with this change, the 64K swap performance goes from a 15% regression to a
44% improvement. 4K and 2M swap improves slightly too.

This test also acts as a good stress test for swap and, more generally mm. A
couple of existing bugs were found as a result [5] [6].


---
The series applies against mm-unstable (d7182786dd0a). Although I've
additionally been running with a couple of extra fixes to avoid the issues at
[6].


Changes since v3 [3]
====================

 - Renamed SWAP_NEXT_NULL -> SWAP_NEXT_INVALID (per Huang, Ying)
 - Simplified max offset calculation (per Huang, Ying)
 - Reinstated struct percpu_cluster to contain per-cluster, per-order `next`
   offset (per Huang, Ying)
 - Removed swap_alloc_large() and merged its functionality into
   scan_swap_map_slots() (per Huang, Ying)
 - Avoid extra cost of folio ref and lock due to removal of CLUSTER_FLAG_HUGE
   by freeing swap entries in batches (see patch 2) (per DavidH)
 - vmscan splits folio if its partially mapped (per Barry Song, DavidH)
 - Avoid splitting in MADV_PAGEOUT path (per Barry Song)
 - Dropped "mm: swap: Simplify ssd behavior when scanner steals entry" patch
   since it's not actually a problem for THP as I first thought.


Changes since v2 [2]
====================

 - Reuse scan_swap_map_try_ssd_cluster() between order-0 and order > 0
   allocation. This required some refactoring to make everything work nicely
   (new patches 2 and 3).
 - Fix bug where nr_swap_pages would say there are pages available but the
   scanner would not be able to allocate them because they were reserved for the
   per-cpu allocator. We now allow stealing of order-0 entries from the high
   order per-cpu clusters (in addition to exisiting stealing from order-0
   per-cpu clusters).


Changes since v1 [1]
====================

 - patch 1:
    - Use cluster_set_count() instead of cluster_set_count_flag() in
      swap_alloc_cluster() since we no longer have any flag to set. I was unable
      to kill cluster_set_count_flag() as proposed against v1 as other call
      sites depend explicitly setting flags to 0.
 - patch 2:
    - Moved large_next[] array into percpu_cluster to make it per-cpu
      (recommended by Huang, Ying).
    - large_next[] array is dynamically allocated because PMD_ORDER is not
      compile-time constant for powerpc (fixes build error).


[1] https://lore.kernel.org/linux-mm/20231010142111.3997780-1-ryan.roberts@arm.com/
[2] https://lore.kernel.org/linux-mm/20231017161302.2518826-1-ryan.roberts@arm.com/
[3] https://lore.kernel.org/linux-mm/20231025144546.577640-1-ryan.roberts@arm.com/
[4] https://lore.kernel.org/linux-mm/20240304081348.197341-1-21cnbao@gmail.com/
[5] https://lore.kernel.org/linux-mm/20240311084426.447164-1-ying.huang@intel.com/
[6] https://lore.kernel.org/linux-mm/79dad067-1d26-4867-8eb1-941277b9a77b@arm.com/

Thanks,
Ryan


Ryan Roberts (6):
  mm: swap: Remove CLUSTER_FLAG_HUGE from swap_cluster_info:flags
  mm: swap: free_swap_and_cache_nr() as batched free_swap_and_cache()
  mm: swap: Simplify struct percpu_cluster
  mm: swap: Allow storage of all mTHP orders
  mm: vmscan: Avoid split during shrink_folio_list()
  mm: madvise: Avoid split during MADV_PAGEOUT and MADV_COLD

 include/linux/pgtable.h |  28 ++++
 include/linux/swap.h    |  33 +++--
 mm/huge_memory.c        |   3 -
 mm/internal.h           |  48 +++++++
 mm/madvise.c            | 101 ++++++++------
 mm/memory.c             |  13 +-
 mm/swapfile.c           | 298 ++++++++++++++++++++++------------------
 mm/vmscan.c             |   9 +-
 8 files changed, 332 insertions(+), 201 deletions(-)

--
2.25.1


             reply	other threads:[~2024-03-11 15:01 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-11 15:00 Ryan Roberts [this message]
2024-03-11 15:00 ` [PATCH v4 1/6] mm: swap: Remove CLUSTER_FLAG_HUGE from swap_cluster_info:flags Ryan Roberts
2024-03-11 15:00 ` [PATCH v4 2/6] mm: swap: free_swap_and_cache_nr() as batched free_swap_and_cache() Ryan Roberts
2024-03-20 11:10   ` Ryan Roberts
2024-03-20 14:13     ` David Hildenbrand
2024-03-20 14:21       ` Ryan Roberts
2024-03-11 15:00 ` [PATCH v4 3/6] mm: swap: Simplify struct percpu_cluster Ryan Roberts
2024-03-12  7:52   ` Huang, Ying
2024-03-12  8:51     ` Ryan Roberts
2024-03-13  1:34       ` Huang, Ying
2024-03-11 15:00 ` [PATCH v4 4/6] mm: swap: Allow storage of all mTHP orders Ryan Roberts
2024-03-12  7:51   ` Huang, Ying
2024-03-12  9:40     ` Ryan Roberts
2024-03-13  1:33       ` Huang, Ying
2024-03-20 12:22     ` Ryan Roberts
2024-03-21  4:39       ` Huang, Ying
2024-03-21 12:21         ` Ryan Roberts
2024-03-22  2:38           ` Can you help us on memory barrier usage? (was Re: [PATCH v4 4/6] mm: swap: Allow storage of all mTHP orders) Huang, Ying
2024-03-22  9:23             ` Ryan Roberts
2024-03-25  3:20               ` Huang, Ying
2024-03-22 13:19             ` Chris Li
2024-03-23  2:11             ` Akira Yokosawa
2024-03-25  0:01               ` Paul E. McKenney
2024-03-25  3:16                 ` Huang, Ying
2024-03-26 17:08                   ` Ryan Roberts
2024-03-25  3:00               ` Huang, Ying
2024-03-22  2:39           ` [PATCH v4 4/6] mm: swap: Allow storage of all mTHP orders Huang, Ying
2024-03-22  9:39             ` Ryan Roberts
2024-03-11 15:00 ` [PATCH v4 5/6] mm: vmscan: Avoid split during shrink_folio_list() Ryan Roberts
2024-03-11 22:30   ` Barry Song
2024-03-12  8:12     ` Ryan Roberts
2024-03-12  8:40       ` Barry Song
2024-03-15 10:43   ` David Hildenbrand
2024-03-15 10:49     ` Ryan Roberts
2024-03-15 11:12       ` David Hildenbrand
2024-03-15 11:38         ` Ryan Roberts
2024-03-18  2:16           ` Huang, Ying
2024-03-18 10:00             ` Yin, Fengwei
2024-03-18 10:05               ` David Hildenbrand
2024-03-18 15:35                 ` Ryan Roberts
2024-03-18 15:36                   ` Ryan Roberts
2024-03-19  2:20                   ` Yin Fengwei
2024-03-19 14:40                     ` Ryan Roberts
2024-03-19  2:31                 ` Yin Fengwei
2024-03-11 15:00 ` [PATCH v4 6/6] mm: madvise: Avoid split during MADV_PAGEOUT and MADV_COLD Ryan Roberts
2024-03-13  7:19   ` Barry Song
2024-03-13  9:03     ` Ryan Roberts
2024-03-13  9:16       ` Barry Song
2024-03-13  9:36         ` Ryan Roberts
2024-03-13 10:37           ` Barry Song
2024-03-13 11:08             ` Ryan Roberts
2024-03-13 11:37               ` Barry Song
2024-03-13 12:02                 ` Ryan Roberts
2024-03-13  9:19       ` Lance Yang
2024-03-13 14:02       ` Lance Yang
2024-03-20 13:49         ` Ryan Roberts
2024-03-20 14:35           ` Lance Yang
2024-03-20 17:38             ` Ryan Roberts
2024-03-21  1:38               ` Lance Yang
2024-03-21 13:38                 ` Ryan Roberts
2024-03-21 14:55                   ` Lance Yang
2024-03-21 15:24                     ` Ryan Roberts
2024-03-22  0:56                       ` Lance Yang
2024-03-15 10:35   ` David Hildenbrand
2024-03-15 10:55     ` Ryan Roberts
2024-03-15 11:13       ` David Hildenbrand
2024-03-20 13:57     ` Ryan Roberts
2024-03-20 14:09       ` David Hildenbrand
2024-03-12  8:01 ` [PATCH v4 0/6] Swap-out mTHP without splitting Huang, Ying
2024-03-12  8:49   ` Ryan Roberts
2024-03-12 13:56     ` Ryan Roberts
2024-03-13  1:15       ` Huang, Ying
2024-03-13  8:50         ` Ryan Roberts
2024-03-12  8:45 ` Ryan Roberts

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240311150058.1122862-1-ryan.roberts@arm.com \
    --to=ryan.roberts@arm.com \
    --cc=21cnbao@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=chrisl@kernel.org \
    --cc=david@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@suse.com \
    --cc=shy828301@gmail.com \
    --cc=wangkefeng.wang@huawei.com \
    --cc=willy@infradead.org \
    --cc=xiang@kernel.org \
    --cc=ying.huang@intel.com \
    --cc=yuzhao@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.