All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sourav Panda <souravpanda@google.com>
To: muchun.song@linux.dev, osalvador@suse.de, akpm@linux-foundation.org
Cc: david@kernel.org, ljs@kernel.org, liam@infradead.org,
	vbabka@kernel.org,  rppt@kernel.org, surenb@google.com,
	mhocko@suse.com, mst@redhat.com,  mhklinux@outlook.com,
	souravpanda@google.com, fvdl@google.com,  gthelen@google.com,
	mike.kravetz@oracle.com, pasha.tatashin@soleen.com,
	 rientjes@google.com, riel@surriel.com, linux-mm@kvack.org,
	 linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	 linux-doc@vger.kernel.org
Subject: [PATCH 4/6] mm/hugetlb: add memory shrinker for cache
Date: Tue,  7 Jul 2026 06:42:33 +0000	[thread overview]
Message-ID: <20260707064235.1386552-5-souravpanda@google.com> (raw)
In-Reply-To: <20260707064235.1386552-1-souravpanda@google.com>

Register a memory shrinker for the HugeTLB dynamic cache to
reclaim cached pages under memory pressure.

Implement hugetlb_shrinker_count to report the number of cached pages
(currently limited to gigantic pages in the shrinker) and
hugetlb_shrinker_scan to free them back to the buddy allocator.

The shrinker scan uses LRU policy to reclaim the coldest pages first.

Signed-off-by: Sourav Panda <souravpanda@google.com>
---
 mm/hugetlb.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index f18a3123cbcb..1bc0198a695c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4399,6 +4399,68 @@ ssize_t __max_cached_huge_pages_store_common(bool obey_mempolicy,
 
 	return err ? err : len;
 }
+
+static unsigned long hugetlb_shrinker_count(struct shrinker *shrink,
+					    struct shrink_control *sc)
+{
+	struct hstate *h;
+	unsigned long count = 0;
+	int nid = sc->nid;
+
+	for_each_hstate(h) {
+		count += h->nr_cached_hugepages_node[nid];
+	}
+	return count;
+}
+
+static unsigned long hugetlb_shrinker_scan(struct shrinker *shrink,
+					   struct shrink_control *sc)
+{
+	struct hstate *h;
+	int nid = sc->nid;
+	unsigned long freed = 0;
+	unsigned long to_scan = sc->nr_to_scan;
+
+	for_each_hstate(h) {
+		while (freed < to_scan) {
+			struct folio *folio = NULL;
+			bool atomic = true;
+
+			/*
+			 * Only do synchronous vmemmap restoration if the caller
+			 * context allows blocking and FS reclaim (GFP_KERNEL compatible).
+			 * Otherwise, defer to workqueue to avoid lock inversion.
+			 */
+			if (gfpflags_allow_blocking(sc->gfp_mask) &&
+			    (sc->gfp_mask & __GFP_FS))
+				atomic = false;
+
+			spin_lock_irq(&hugetlb_lock);
+			if (list_empty(&h->hugepage_cache_lists[nid])) {
+				spin_unlock_irq(&hugetlb_lock);
+				break;
+			}
+
+			folio = list_first_entry(&h->hugepage_cache_lists[nid],
+						 struct folio, lru);
+
+			remove_hugetlb_folio(h, folio, false);
+			spin_unlock_irq(&hugetlb_lock);
+
+			update_and_free_hugetlb_folio(h, folio, atomic);
+
+			freed++;
+			if (current->reclaim_state)
+				current->reclaim_state->reclaimed += pages_per_huge_page(h);
+		}
+		if (freed >= to_scan)
+			break;
+	}
+
+	return freed;
+}
+
+static struct shrinker *hugetlb_cached_pages_shrinker;
 #endif /* CONFIG_HUGETLB_CACHE */
 
 ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
@@ -4502,6 +4564,21 @@ static int __init hugetlb_init(void)
 
 	for (i = 0; i < num_fault_mutexes; i++)
 		mutex_init(&hugetlb_fault_mutex_table[i]);
+
+#ifdef CONFIG_HUGETLB_CACHE
+	hugetlb_cached_pages_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE |
+						       SHRINKER_NONSLAB,
+						       "hugetlb-cached-pages");
+	if (!hugetlb_cached_pages_shrinker) {
+		pr_warn("HugeTLB: Failed to allocate shrinker\n");
+	} else {
+		hugetlb_cached_pages_shrinker->count_objects = hugetlb_shrinker_count;
+		hugetlb_cached_pages_shrinker->scan_objects = hugetlb_shrinker_scan;
+		hugetlb_cached_pages_shrinker->batch = 1;
+		shrinker_register(hugetlb_cached_pages_shrinker);
+	}
+#endif
+
 	return 0;
 }
 subsys_initcall(hugetlb_init);
-- 
2.55.0.rc0.799.gd6f94ed593-goog


  parent reply	other threads:[~2026-07-07  6:42 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-07  6:42 [RFC PATCH 0/6] mm/hugetlb: Dynamic, NUMA-aware HugePage Cache & Free Page Reporting Sourav Panda
2026-07-07  6:42 ` [PATCH 1/6] mm/hugetlb: add Kconfig and basic cache infrastructure Sourav Panda
2026-07-07  6:42 ` [PATCH 2/6] mm/hugetlb: implement cache recycling and allocation Sourav Panda
2026-07-07  6:42 ` [PATCH 3/6] mm/hugetlb: add sysfs interfaces for cache Sourav Panda
2026-07-07  6:42 ` Sourav Panda [this message]
2026-07-07  6:42 ` [PATCH 5/6] Documentation/admin-guide/mm/hugetlbpage.rst: document cache interfaces Sourav Panda
2026-07-07  6:42 ` [PATCH 6/6] mm/hugetlb: support free page reporting for cached hugepages Sourav Panda
2026-07-07  7:18   ` Michael S. Tsirkin
2026-07-07 10:18   ` Michael S. Tsirkin
2026-07-07  6:56 ` [RFC PATCH 0/6] mm/hugetlb: Dynamic, NUMA-aware HugePage Cache & Free Page Reporting Michael S. Tsirkin
2026-07-07  7:21   ` Sourav Panda
2026-07-07  7:29 ` David Hildenbrand (Arm)
2026-07-07  8:09   ` Muchun Song
2026-07-07 10:25   ` Michael S. Tsirkin
2026-07-07 10:28     ` David Hildenbrand (Arm)
2026-07-07 11:06       ` Lorenzo Stoakes
2026-07-07 14:01         ` Michael S. Tsirkin
2026-07-07 18:46           ` Lorenzo Stoakes
2026-07-07 19:32             ` Michael S. Tsirkin
2026-07-07 19:46               ` David Hildenbrand (Arm)
2026-07-08  8:26                 ` Lorenzo Stoakes
2026-07-08  9:16                   ` Michael S. Tsirkin
2026-07-09  6:15                     ` Sourav Panda

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=20260707064235.1386552-5-souravpanda@google.com \
    --to=souravpanda@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=fvdl@google.com \
    --cc=gthelen@google.com \
    --cc=liam@infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhklinux@outlook.com \
    --cc=mhocko@suse.com \
    --cc=mike.kravetz@oracle.com \
    --cc=mst@redhat.com \
    --cc=muchun.song@linux.dev \
    --cc=osalvador@suse.de \
    --cc=pasha.tatashin@soleen.com \
    --cc=riel@surriel.com \
    --cc=rientjes@google.com \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    /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.