Skip to contentSkip to conversation

mm/khugepaged: cap min_free_kbytes recommendation at 1 GiB

PATCH In review Nimrod Oren 6 participants 11 messages Aug 31

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 mm/khugepaged: cap min_free_kbytes recommendation at 1 GiB

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

---
v2:
* Use a named constant for the cap.
* Drop explicit linux/sizes.h include.
* Update min_free_kbytes documentation.

v1:
* Cap the final recommendation at 1 GiB as suggested by Lorenzo.
https://lore.kernel.org/r/[email protected]/

RFC v1:
https://lore.kernel.org/r/[email protected]/

---
 Documentation/admin-guide/sysctl/vm.rst | 8 ++++++++
 mm/khugepaged.c                         | 7 ++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)
Documentation/admin-guide/sysctl/vm.rst +8 -0
index 5b318d17aa4b..c0c925e6f504 100644
@@ -539,6 +539,14 @@ watermark[WMARK_MIN] value for each lowmem zone in the system.
 Each lowmem zone gets a number of reserved free pages based
 proportionally on its size.
 
+When Transparent Hugepage (THP) support is enabled through global or
+per-size controls, the kernel may raise this value automatically to
+help keep pageblocks free and reduce fragmentation for THP allocations.
+The automatic recommendation cannot exceed 5% of low memory or 1 GiB,
+whichever is lower.  This limit applies only to the automatic
+recommendation and does not constrain a higher value written by
+userspace.
+
 Some minimal amount of memory is needed to satisfy PF_MEMALLOC
 allocations; if you set this to lower than 1024KB, your system will
 become subtly broken, and prone to deadlock under high loads.
mm/khugepaged.c +6 -1
index f49a6710933b..a8fc061d2488 100644
@@ -101,6 +101,7 @@ static DEFINE_READ_MOSTLY_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
 
 static struct kmem_cache *mm_slot_cache __ro_after_init;
 
+#define THP_MIN_FREE_MAX_PAGES		(SZ_1G / PAGE_SIZE)
 #define KHUGEPAGED_MIN_MTHP_ORDER	2
 
 struct collapse_control {
@@ -3120,9 +3121,13 @@ void set_recommended_min_free_kbytes(void)
 	recommended_min += pageblock_nr_pages * nr_zones *
 			   MIGRATE_PCPTYPES * MIGRATE_PCPTYPES;
 
-	/* don't ever allow to reserve more than 5% of the lowmem */
+	/*
+	 * Don't allow the THP recommendation to exceed 5% of lowmem or an
+	 * absolute cap, whichever is smaller.
+	 */
 	recommended_min = min(recommended_min,
 			      (unsigned long) nr_free_buffer_pages() / 20);
+	recommended_min = min(recommended_min, THP_MIN_FREE_MAX_PAGES);
 	recommended_min <<= (PAGE_SHIFT-10);
 
 	if (recommended_min > min_free_kbytes) {
Signature · 1 line
2.45.0
#1 lore raw
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

I am not against an upper limit for min_free_kbytes, but I think the root cause of the problem you see is the size of the page block.

We at Meta switched to 2M page blocks on 64k ARMs recently, targeting 2M mTHPs. A 512M pageblock is not practical.

Signature · 1 line
  Kiryl Shutsemau / Kirill A. Shutemov
#2 lore raw
Quoted 23 lines · Kiryl Shutsemau
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

Quoted 5 lines

I am not against an upper limit for min_free_kbytes, but I think the root cause of the problem you see is the size of the page block.

We at Meta switched to 2M page blocks on 64k ARMs recently, targeting 2M mTHPs. A 512M pageblock is not practical.

I mean we do keep looping around on these things as 64 KiB page size is fundamentally a big problem for the pageblock model :)

I don't love the idea of just making page blocks arbitrary smaller for higher page table size, because hey the intent is to get a PMD-sized thing.

So really I think to do it 'properly' you'd need to rework how that whole thing functions.

For me the approach here is a practical trade-off - if the intent is to cap at a sensible value, then just cap at a sensible value.

Quoted 3 lines

--
Kiryl Shutsemau / Kirill A. Shutemov

--
Cheers, Lorenzo

reviewer Acked-by on v2 1/1
#3 lore raw
In reply to Nimrod Oren
Quoted 17 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Quoted 8 lines

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

I do think this is a practical way of preventing runaway increase of reserves.

In the long run we need to rework the pageblock model I think, but this is a reasonable way forward in the short-medium term.

Obviously I defer to David and the community on this if they think this is horrible, then let's not.

But I do worry that we'll carry on with unworkably huge reserves on 64 KiB page size while rejecting every way out until pageblocks are _entirely_ reworked to account for this (probably the long term solution).

So I think this the least-worst approach of those proposed so far for now :) Therefore:

Quoted 64 lines

---
v2:
* Use a named constant for the cap.
* Drop explicit linux/sizes.h include.
* Update min_free_kbytes documentation.

v1:
* Cap the final recommendation at 1 GiB as suggested by Lorenzo.
https://lore.kernel.org/r/[email protected]/

RFC v1:
https://lore.kernel.org/r/[email protected]/

---
 Documentation/admin-guide/sysctl/vm.rst | 8 ++++++++
 mm/khugepaged.c                         | 7 ++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)
Documentation/admin-guide/sysctl/vm.rst +8 -0
index 5b318d17aa4b..c0c925e6f504 100644
@@ -539,6 +539,14 @@ watermark[WMARK_MIN] value for each lowmem zone in the system.
 Each lowmem zone gets a number of reserved free pages based
 proportionally on its size.
 
+When Transparent Hugepage (THP) support is enabled through global or
+per-size controls, the kernel may raise this value automatically to
+help keep pageblocks free and reduce fragmentation for THP allocations.
+The automatic recommendation cannot exceed 5% of low memory or 1 GiB,
+whichever is lower.  This limit applies only to the automatic
+recommendation and does not constrain a higher value written by
+userspace.
+
 Some minimal amount of memory is needed to satisfy PF_MEMALLOC
 allocations; if you set this to lower than 1024KB, your system will
 become subtly broken, and prone to deadlock under high loads.
mm/khugepaged.c +6 -2
index f49a6710933b..a8fc061d2488 100644
@@ -101,6 +101,7 @@ static DEFINE_READ_MOSTLY_HASHTABLE(mm_slots_hash, MM_SLOTS_HASH_BITS);
 
 static struct kmem_cache *mm_slot_cache __ro_after_init;
 
+#define THP_MIN_FREE_MAX_PAGES		(SZ_1G / PAGE_SIZE)
 #define KHUGEPAGED_MIN_MTHP_ORDER	2
 
 struct collapse_control {
@@ -3120,9 +3121,13 @@ void set_recommended_min_free_kbytes(void)
 	recommended_min += pageblock_nr_pages * nr_zones *
 			   MIGRATE_PCPTYPES * MIGRATE_PCPTYPES;
 
-	/* don't ever allow to reserve more than 5% of the lowmem */
+	/*
+	 * Don't allow the THP recommendation to exceed 5% of lowmem or an
+	 * absolute cap, whichever is smaller.
+	 */
 	recommended_min = min(recommended_min,
 			      (unsigned long) nr_free_buffer_pages() / 20);
+	recommended_min = min(recommended_min, THP_MIN_FREE_MAX_PAGES);
 	recommended_min <<= (PAGE_SHIFT-10);
 
 	if (recommended_min > min_free_kbytes) {
--
Quoted 2 lines

2.45.0

--
Cheers, Lorenzo

reviewer
#4 lore raw
In reply to Nimrod Oren
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

Sorry, I haven't been following the previous discussion.

One nit: why 1 GiB? It feels a bit arbitrary to me ...

reviewer
#5 lore raw
Quoted 18 lines · Lance Yang
Quoted 17 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Quoted 8 lines
Quoted 4 lines

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

Sorry, I haven't been following the previous discussion.

One nit: why 1 GiB? It feels a bit arbitrary to me ...

It is. Just better than 5.5GiB in the existing configuration.

Best Regards,
Yan, Zi

reviewer
#6 lore raw
In reply to Nimrod Oren
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

I would argue that the whole model of increasing min_free_kbytes for THP is wrong. This will trigger memory reclaim sooner and make the THP availability more likely but this was at times where we didn't have pro-active compaction and many changes in the compaction. So is this actually needed in general resp. only large pageblocks systems?

Signature · 2 lines
Michal Hocko
SUSE Labs
#7 lore raw
Quoted 23 lines · Michal Hocko
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

Quoted 5 lines

I would argue that the whole model of increasing min_free_kbytes for THP is wrong. This will trigger memory reclaim sooner and make the THP availability more likely but this was at times where we didn't have pro-active compaction and many changes in the compaction. So is this actually needed in general resp. only large pageblocks systems?

Ohh even better :)

I did find it strange that we increased accordingly.

I'm more than happy to see this just die altogether if people agree that's a sensible way forward...

Quoted 4 lines

--
Michal Hocko
SUSE Labs

--
Cheers, Lorenzo

reviewer
#8 lore raw
Quoted 30 lines · Lorenzo Stoakes (ARM)
Quoted 23 lines · Michal Hocko
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

Quoted 5 lines

I would argue that the whole model of increasing min_free_kbytes for THP is wrong. This will trigger memory reclaim sooner and make the THP availability more likely but this was at times where we didn't have pro-active compaction and many changes in the compaction. So is this actually needed in general resp. only large pageblocks systems?

Quoted 6 lines

Ohh even better :)

I did find it strange that we increased accordingly.

I'm more than happy to see this just die altogether if people agree that's a sensible way forward...

It sounds reasonable to me.

My first reaction was that THP generation might be hurt due to fewer free pages. But probably the extra min_free_kbytes just moves reclaim earlier, like Michal said.

After removing this automatic min_free_kbytes bump, user can retain the old behavior by setting a higher min_free_kbytes at boot time.

Best Regards,
Yan, Zi

#9 lore raw
Quoted 39 lines · Zi Yan
Quoted 30 lines · Lorenzo Stoakes (ARM)
Quoted 23 lines · Michal Hocko
Quoted 15 lines · Nimrod Oren

When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory.

This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is:

4 KiB pages: 2 MiB pageblock, 22 MiB per zone
16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone

Quoted 6 lines

Consequently, min_free_kbytes can reach excessive and unwanted levels.

Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks.

Quoted 5 lines

I would argue that the whole model of increasing min_free_kbytes for THP is wrong. This will trigger memory reclaim sooner and make the THP availability more likely but this was at times where we didn't have pro-active compaction and many changes in the compaction. So is this actually needed in general resp. only large pageblocks systems?

Quoted 6 lines

Ohh even better :)

I did find it strange that we increased accordingly.

I'm more than happy to see this just die altogether if people agree that's a sensible way forward...

Quoted 8 lines

It sounds reasonable to me.

My first reaction was that THP generation might be hurt due to fewer free pages. But probably the extra min_free_kbytes just moves reclaim earlier, like Michal said.

After removing this automatic min_free_kbytes bump, user can retain the old behavior by setting a higher min_free_kbytes at boot time.

Nimrod - care to send a patch to just yank this min_free_kbytes change for thp out? :)

This solves your problem another way and is neater overall.

Quoted 3 lines

Best Regards,
Yan, Zi

--
Cheers, Lorenzo

#10 lore raw
Quoted 22 lines · Lorenzo Stoakes (ARM)
Quoted 21 lines · Zi Yan
Quoted 7 lines · Lorenzo Stoakes (ARM)
Quoted 5 lines · Michal Hocko

I would argue that the whole model of increasing min_free_kbytes for THP is wrong. This will trigger memory reclaim sooner and make the THP availability more likely but this was at times where we didn't have pro-active compaction and many changes in the compaction. So is this actually needed in general resp. only large pageblocks systems?

Quoted 6 lines

Ohh even better :)

I did find it strange that we increased accordingly.

I'm more than happy to see this just die altogether if people agree that's a sensible way forward...

It sounds reasonable to me.

My first reaction was that THP generation might be hurt due to fewer free pages. But probably the extra min_free_kbytes just moves reclaim earlier, like Michal said.

Quoted 7 lines
Quoted 2 lines

After removing this automatic min_free_kbytes bump, user can retain the old behavior by setting a higher min_free_kbytes at boot time.

Nimrod - care to send a patch to just yank this min_free_kbytes change for thp out? :)

This solves your problem another way and is neater overall.

Absolutely :)
Thanks for the suggestion!