BACKPORT: mm: add sysfs entry to disable splitting underused THPs

If disabled, THPs faulted in or collapsed will not be added to
_deferred_list, and therefore won't be considered for splitting under
memory pressure if underused.

Link: https://lkml.kernel.org/r/20240830100438.3623486-7-usamaarif642@gmail.com
Change-Id: I1ec6aa4a7da1202272518962a1e436aa561667c5
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
Cc: Alexander Zhu <alexlzhu@fb.com>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kairui Song <ryncsn@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nico Pache <npache@redhat.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Shuang Zhai <zhais@google.com>
Cc: Shuang Zhai <szhai2@cs.rochester.edu>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
(cherry picked from commit 81d3ff3c6f76306b22138d69e980634f53bf17fa)
[ Fix trivial conflicts in mm/huge_memory.c and transhuge.rst
    - Kalesh Singh ]
Bug: 419599659
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
This commit is contained in:
Usama Arif
2024-08-30 11:03:40 +01:00
committed by Kalesh Singh
parent 40ffd525e5
commit dd46964f3e
2 changed files with 36 additions and 0 deletions

View File

@@ -202,6 +202,16 @@ PMD-mappable transparent hugepage::
cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
All THPs at fault and collapse time will be added to _deferred_list,
and will therefore be split under memory presure if they are considered
"underused". A THP is underused if the number of zero-filled pages in
the THP is above max_ptes_none (see below). It is possible to disable
this behaviour by writing 0 to shrink_underused, and enable it by writing
1 to it::
echo 0 > /sys/kernel/mm/transparent_hugepage/shrink_underused
echo 1 > /sys/kernel/mm/transparent_hugepage/shrink_underused
khugepaged will be automatically started when one or more hugepage khugepaged will be automatically started when one or more hugepage
sizes are enabled (either by directly setting "always" or "madvise", sizes are enabled (either by directly setting "always" or "madvise",
or by setting "inherit" while the top-level enabled is set to "always" or by setting "inherit" while the top-level enabled is set to "always"

View File

@@ -70,6 +70,7 @@ unsigned long transparent_hugepage_flags __read_mostly =
(1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG); (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
static struct shrinker deferred_split_shrinker; static struct shrinker deferred_split_shrinker;
static bool split_underused_thp = true;
static atomic_t huge_zero_refcount; static atomic_t huge_zero_refcount;
struct page *huge_zero_page __read_mostly; struct page *huge_zero_page __read_mostly;
@@ -423,6 +424,27 @@ static ssize_t hpage_pmd_size_show(struct kobject *kobj,
static struct kobj_attribute hpage_pmd_size_attr = static struct kobj_attribute hpage_pmd_size_attr =
__ATTR_RO(hpage_pmd_size); __ATTR_RO(hpage_pmd_size);
static ssize_t split_underused_thp_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sysfs_emit(buf, "%d\n", split_underused_thp);
}
static ssize_t split_underused_thp_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
int err = kstrtobool(buf, &split_underused_thp);
if (err < 0)
return err;
return count;
}
static struct kobj_attribute split_underused_thp_attr = __ATTR(
shrink_underused, 0644, split_underused_thp_show, split_underused_thp_store);
static struct attribute *hugepage_attr[] = { static struct attribute *hugepage_attr[] = {
&enabled_attr.attr, &enabled_attr.attr,
&defrag_attr.attr, &defrag_attr.attr,
@@ -431,6 +453,7 @@ static struct attribute *hugepage_attr[] = {
#ifdef CONFIG_SHMEM #ifdef CONFIG_SHMEM
&shmem_enabled_attr.attr, &shmem_enabled_attr.attr,
#endif #endif
&split_underused_thp_attr.attr,
NULL, NULL,
}; };
@@ -3603,6 +3626,9 @@ void deferred_split_folio(struct folio *folio, bool partially_mapped)
if (folio_order(folio) <= 1) if (folio_order(folio) <= 1)
return; return;
if (!partially_mapped && !split_underused_thp)
return;
/* /*
* The try_to_unmap() in page reclaim path might reach here too, * The try_to_unmap() in page reclaim path might reach here too,
* this may cause a race condition to corrupt deferred split queue. * this may cause a race condition to corrupt deferred split queue.