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:
@@ -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"
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user