Commit 09350a7c authored by Liu Shixin's avatar Liu Shixin
Browse files

mm/huge_memory: mTHP user controls to pagecache large folio

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAKLTF



--------------------------------

Add mTHP controls to sysfs to allow user space to disable large folio.
For now, the control can be set to either `always` or `never` to enable
or disable.

By default, large folio is enabled if it is supported by filesystem.

Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 63fb4139
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -232,6 +232,12 @@ it back by writing 0::
        echo 0 >/sys/kernel/mm/transparent_hugepage/pcp_allow_high_order
        echo 4 >/sys/kernel/mm/transparent_hugepage/pcp_allow_high_order

The kernel could enable or disable file-backed hugepages, which has no
effect on existed pagecache::

	echo always >/sys/kernel/mm/transparent_hugepage/file_enabled
	echo never >/sys/kernel/mm/transparent_hugepage/file_enabled

khugepaged will be automatically started when PMD-sized THP is enabled
(either of the per-size anon control or the top-level control are set
to "always" or "madvise"), and it'll be automatically shutdown when
+7 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ enum transparent_hugepage_flag {
	TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG,
	TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG,
	TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG,
	TRANSPARENT_HUGEPAGE_FILE_MTHP_FLAG,
	TRANSPARENT_HUGEPAGE_FILE_EXEC_THP_FLAG,
	TRANSPARENT_HUGEPAGE_FILE_EXEC_MTHP_FLAG,
	TRANSPARENT_HUGEPAGE_FILE_MAPPING_ALIGN_FLAG,
@@ -308,6 +309,10 @@ static inline void count_mthp_stat(int order, enum mthp_stat_item item)
	(transparent_hugepage_flags &					\
	 (1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG))

#define file_mthp_enabled()					\
	(transparent_hugepage_flags &				\
	 (1<<TRANSPARENT_HUGEPAGE_FILE_MTHP_FLAG))

#define thp_anon_mapping_pmd_align()				\
	(transparent_hugepage_flags &				\
	 (1<<TRANSPARENT_HUGEPAGE_ANON_MAPPING_PMD_ALIGN_FLAG))
@@ -465,6 +470,8 @@ static inline void folio_prep_large_rmappable(struct folio *folio) {}

#define transparent_hugepage_flags 0UL

#define file_mthp_enabled()	false

#define thp_anon_mapping_pmd_align()	NULL

#define thp_get_unmapped_area	NULL
+2 −0
Original line number Diff line number Diff line
@@ -1932,6 +1932,8 @@ struct folio *__filemap_get_folio(struct address_space *mapping, pgoff_t index,

		if (!mapping_large_folio_support(mapping))
			order = 0;
		if (order && !file_mthp_enabled())
			order = 0;
		if (order && mm_in_dynamic_pool(current->mm))
			order = 0;
		if (order > MAX_PAGECACHE_ORDER)
+37 −1
Original line number Diff line number Diff line
@@ -65,7 +65,8 @@ unsigned long transparent_hugepage_flags __read_mostly =
#endif
	(1<<TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG)|
	(1<<TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG)|
	(1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG);
	(1<<TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG)|
	(1<<TRANSPARENT_HUGEPAGE_FILE_MTHP_FLAG);

static struct shrinker deferred_split_shrinker;

@@ -489,6 +490,40 @@ static void thp_flag_set(enum transparent_hugepage_flag flag, bool enable)
		clear_bit(flag, &transparent_hugepage_flags);
}

static ssize_t file_enabled_show(struct kobject *kobj,
				 struct kobj_attribute *attr, char *buf)
{
	const char *output;

	if (test_bit(TRANSPARENT_HUGEPAGE_FILE_MTHP_FLAG,
		     &transparent_hugepage_flags))
		output = "[always] never";
	else
		output = "always [never]";

	return sysfs_emit(buf, "%s\n", output);
}

static ssize_t file_enabled_store(struct kobject *kobj,
				  struct kobj_attribute *attr,
				  const char *buf, size_t count)
{
	ssize_t ret = count;

	if (sysfs_streq(buf, "always")) {
		set_bit(TRANSPARENT_HUGEPAGE_FILE_MTHP_FLAG,
			&transparent_hugepage_flags);
	} else if (sysfs_streq(buf, "never")) {
		clear_bit(TRANSPARENT_HUGEPAGE_FILE_MTHP_FLAG,
			  &transparent_hugepage_flags);
	} else
		ret = -EINVAL;

	return ret;
}

static struct kobj_attribute file_enabled_attr = __ATTR_RW(file_enabled);

static ssize_t thp_exec_enabled_show(struct kobject *kobj,
				     struct kobj_attribute *attr, char *buf)
{
@@ -592,6 +627,7 @@ static struct attribute *hugepage_attr[] = {
#ifdef CONFIG_SHMEM
	&shmem_enabled_attr.attr,
#endif
	&file_enabled_attr.attr,
	&thp_exec_enabled_attr.attr,
	&thp_mapping_align_attr.attr,
	NULL,
+2 −0
Original line number Diff line number Diff line
@@ -504,6 +504,8 @@ void page_cache_ra_order(struct readahead_control *ractl,

	if (!mapping_large_folio_support(mapping) || ra->size < 4)
		goto fallback;
	if (!file_mthp_enabled())
		goto fallback;
	if (mm_in_dynamic_pool(current->mm))
		goto fallback;