linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v2 00/16] Page Alloc Hogger
@ 2026-08-06  1:09 Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 01/16] mm: Page Alloc Hogger module Juan Yescas
                   ` (17 more replies)
  0 siblings, 18 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This patch series introduces the Page Alloc Hogger. The Page Alloc Hogger
allows you to allocate memory pages from specific nodes, zones, migration
types, and orders directly via debugfs. This provides key benefits for
testing and debugging:

- Reproduce low-memory conditions: Easily trigger and inspect kernel
mechanisms like direct reclaim, kswapd, the OOM killer, and allocation
fallbacks.

- Simplify memory pressure debugging: Debug issues that only manifest under
memory stress without needing custom kernel drivers or userspace programs
to allocate memory.

- Simplify unit testing: Verify that memory management subsystems
(direct reclaim, OOM killer, kswapd) trigger as expected in test suites.

- Measure performance under stress: Evaluate how applications behave and
perform during severe memory pressure.

Usage:

1. To trigger the allocation, navigate to the debugfs path corresponding
   to your target node, memory zone, allocation order, and migration type,
   then write the requested allocation count to nr_pages_allocs.

   For example, to make 3 allocs of order 9, Migrate Type Movable,
   Zone Normal and Node 0, run:

   $ echo 3 > /sys/kernel/debug/mm/node-0/zone-Normal/order-9/migrate-Movable/nr_pages_allocs

2. For each allocation created, a corresponding file named sequentially
   (1, 2, n) will appear in that directory.

   $ ls /sys/kernel/debug/mm/node-0/zone-Normal/order-9/migrate-Movable/
   1   2   3  nr_pages_allocs

3. To free the allocation, write the allocation file name in
   /sys/kernel/debug/mm/free. For example, to release the 2nd allocation run:

   $ echo 2 > /sys/kernel/debug/mm/free

Example:

$ cat /proc/pagetypeinfo
Page block order: 9
Pages per block:  512

Free pages count per migrate type at order 0  1  2  3  4  5  6  7  8  9   10
Node 0, zone    DMA, type   Unmovable      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type     Movable      1  1  1  0  1  1  2  2  1  3  732
Node 0, zone    DMA, type Reclaimable      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type  HighAtomic      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type         CMA      0  0  0  0  0  0  0  0  0  1    7
Node 0, zone    DMA, type     Isolate      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone Normal, type   Unmovable     13  7  0  1  0  0  1  0  1  0    0
Node 0, zone Normal, type     Movable      1  1  1  1  1  1  1  0  1  1 1221
Node 0, zone Normal, type Reclaimable      1  0  0  0  0  0  1  0  0  1    0
Node 0, zone Normal, type  HighAtomic      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone Normal, type         CMA      0  0  0  0  0  0  0  0  0  1    7
Node 0, zone Normal, type     Isolate      0  0  0  0  0  0  0  0  0  0    0

Number of blocks type  Unmovable  Movable Reclaimable HighAtomic CMA Isolate
Node 0, zone      DMA          0     1520           0          0  16       0
Node 0, zone   Normal         12     2530           2          0  16       0

$ echo 1200 > /sys/kernel/debug/mm/node-0/zone-Normal/order-10/migrate-Movable/nr_pages_allocs

$ cat /proc/pagetypeinfo
Page block order: 9
Pages per block:  512

Free pages count per migrate type at order 0  1  2  3  4  5  6  7  8  9   10
Node 0, zone    DMA, type   Unmovable      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type     Movable      1  1  1  0  1  1  2  2  1  3  732
Node 0, zone    DMA, type Reclaimable      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type  HighAtomic      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type         CMA      0  0  0  0  0  0  0  0  0  1    7
Node 0, zone    DMA, type     Isolate      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone Normal, type   Unmovable     13  7  1  1  0  0  0  0  1  0    0
Node 0, zone Normal, type     Movable      1  1  1  1  1  1  1  0  1  1   21
Node 0, zone Normal, type Reclaimable      0  1  0  0  1  0  0  0  1  0    0
Node 0, zone Normal, type  HighAtomic      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone Normal, type         CMA      0  0  0  0  0  0  0  0  0  1    7
Node 0, zone Normal, type     Isolate      0  0  0  0  0  0  0  0  0  0    0

Number of blocks type  Unmovable  Movable Reclaimable HighAtomic CMA Isolate
Node 0, zone      DMA          0     1520           0          0  16       0
Node 0, zone   Normal         12     2530           2          0  16       0

$ for i in `seq 1 1200`; do echo $i > /sys/kernel/debug/mm/free; done

$ cat /proc/pagetypeinfo
Page block order: 9
Pages per block:  512

Free pages count per migrate type at order 0  1  2  3  4  5  6  7  8  9   10
Node 0, zone    DMA, type   Unmovable      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type     Movable      1  1  1  0  1  1  2  2  1  3  732
Node 0, zone    DMA, type Reclaimable      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type  HighAtomic      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone    DMA, type         CMA      0  0  0  0  0  0  0  0  0  1    7
Node 0, zone    DMA, type     Isolate      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone Normal, type   Unmovable     13  7  1  1  0  0  0  0  1  0    0
Node 0, zone Normal, type     Movable      1  1  1  1  1  1  1  0  1  1 1221
Node 0, zone Normal, type Reclaimable      0  1  0  0  1  0  0  0  1  0    0
Node 0, zone Normal, type  HighAtomic      0  0  0  0  0  0  0  0  0  0    0
Node 0, zone Normal, type         CMA      0  0  0  0  0  0  0  0  0  1    7
Node 0, zone Normal, type     Isolate      0  0  0  0  0  0  0  0  0  0    0

Number of blocks type  Unmovable  Movable Reclaimable HighAtomic CMA Isolate
Node 0, zone      DMA          0     1520           0          0  16       0
Node 0, zone   Normal         12     2530           2          0  16       0

Notes:

- The only zone that is not supported is ZONE_DEVICE.
- MIGRATE_CMA will be supported soon

Juan Yescas (16):
  mm: Page Alloc Hogger module
  mm: Define structs for allocation requests and store allocations
  mm: Define the caches for the structs req_alloc and page_alloc
  mm: Define function to create a dir for each online node
  mm: Define function to create a dir for populated zone
  mm: Define function to create a dir for each page order
  mm: Define function to create a dir for each migrate type
  mm: Define function that creates the "nr_pages_allocs" file
  mm: Read the nr_pages_allocs value given by user
  mm: Set the selected zone in gfp_t flags
  mm: Sets the migrate type in gfp_t flags
  mm: Define the make_alloc() function
  mm: Create the file associated with an allocation
  mm: Free pages, remove files and clean cache when one alloc fails
  mm: Create the "free" file to release the previously allocated pages
  mm: Release resources when the page alloc hogger module exits

 mm/Kconfig.debug       |  12 +
 mm/Makefile            |   1 +
 mm/page_alloc_hogger.c | 610 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 623 insertions(+)
 create mode 100644 mm/page_alloc_hogger.c

-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 01/16] mm: Page Alloc Hogger module
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 02/16] mm: Define structs for allocation requests and store allocations Juan Yescas
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This patch contains the skeleton for the Page Alloc Hogger. It creates the
"mm" dir that will be the base directory that will contain the "free" file
and the "node-<x>" dirs.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Change to a tristate module.
	- Fix typos
	- Use static for the mmdir declaration.

 mm/Kconfig.debug       |  12 +++++
 mm/Makefile            |   1 +
 mm/page_alloc_hogger.c | 115 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 128 insertions(+)
 create mode 100644 mm/page_alloc_hogger.c

diff --git a/mm/Kconfig.debug b/mm/Kconfig.debug
index 7638d75b27db..bad8a606152c 100644
--- a/mm/Kconfig.debug
+++ b/mm/Kconfig.debug
@@ -309,3 +309,15 @@ config PER_VMA_LOCK_STATS
 	  overhead in the page fault path.
 
 	  If in doubt, say N.
+
+config PAGEALLOC_HOGGER
+	tristate "Alloc pages from different nodes, zones, migrate types and orders"
+	depends on DEBUG_FS
+	help
+	  Say Y to alloc pages from different nodes, zones, migrate type and
+	  orders using the debug fs filesystem. This helps to generate memory
+	  pressure easily. This is useful to debug memory reclaims issues,
+	  OOM triggers, page migration issues, etc.
+
+	  If in doubt, say N.
+
diff --git a/mm/Makefile b/mm/Makefile
index 2d0570a16e5b..b48f2ac6ee80 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -133,6 +133,7 @@ obj-$(CONFIG_IDLE_PAGE_TRACKING) += page_idle.o
 obj-$(CONFIG_DEBUG_PAGEALLOC) += debug_page_alloc.o
 obj-$(CONFIG_DEBUG_PAGE_REF) += debug_page_ref.o
 obj-$(CONFIG_DAMON) += damon/
+obj-$(CONFIG_PAGEALLOC_HOGGER) += page_alloc_hogger.o
 obj-$(CONFIG_HARDENED_USERCOPY) += usercopy.o
 obj-$(CONFIG_PERCPU_STATS) += percpu-stats.o
 obj-$(CONFIG_ZONE_DEVICE) += memremap.o
diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
new file mode 100644
index 000000000000..1d31e981920e
--- /dev/null
+++ b/mm/page_alloc_hogger.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Page allocator DebugFS Interface
+ * Author: Juan Yescas <jyescas@google.com>
+ *
+ * This module allows to make page allocs per node, zone, migrate type
+ * and order using the DebugFS filesystem.
+ *
+ * When this module is installed and the debugfs is mounted, the "mm" directory
+ * will be created in <debugfs mount point>/mm" directory. Under this directory,
+ * there will be subdirs to select the nodes, zones, orders and migrate type.
+ *
+ * For example:
+ *
+ *      /sys/kernel/debug/mm/
+ *      |-- free
+ *      `-- node-0
+ *         |-- zone-DMA
+ *         |   |-- order-0
+ *         |   |   |-- migrate-HighAtomic
+ *         |   |   |   `-- nr_pages_allocs
+ *         |   |   |-- migrate-Movable
+ *         |   |   |   `-- nr_pages_allocs
+ *         |   |   |-- migrate-Reclaimable
+ *         |   |   |   `-- nr_pages_allocs
+ *         |   |   `-- migrate-Unmovable
+ *         |   |       `-- nr_pages_allocs
+ *         |   |-- ...
+ *         |   |
+ *         |   `-- order-9
+ *         |       |-- migrate-HighAtomic
+ *         |       |   `-- nr_pages_allocs
+ *         |       |-- migrate-Movable
+ *         |       |   `-- nr_pages_allocs
+ *         |       |-- migrate-Reclaimable
+ *         |       |   `-- nr_pages_allocs
+ *         |       `-- migrate-Unmovable
+ *         |           `-- nr_pages_allocs
+ *         `-- zone-Normal
+ *             |-- order-0
+ *             |   |-- migrate-HighAtomic
+ *             |   |   `-- nr_pages_allocs
+ *             |   |-- migrate-Movable
+ *             |   |   `-- nr_pages_allocs
+ *             |   |-- migrate-Reclaimable
+ *             |   |   `-- nr_pages_allocs
+ *             |   `-- migrate-Unmovable
+ *             |       `-- nr_pages_allocs
+ *             |-- ....
+ *             |
+ *             `-- order-9
+ *                 |-- migrate-HighAtomic
+ *                 |   `-- nr_pages_allocs
+ *                 |-- migrate-Movable
+ *                 |   `-- nr_pages_allocs
+ *                 |-- migrate-Reclaimable
+ *                 |   `-- nr_pages_allocs
+ *                 `-- migrate-Unmovable
+ *                     `-- nr_pages_allocs
+ *
+ * Usage:
+ *
+ * 1. To trigger the allocation, navigate to the debugfs path corresponding
+ *    to your target node, memory zone, allocation order, and migration type,
+ *    then write the requested allocation count to nr_pages_allocs.
+ *
+ *    For example, to make 3 allocs of order 9, Migrate Type Movable,
+ *    Zone Normal and Node 0, run:
+ *
+ *    $ echo 3 > /sys/kernel/debug/mm/node-0/zone-Normal/order-9/migrate-Movable/nr_pages_allocs
+ *
+ * 2. For each allocation created, a corresponding file named sequentially
+ *    (1, 2, n) will appear in that directory.
+ *
+ *    $ ls /sys/kernel/debug/mm/node-0/zone-Normal/order-9/migrate-Movable/
+ *    1   2   3  nr_pages_allocs
+ *
+ * 3. To free the allocation, write the allocation file name in /sys/kernel/debug/mm/free.
+ *    For example, to release the 2nd allocation run:
+ *
+ *    $ echo 2 > /sys/kernel/debug/mm/free
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/errno.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+
+static struct dentry *mmdir;
+
+static int __init page_alloc_hogger_debugfs_init(void)
+{
+	mmdir = debugfs_create_dir("mm", NULL);
+	if (IS_ERR(mmdir)) {
+		pr_err("Unable to create mm directory\n");
+		return PTR_ERR(mmdir);
+	}
+
+	return 0;
+}
+
+static void __exit page_alloc_hogger_debugfs_exit(void)
+{
+	debugfs_remove_recursive(mmdir);
+}
+
+module_init(page_alloc_hogger_debugfs_init);
+module_exit(page_alloc_hogger_debugfs_exit);
+
+MODULE_AUTHOR("Juan Yescas");
+MODULE_DESCRIPTION("Module to alloc pages to generate memory pressure");
+MODULE_LICENSE("GPL");
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 02/16] mm: Define structs for allocation requests and store allocations
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 01/16] mm: Page Alloc Hogger module Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 03/16] mm: Define the caches for the structs req_alloc and page_alloc Juan Yescas
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change introduces the next structs:

- struct req_alloc to keep the request info for the allocation.

- struct page_alloc to store a pointer to the page that was
allocated, the request info and the file that represents this
allocation. This file will be used to free the allocation when
it is not longer needed.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Fix comment block. Add an extra * at the beginning.

 mm/page_alloc_hogger.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 1d31e981920e..caeb2e5e8579 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -91,6 +91,34 @@
 
 static struct dentry *mmdir;
 
+/**
+ * struct req_alloc - Represents the requested allocation
+ * @node_idx: The Node index to allocate from.
+ * @zone_idx: The Zone index to allocate from.
+ * @order: The Order of pages to allocate.
+ * @migrate_type: The Migrate type to allocate from.
+ * @parentdir: The parent dir where the file representing the alloc was created.
+ */
+struct req_alloc {
+	int node_idx;
+	int zone_idx;
+	int order;
+	int migrate_type;
+	struct dentry *parentdir;
+};
+
+/**
+ * struct page_alloc - Represents the page allocation.
+ * @page: The pointer to the page(s) allocated.
+ * @req_alloc: The details of the allocation.
+ * @alloc_dentry: The pointer to the file that represents the allocation.
+ */
+struct page_alloc {
+	struct page *page;
+	struct req_alloc *req_alloc;
+	struct dentry *alloc_dentry;
+};
+
 static int __init page_alloc_hogger_debugfs_init(void)
 {
 	mmdir = debugfs_create_dir("mm", NULL);
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 03/16] mm: Define the caches for the structs req_alloc and page_alloc
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 01/16] mm: Page Alloc Hogger module Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 02/16] mm: Define structs for allocation requests and store allocations Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 04/16] mm: Define function to create a dir for each online node Juan Yescas
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change defines and initializes the caches for the structs req_alloc
and page_alloc.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Use static for the kmem_cache variables.
	- Use \n for the pr_err messages.

 mm/page_alloc_hogger.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index caeb2e5e8579..175f479c487b 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -85,9 +85,12 @@
 
 #include <linux/errno.h>
 #include <linux/debugfs.h>
+#include <linux/gfp.h>
+#include <linux/gfp_types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/printk.h>
+#include <linux/slab.h>
 
 static struct dentry *mmdir;
 
@@ -119,20 +122,55 @@ struct page_alloc {
 	struct dentry *alloc_dentry;
 };
 
+static struct kmem_cache *req_alloc_cache;
+static struct kmem_cache *page_alloc_cache;
+
 static int __init page_alloc_hogger_debugfs_init(void)
 {
+	int ret;
+
+	req_alloc_cache = kmem_cache_create(
+		"req_alloc_cache", sizeof(struct req_alloc), 0,
+		SLAB_HWCACHE_ALIGN, NULL);
+	if (!req_alloc_cache) {
+		pr_err("The req_alloc_cache couldn't be created\n");
+		ret = -ENOMEM;
+		goto error_exit;
+	}
+
+	page_alloc_cache = kmem_cache_create(
+		"page_alloc_cache", sizeof(struct page_alloc), 0,
+		SLAB_HWCACHE_ALIGN, NULL);
+	if (!page_alloc_cache) {
+		pr_err("The page_alloc_cache couldn't be created\n");
+		ret = -ENOMEM;
+		goto clean_req_alloc_cache;
+	}
+
 	mmdir = debugfs_create_dir("mm", NULL);
 	if (IS_ERR(mmdir)) {
 		pr_err("Unable to create mm directory\n");
-		return PTR_ERR(mmdir);
+		ret = PTR_ERR(mmdir);
+		goto clean_page_alloc_cache;
 	}
 
 	return 0;
+
+clean_page_alloc_cache:
+	kmem_cache_destroy(page_alloc_cache);
+
+clean_req_alloc_cache:
+	kmem_cache_destroy(req_alloc_cache);
+
+error_exit:
+	return ret;
 }
 
 static void __exit page_alloc_hogger_debugfs_exit(void)
 {
 	debugfs_remove_recursive(mmdir);
+	kmem_cache_destroy(req_alloc_cache);
+	kmem_cache_destroy(page_alloc_cache);
 }
 
 module_init(page_alloc_hogger_debugfs_init);
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 04/16] mm: Define function to create a dir for each online node
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (2 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 03/16] mm: Define the caches for the structs req_alloc and page_alloc Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 05/16] mm: Define function to create a dir for populated zone Juan Yescas
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change creates a directory for each online node
in the system.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Fix comments.
	- Use for_each_node_state(nid, N_MEMORY) instead.

 mm/page_alloc_hogger.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 175f479c487b..5765ecc43567 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -89,6 +89,7 @@
 #include <linux/gfp_types.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/nodemask.h>
 #include <linux/printk.h>
 #include <linux/slab.h>
 
@@ -125,6 +126,26 @@ struct page_alloc {
 static struct kmem_cache *req_alloc_cache;
 static struct kmem_cache *page_alloc_cache;
 
+/**
+ * create_nodes_subdirs() - Creates a directory for each node that contains
+ * memory.
+ */
+static inline int create_nodes_subdirs(struct dentry *mmdir)
+{
+	struct dentry *nodedir;
+	int nid;
+	char dirname[12];
+
+	for_each_node_state(nid, N_MEMORY) {
+		snprintf(dirname, sizeof(dirname), "node-%d", nid);
+		nodedir = debugfs_create_dir(dirname, mmdir);
+		if (IS_ERR(nodedir))
+			return PTR_ERR(nodedir);
+	}
+
+	return 0;
+}
+
 static int __init page_alloc_hogger_debugfs_init(void)
 {
 	int ret;
@@ -154,8 +175,15 @@ static int __init page_alloc_hogger_debugfs_init(void)
 		goto clean_page_alloc_cache;
 	}
 
+	ret = create_nodes_subdirs(mmdir);
+	if (ret)
+		goto clean_dir;
+
 	return 0;
 
+clean_dir:
+	debugfs_remove_recursive(mmdir);
+
 clean_page_alloc_cache:
 	kmem_cache_destroy(page_alloc_cache);
 
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 05/16] mm: Define function to create a dir for populated zone
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (3 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 04/16] mm: Define function to create a dir for each online node Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 06/16] mm: Define function to create a dir for each page order Juan Yescas
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change creates a directory for each populated zone
in the node.

Note: ZONE_DEVICE pages won't be exposed in this driver
due they are not managed by the Buddy Allocator.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Update comments.
	- Remove unused variables.

 mm/page_alloc_hogger.c | 46 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 5765ecc43567..e8944080e82e 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -88,6 +88,7 @@
 #include <linux/gfp.h>
 #include <linux/gfp_types.h>
 #include <linux/kernel.h>
+#include <linux/mmzone.h>
 #include <linux/module.h>
 #include <linux/nodemask.h>
 #include <linux/printk.h>
@@ -126,21 +127,62 @@ struct page_alloc {
 static struct kmem_cache *req_alloc_cache;
 static struct kmem_cache *page_alloc_cache;
 
+
+/**
+ * create_zones_subdirs() - Creates a directory for each populated zone in the
+ * node.
+ *
+ * Note: ZONE_DEVICE pages won't be allocated using this driver. The main reason
+ * is because they are not managed by the Buddy Allocator or CMA allocator.
+ */
+static inline int create_zones_subdirs(struct dentry *nodedir,
+					struct pglist_data *pgdata)
+{
+	struct dentry *zonedir;
+	struct zone *zone;
+	struct zone *node_zones = pgdata->node_zones;
+	char dirname[24];
+
+	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
+		if (!populated_zone(zone))
+			continue;
+
+		/* ZONE_DEVICE pages won't be allocated using this driver. */
+		if (zone_is_zone_device(zone))
+			continue;
+
+		snprintf(dirname, sizeof(dirname), "zone-%s", zone->name);
+		zonedir = debugfs_create_dir(dirname, nodedir);
+		if (IS_ERR(zonedir))
+			return PTR_ERR(zonedir);
+	}
+
+	return 0;
+}
+
 /**
  * create_nodes_subdirs() - Creates a directory for each node that contains
- * memory.
+ * memory. Once that the node directory is created, it creates a directory for
+ * each zone in the node.
  */
 static inline int create_nodes_subdirs(struct dentry *mmdir)
 {
 	struct dentry *nodedir;
-	int nid;
 	char dirname[12];
+	int nid;
+	int ret;
 
 	for_each_node_state(nid, N_MEMORY) {
+		struct pglist_data *pgdata = NODE_DATA(nid);
+
 		snprintf(dirname, sizeof(dirname), "node-%d", nid);
 		nodedir = debugfs_create_dir(dirname, mmdir);
 		if (IS_ERR(nodedir))
 			return PTR_ERR(nodedir);
+
+		ret = create_zones_subdirs(nodedir, pgdata);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 06/16] mm: Define function to create a dir for each page order
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (4 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 05/16] mm: Define function to create a dir for populated zone Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 07/16] mm: Define function to create a dir for each migrate type Juan Yescas
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change creates a directory for each page order inside
the zone directory.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Update comments.
	- Remove unused parameters in function.

 mm/page_alloc_hogger.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index e8944080e82e..24856f7ea5d7 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -127,10 +127,29 @@ struct page_alloc {
 static struct kmem_cache *req_alloc_cache;
 static struct kmem_cache *page_alloc_cache;
 
+/**
+ * create_page_orders_subdirs() - Creates a directory for each page order inside
+ * the zone directory.
+ */
+static inline int create_page_orders_subdirs(struct dentry *zonedir)
+{
+	struct dentry *orderdir;
+	char dirname[12];
+
+	for (int order = 0; order < NR_PAGE_ORDERS; order++) {
+		snprintf(dirname, sizeof(dirname), "order-%d", order);
+		orderdir = debugfs_create_dir(dirname, zonedir);
+		if (IS_ERR(orderdir))
+			return PTR_ERR(orderdir);
+	}
+
+	return 0;
+}
 
 /**
  * create_zones_subdirs() - Creates a directory for each populated zone in the
- * node.
+ * node. Once that the zone directory is created, it creates a directory for
+ * each order supported.
  *
  * Note: ZONE_DEVICE pages won't be allocated using this driver. The main reason
  * is because they are not managed by the Buddy Allocator or CMA allocator.
@@ -142,6 +161,7 @@ static inline int create_zones_subdirs(struct dentry *nodedir,
 	struct zone *zone;
 	struct zone *node_zones = pgdata->node_zones;
 	char dirname[24];
+	int ret;
 
 	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
 		if (!populated_zone(zone))
@@ -155,6 +175,10 @@ static inline int create_zones_subdirs(struct dentry *nodedir,
 		zonedir = debugfs_create_dir(dirname, nodedir);
 		if (IS_ERR(zonedir))
 			return PTR_ERR(zonedir);
+
+		ret = create_page_orders_subdirs(zonedir);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 07/16] mm: Define function to create a dir for each migrate type
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (5 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 06/16] mm: Define function to create a dir for each page order Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 08/16] mm: Define function that creates the "nr_pages_allocs" file Juan Yescas
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change creates a directory for each migrate type inside
the order directory.

This function won't create a directory for MIGRATE_ISOLATE due
they can't be allocated using the Buddy Allocator.

Note: The MIGRATE_CMA directory won't be created yet. It will
be supported in the future.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Update comments.
	- Remove unused parameters.

 mm/page_alloc_hogger.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 24856f7ea5d7..ab39ea300704 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -127,20 +127,54 @@ struct page_alloc {
 static struct kmem_cache *req_alloc_cache;
 static struct kmem_cache *page_alloc_cache;
 
+/**
+ * create_migrate_type_subdirs() - Creates a directory for each migrate type
+ * inside the order directory.
+ */
+static inline int create_migrate_type_subdirs(struct dentry *orderdir)
+{
+	struct dentry *migratedir;
+	char dirname[24];
+
+	for (int mtype = 0; mtype < MIGRATE_TYPES; mtype++) {
+#ifdef CONFIG_CMA
+		if (mtype == MIGRATE_CMA) /* CMA allocs are not supported yet*/
+			continue;
+#endif
+#ifdef CONFIG_MEMORY_ISOLATION
+		if (mtype == MIGRATE_ISOLATE) /* can't allocate from here */
+			continue;
+#endif
+		snprintf(dirname, sizeof(dirname), "migrate-%s",
+			 migratetype_names[mtype]);
+		migratedir = debugfs_create_dir(dirname, orderdir);
+		if (IS_ERR(migratedir))
+			return PTR_ERR(migratedir);
+	}
+
+	return 0;
+}
+
 /**
  * create_page_orders_subdirs() - Creates a directory for each page order inside
- * the zone directory.
+ * the zone directory. Once that the page order directory is created, it creates
+ * a directory for each migrate type.
  */
 static inline int create_page_orders_subdirs(struct dentry *zonedir)
 {
 	struct dentry *orderdir;
 	char dirname[12];
+	int ret;
 
 	for (int order = 0; order < NR_PAGE_ORDERS; order++) {
 		snprintf(dirname, sizeof(dirname), "order-%d", order);
 		orderdir = debugfs_create_dir(dirname, zonedir);
 		if (IS_ERR(orderdir))
 			return PTR_ERR(orderdir);
+
+		ret = create_migrate_type_subdirs(orderdir);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 08/16] mm: Define function that creates the "nr_pages_allocs" file
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (6 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 07/16] mm: Define function to create a dir for each migrate type Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 09/16] mm: Read the nr_pages_allocs value given by user Juan Yescas
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change implements the function that creates the
"nr_pages_allocs". This file will be used to make the allocations.

When the user wants to make an allocation, it will write
the number of allocations to this file. For example, if want
to make 56 allocations of order 9 in the Node 0, Normal Zone and Migrate
type Movable, we execute this command:

echo 56 > <sysfs>/mm/node-0/zone-Normal/order-9/migrate-Movable/nr_pages_allocs

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Update file permissions to 0200.
	- Free req_alloc.

 mm/page_alloc_hogger.c | 81 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 73 insertions(+), 8 deletions(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index ab39ea300704..ded3f0fc6641 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -127,14 +127,70 @@ struct page_alloc {
 static struct kmem_cache *req_alloc_cache;
 static struct kmem_cache *page_alloc_cache;
 
+/**
+ * req_page_alloc_write() - Allocates the pages on the requested node, zone,
+ * order and migrate type. Once the allocation is performed, a file is created
+ * to free the allocation later.
+ */
+static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
+				     size_t cnt, loff_t *ppos)
+{
+	return cnt;
+}
+
+static const struct file_operations req_page_alloc_fops = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.write = req_page_alloc_write,
+};
+
+/**
+ * create_nr_pages_allocs_file() - Creates the file "nr_pages_allocs".
+ *
+ * The "nr_pages_allocs" file will be used to write the number of allocations
+ * that will be performed. When the allocations are performed, a new file for
+ * each allocation will be created in @migratedir.
+ */
+static inline int create_nr_pages_allocs_file(struct dentry *migratedir,
+					      int nid, int zone_idx,
+					      int order, int mtype)
+{
+	struct req_alloc *req;
+	struct dentry *nr_pages;
+
+	req = kmem_cache_alloc(req_alloc_cache, GFP_KERNEL);
+	if (!req) {
+		pr_err("Failed to create nr_pages_allocs_info");
+		return -ENOMEM;
+	}
+
+	req->node_idx = nid;
+	req->zone_idx = zone_idx;
+	req->order = order;
+	req->migrate_type = mtype;
+	req->parentdir = migratedir;
+
+	nr_pages = debugfs_create_file("nr_pages_allocs", 0200, migratedir, req,
+				       &req_page_alloc_fops);
+	if (IS_ERR(nr_pages)) {
+		kmem_cache_free(req_alloc_cache, req);
+		return PTR_ERR(nr_pages);
+	}
+
+	return 0;
+}
+
 /**
  * create_migrate_type_subdirs() - Creates a directory for each migrate type
- * inside the order directory.
+ * inside the order directory. Once the migrate type directory is created, it
+ * creates the "nr_pages_allocs" file.
  */
-static inline int create_migrate_type_subdirs(struct dentry *orderdir)
+static inline int create_migrate_type_subdirs(struct dentry *orderdir, int nid,
+					int zone_idx, int order)
 {
 	struct dentry *migratedir;
 	char dirname[24];
+	int ret;
 
 	for (int mtype = 0; mtype < MIGRATE_TYPES; mtype++) {
 #ifdef CONFIG_CMA
@@ -150,6 +206,11 @@ static inline int create_migrate_type_subdirs(struct dentry *orderdir)
 		migratedir = debugfs_create_dir(dirname, orderdir);
 		if (IS_ERR(migratedir))
 			return PTR_ERR(migratedir);
+
+		ret = create_nr_pages_allocs_file(migratedir, nid, zone_idx,
+						order, mtype);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -160,7 +221,8 @@ static inline int create_migrate_type_subdirs(struct dentry *orderdir)
  * the zone directory. Once that the page order directory is created, it creates
  * a directory for each migrate type.
  */
-static inline int create_page_orders_subdirs(struct dentry *zonedir)
+static inline int create_page_orders_subdirs(struct dentry *zonedir, int nid,
+					int zone_idx)
 {
 	struct dentry *orderdir;
 	char dirname[12];
@@ -172,7 +234,8 @@ static inline int create_page_orders_subdirs(struct dentry *zonedir)
 		if (IS_ERR(orderdir))
 			return PTR_ERR(orderdir);
 
-		ret = create_migrate_type_subdirs(orderdir);
+		ret = create_migrate_type_subdirs(orderdir, nid, zone_idx,
+						order);
 		if (ret)
 			return ret;
 	}
@@ -189,15 +252,17 @@ static inline int create_page_orders_subdirs(struct dentry *zonedir)
  * is because they are not managed by the Buddy Allocator or CMA allocator.
  */
 static inline int create_zones_subdirs(struct dentry *nodedir,
-					struct pglist_data *pgdata)
+					struct pglist_data *pgdata, int nid)
 {
 	struct dentry *zonedir;
 	struct zone *zone;
 	struct zone *node_zones = pgdata->node_zones;
+	int zone_idx;
 	char dirname[24];
 	int ret;
 
-	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
+	for (zone = node_zones, zone_idx = 0; zone - node_zones < MAX_NR_ZONES;
+			++zone, ++zone_idx) {
 		if (!populated_zone(zone))
 			continue;
 
@@ -210,7 +275,7 @@ static inline int create_zones_subdirs(struct dentry *nodedir,
 		if (IS_ERR(zonedir))
 			return PTR_ERR(zonedir);
 
-		ret = create_page_orders_subdirs(zonedir);
+		ret = create_page_orders_subdirs(zonedir, nid, zone_idx);
 		if (ret)
 			return ret;
 	}
@@ -238,7 +303,7 @@ static inline int create_nodes_subdirs(struct dentry *mmdir)
 		if (IS_ERR(nodedir))
 			return PTR_ERR(nodedir);
 
-		ret = create_zones_subdirs(nodedir, pgdata);
+		ret = create_zones_subdirs(nodedir, pgdata, nid);
 		if (ret)
 			return ret;
 	}
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 09/16] mm: Read the nr_pages_allocs value given by user
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (7 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 08/16] mm: Define function that creates the "nr_pages_allocs" file Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 10/16] mm: Set the selected zone in gfp_t flags Juan Yescas
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change reads the nr_page_allocs value given by the user and
validates that is an unsigned long.

If the input is valid, it will allocate an array of nr_page_allocs
size. This array will store the allocation ids. These allocation ids
will be used to free the allocations.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Free allocs_ids.

 mm/page_alloc_hogger.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index ded3f0fc6641..9b1eaf3814e1 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -135,6 +135,21 @@ static struct kmem_cache *page_alloc_cache;
 static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 				     size_t cnt, loff_t *ppos)
 {
+	unsigned long nr_pages_allocs;
+	unsigned long *allocs_ids;
+	int ret;
+
+	ret = kstrtoul_from_user(ubuf, cnt, 10, &nr_pages_allocs);
+	if (ret)
+		return ret;
+
+	allocs_ids = kmalloc_array(nr_pages_allocs, sizeof(unsigned long),
+					GFP_KERNEL);
+	if (!allocs_ids)
+		return -ENOMEM;
+
+	kfree(allocs_ids);
+
 	return cnt;
 }
 
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 10/16] mm: Set the selected zone in gfp_t flags
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (8 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 09/16] mm: Read the nr_pages_allocs value given by user Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 11/16] mm: Sets the migrate type " Juan Yescas
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change sets the selected zone in gfp_t flags.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Use static for the set_zone_to_alloc_from function.

 mm/page_alloc_hogger.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 9b1eaf3814e1..0e9ac43e9868 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -127,6 +127,34 @@ struct page_alloc {
 static struct kmem_cache *req_alloc_cache;
 static struct kmem_cache *page_alloc_cache;
 
+static inline void set_zone_to_alloc_from(int zone_idx, gfp_t *flags_ptr)
+{
+	switch (zone_idx) {
+#ifdef CONFIG_ZONE_DMA
+	case ZONE_DMA:
+		*flags_ptr |= __GFP_DMA;
+		break;
+#endif
+#ifdef CONFIG_ZONE_DMA32
+	case ZONE_DMA32:
+		*flags_ptr |= __GFP_DMA32;
+		break;
+#endif
+#ifdef CONFIG_HIGHMEM
+	case ZONE_HIGHMEM:
+		*flags_ptr |= __GFP_HIGHMEM;
+		break;
+#endif
+	case ZONE_MOVABLE:
+		*flags_ptr |= __GFP_MOVABLE;
+		break;
+	case ZONE_NORMAL:
+	default:
+		*flags_ptr |= 0;
+		break;
+	}
+}
+
 /**
  * req_page_alloc_write() - Allocates the pages on the requested node, zone,
  * order and migrate type. Once the allocation is performed, a file is created
@@ -135,8 +163,10 @@ static struct kmem_cache *page_alloc_cache;
 static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 				     size_t cnt, loff_t *ppos)
 {
+	struct req_alloc *req = file->private_data;
 	unsigned long nr_pages_allocs;
 	unsigned long *allocs_ids;
+	gfp_t flags = 0;
 	int ret;
 
 	ret = kstrtoul_from_user(ubuf, cnt, 10, &nr_pages_allocs);
@@ -148,6 +178,8 @@ static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 	if (!allocs_ids)
 		return -ENOMEM;
 
+	set_zone_to_alloc_from(req->zone_idx, &flags);
+
 	kfree(allocs_ids);
 
 	return cnt;
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 11/16] mm: Sets the migrate type in gfp_t flags
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (9 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 10/16] mm: Set the selected zone in gfp_t flags Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 12/16] mm: Define the make_alloc() function Juan Yescas
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change sets the selected migrate type in gfp_t flags.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Make sure that ZONE_MOVABLE is only used by MIGRATE_MOVABLE requests.

 mm/page_alloc_hogger.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 0e9ac43e9868..4b72acfbc087 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -155,6 +155,24 @@ static inline void set_zone_to_alloc_from(int zone_idx, gfp_t *flags_ptr)
 	}
 }
 
+static inline void set_migrate_type_to_alloc_from(int migrate_type, gfp_t *flags_ptr)
+{
+	switch (migrate_type) {
+	case MIGRATE_UNMOVABLE:
+		*flags_ptr &= ~(__GFP_RECLAIMABLE | __GFP_MOVABLE);
+		break;
+	case MIGRATE_RECLAIMABLE:
+		*flags_ptr |= __GFP_RECLAIMABLE;
+		break;
+	case MIGRATE_HIGHATOMIC:
+		*flags_ptr |= __GFP_HIGH;
+		break;
+	case MIGRATE_MOVABLE: default:
+		*flags_ptr |= __GFP_MOVABLE;
+		break;
+	}
+}
+
 /**
  * req_page_alloc_write() - Allocates the pages on the requested node, zone,
  * order and migrate type. Once the allocation is performed, a file is created
@@ -179,6 +197,7 @@ static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 		return -ENOMEM;
 
 	set_zone_to_alloc_from(req->zone_idx, &flags);
+	set_migrate_type_to_alloc_from(req->migrate_type, &flags);
 
 	kfree(allocs_ids);
 
@@ -248,6 +267,9 @@ static inline int create_migrate_type_subdirs(struct dentry *orderdir, int nid,
 		if (mtype == MIGRATE_ISOLATE) /* can't allocate from here */
 			continue;
 #endif
+		if (zone_idx == ZONE_MOVABLE && mtype != MIGRATE_MOVABLE)
+			continue;
+
 		snprintf(dirname, sizeof(dirname), "migrate-%s",
 			 migratetype_names[mtype]);
 		migratedir = debugfs_create_dir(dirname, orderdir);
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 12/16] mm: Define the make_alloc() function
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (10 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 11/16] mm: Sets the migrate type " Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 13/16] mm: Create the file associated with an allocation Juan Yescas
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

The make_alloc() is the core function that performs the allocation.

The tasks of this function are:

- Call the Buddy allocator to make the allocation.
- Store the details of the allocation in struct page_alloc.
- Insert the struct page_alloc in an xarray using the allocation id
as key.

If something fails during the allocation, the pages and cache
will be freed.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Once that page_alloc is initialized, insert it in xarray.
	- Use 20 characters for the file name instead of 12.
	- Fix use-after-free issue while releasing the pages.

 mm/page_alloc_hogger.c | 72 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 4b72acfbc087..e22247b7bd98 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -96,6 +96,18 @@
 
 static struct dentry *mmdir;
 
+/**
+ * atomic_long_t allocs_file_seq - Represents the naming sequence used for
+ * allocation files.
+ */
+static atomic_long_t allocs_file_seq = ATOMIC_INIT(0);
+
+/**
+ * allocs_xa - Represent the xarray that contains the actual allocations perform
+ * by this driver.
+ */
+static DEFINE_XARRAY(allocs_xa);
+
 /**
  * struct req_alloc - Represents the requested allocation
  * @node_idx: The Node index to allocate from.
@@ -173,6 +185,47 @@ static inline void set_migrate_type_to_alloc_from(int migrate_type, gfp_t *flags
 	}
 }
 
+static int make_alloc(struct req_alloc *req,
+			    gfp_t flags, unsigned long *alloc_id)
+{
+	struct page_alloc *pa;
+	struct page *page;
+	char new_alloc_name[20];
+	int ret;
+
+	page = alloc_pages_node_noprof(req->node_idx, flags, req->order);
+	if (page) {
+		pa = kmem_cache_alloc(page_alloc_cache, GFP_KERNEL);
+		if (!pa) {
+			ret = -ENOMEM;
+			goto free_pages;
+		}
+
+		*alloc_id = atomic_long_inc_return(&allocs_file_seq);
+		snprintf(new_alloc_name, sizeof(new_alloc_name), "%lu",
+			 *alloc_id);
+
+		pa->req_alloc = req;
+		pa->page = page;
+
+		ret = xa_insert(&allocs_xa, *alloc_id, pa, GFP_KERNEL);
+		if (ret)
+			goto free_page_alloc;
+	} else {
+		return -ENOMEM;
+	}
+
+	return 0;
+
+free_page_alloc:
+	kmem_cache_free(page_alloc_cache, pa);
+
+free_pages:
+	__free_pages(page, req->order);
+
+	return ret;
+}
+
 /**
  * req_page_alloc_write() - Allocates the pages on the requested node, zone,
  * order and migrate type. Once the allocation is performed, a file is created
@@ -182,10 +235,12 @@ static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 				     size_t cnt, loff_t *ppos)
 {
 	struct req_alloc *req = file->private_data;
+	unsigned long alloc_id;
 	unsigned long nr_pages_allocs;
 	unsigned long *allocs_ids;
 	gfp_t flags = 0;
 	int ret;
+	int i;
 
 	ret = kstrtoul_from_user(ubuf, cnt, 10, &nr_pages_allocs);
 	if (ret)
@@ -199,9 +254,26 @@ static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 	set_zone_to_alloc_from(req->zone_idx, &flags);
 	set_migrate_type_to_alloc_from(req->migrate_type, &flags);
 
+	for (i = 0; i < nr_pages_allocs; i++) {
+		ret = make_alloc(req, flags, &alloc_id);
+		if (ret)
+			goto free_allocs;
+
+		allocs_ids[i] = alloc_id;
+	}
+
 	kfree(allocs_ids);
 
 	return cnt;
+
+free_allocs:
+	/*
+	 * A proper clean up of the pages and page_alloc allocations will
+	 * be done in a follow up patch of this topic.
+	 */
+	kfree(allocs_ids);
+
+	return ret;
 }
 
 static const struct file_operations req_page_alloc_fops = {
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 13/16] mm: Create the file associated with an allocation
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (11 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 12/16] mm: Define the make_alloc() function Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 14/16] mm: Free pages, remove files and clean cache when one alloc fails Juan Yescas
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change creates the file associated with an allocation. The
name of the file will be given by incrementing the atomic
long "allocs_file_seq".

This file will be used to free the allocation when the user
requests it. The implementation will be included in a follow-up
patch of this topic.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Update commit message.
	- Set file permissions to 0400 instead of 0644.

 mm/page_alloc_hogger.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index e22247b7bd98..a70c924e4172 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -185,12 +185,26 @@ static inline void set_migrate_type_to_alloc_from(int migrate_type, gfp_t *flags
 	}
 }
 
+static ssize_t page_alloc_read(struct file *file, char __user *ubuf,
+				    size_t cnt, loff_t *ppos)
+{
+	/*  Which information should be print about the page or allocation? */
+	return 0;
+}
+
+static const struct file_operations page_alloc_fops = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.read = page_alloc_read,
+};
+
 static int make_alloc(struct req_alloc *req,
 			    gfp_t flags, unsigned long *alloc_id)
 {
 	struct page_alloc *pa;
 	struct page *page;
 	char new_alloc_name[20];
+	struct dentry *new_alloc_dentry;
 	int ret;
 
 	page = alloc_pages_node_noprof(req->node_idx, flags, req->order);
@@ -205,18 +219,30 @@ static int make_alloc(struct req_alloc *req,
 		snprintf(new_alloc_name, sizeof(new_alloc_name), "%lu",
 			 *alloc_id);
 
+		new_alloc_dentry = debugfs_create_file(
+			new_alloc_name, 0400, req->parentdir,
+			pa, &page_alloc_fops);
+		if (IS_ERR(new_alloc_dentry)) {
+			ret = PTR_ERR(new_alloc_dentry);
+			goto free_page_alloc;
+		}
+
 		pa->req_alloc = req;
 		pa->page = page;
+		pa->alloc_dentry = new_alloc_dentry;
 
 		ret = xa_insert(&allocs_xa, *alloc_id, pa, GFP_KERNEL);
 		if (ret)
-			goto free_page_alloc;
+			goto remove_alloc_dentry;
 	} else {
 		return -ENOMEM;
 	}
 
 	return 0;
 
+remove_alloc_dentry:
+	debugfs_remove(new_alloc_dentry);
+
 free_page_alloc:
 	kmem_cache_free(page_alloc_cache, pa);
 
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 14/16] mm: Free pages, remove files and clean cache when one alloc fails
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (12 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 13/16] mm: Create the file associated with an allocation Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 15/16] mm: Create the "free" file to release the previously allocated pages Juan Yescas
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

When one of the requested allocations failed, do

- free the pages that were previously allocated as part of the request.
- remove the files that were created as part of the request.
- clean the kmem cache.
- Erase the struct page_alloc objects from the xarray that were inserted
as part of the request.

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Remove comment about the future implementation.

 mm/page_alloc_hogger.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index a70c924e4172..ce53a17ac790 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -93,6 +93,7 @@
 #include <linux/nodemask.h>
 #include <linux/printk.h>
 #include <linux/slab.h>
+#include <linux/xarray.h>
 
 static struct dentry *mmdir;
 
@@ -252,6 +253,23 @@ static int make_alloc(struct req_alloc *req,
 	return ret;
 }
 
+static int free_alloc_helper(unsigned long alloc_id)
+{
+	struct page_alloc *pa;
+
+	pa = xa_erase(&allocs_xa, alloc_id);
+	if (!pa) {
+		pr_err("The alloc_id %lu was not found!", alloc_id);
+		return -EINVAL;
+	}
+
+	__free_pages(pa->page, pa->req_alloc->order);
+	debugfs_remove(pa->alloc_dentry);
+	kmem_cache_free(page_alloc_cache, pa);
+
+	return 0;
+}
+
 /**
  * req_page_alloc_write() - Allocates the pages on the requested node, zone,
  * order and migrate type. Once the allocation is performed, a file is created
@@ -293,10 +311,15 @@ static ssize_t req_page_alloc_write(struct file *file, const char __user *ubuf,
 	return cnt;
 
 free_allocs:
-	/*
-	 * A proper clean up of the pages and page_alloc allocations will
-	 * be done in a follow up patch of this topic.
-	 */
+	/* Free all the pages and resources previously allocated. */
+	for (int j = 0; j < i; j++) {
+		int ret2 = free_alloc_helper(allocs_ids[j]);
+
+		if (ret2)
+			pr_err("Unable to free pages associated with file %lu",
+			       allocs_ids[j]);
+	}
+
 	kfree(allocs_ids);
 
 	return ret;
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 15/16] mm: Create the "free" file to release the previously allocated pages
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (13 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 14/16] mm: Free pages, remove files and clean cache when one alloc fails Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  1:09 ` [RFC PATCH v2 16/16] mm: Release resources when the page alloc hogger module exits Juan Yescas
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

This change creates the "free" file and defines its file_operations
to release the previously allocated pages. To release an allocation,
the user will run:

echo <file name> > /sys/kernel/debug/mm/free

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Set the file permissions to 0200.

 mm/page_alloc_hogger.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index ce53a17ac790..6a6fbb78513a 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -83,6 +83,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/atomic.h>
 #include <linux/errno.h>
 #include <linux/debugfs.h>
 #include <linux/gfp.h>
@@ -331,6 +332,37 @@ static const struct file_operations req_page_alloc_fops = {
 	.write = req_page_alloc_write,
 };
 
+/**
+ * free_page_alloc_write() - free the previously allocated pages.
+ * @file: File where the user is writing.
+ * @ubuf: Contains the name of the file the user wants to delete and have the
+ *       memory associated with that file freed.
+ * @cnt: Size of @ubuf.
+ * @ppos: Current position in the file.
+ */
+static ssize_t free_page_alloc_write(struct file *file,
+				      const char __user *ubuf, size_t cnt,
+				      loff_t *ppos)
+{
+	int ret;
+	unsigned long alloc_id;
+
+	ret = kstrtoul_from_user(ubuf, cnt, 10, &alloc_id);
+	if (ret)
+		return ret;
+
+	ret = free_alloc_helper(alloc_id);
+	if (ret)
+		return ret;
+
+	return cnt;
+}
+
+static const struct file_operations free_page_alloc_fops = {
+	.owner = THIS_MODULE,
+	.write = free_page_alloc_write,
+};
+
 /**
  * create_nr_pages_allocs_file() - Creates the file "nr_pages_allocs".
  *
@@ -503,6 +535,7 @@ static inline int create_nodes_subdirs(struct dentry *mmdir)
 
 static int __init page_alloc_hogger_debugfs_init(void)
 {
+	struct dentry *free_file;
 	int ret;
 
 	req_alloc_cache = kmem_cache_create(
@@ -534,6 +567,13 @@ static int __init page_alloc_hogger_debugfs_init(void)
 	if (ret)
 		goto clean_dir;
 
+	free_file = debugfs_create_file("free", 0200, mmdir, NULL,
+					&free_page_alloc_fops);
+	if (IS_ERR(free_file)) {
+		ret = PTR_ERR(free_file);
+		goto clean_dir;
+	}
+
 	return 0;
 
 clean_dir:
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [RFC PATCH v2 16/16] mm: Release resources when the page alloc hogger module exits
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (14 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 15/16] mm: Create the "free" file to release the previously allocated pages Juan Yescas
@ 2026-08-06  1:09 ` Juan Yescas
  2026-08-06  5:22 ` [RFC PATCH v2 00/16] Page Alloc Hogger Andrew Morton
  2026-08-06  9:48 ` Lorenzo Stoakes (ARM)
  17 siblings, 0 replies; 20+ messages in thread
From: Juan Yescas @ 2026-08-06  1:09 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE
  Cc: jyescas, android-mm, ljs, fvdl, tkjos, minchan, dskiba, open list,
	open list:MEMORY MANAGEMENT - CORE

When the page alloc hogger module exits:

- free all the previously allocated pages
- Erase all the entries from the xarray

Signed-off-by: Juan Yescas <jyescas@google.com>
---

Changes in v2:
	- Refactor the exit method.
	- Release the page_alloc object.

 mm/page_alloc_hogger.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/mm/page_alloc_hogger.c b/mm/page_alloc_hogger.c
index 6a6fbb78513a..72c0505a6f5a 100644
--- a/mm/page_alloc_hogger.c
+++ b/mm/page_alloc_hogger.c
@@ -591,6 +591,12 @@ static int __init page_alloc_hogger_debugfs_init(void)
 
 static void __exit page_alloc_hogger_debugfs_exit(void)
 {
+	struct page_alloc *pa;
+	unsigned long idx;
+
+	xa_for_each(&allocs_xa, idx, pa)
+		free_alloc_helper(idx);
+
 	debugfs_remove_recursive(mmdir);
 	kmem_cache_destroy(req_alloc_cache);
 	kmem_cache_destroy(page_alloc_cache);
-- 
2.55.0.629.g250fe7f194-goog



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [RFC PATCH v2 00/16] Page Alloc Hogger
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (15 preceding siblings ...)
  2026-08-06  1:09 ` [RFC PATCH v2 16/16] mm: Release resources when the page alloc hogger module exits Juan Yescas
@ 2026-08-06  5:22 ` Andrew Morton
  2026-08-06  9:48 ` Lorenzo Stoakes (ARM)
  17 siblings, 0 replies; 20+ messages in thread
From: Andrew Morton @ 2026-08-06  5:22 UTC (permalink / raw)
  To: Juan Yescas
  Cc: David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	open list, open list:MEMORY MANAGEMENT - CORE, android-mm, ljs,
	fvdl, tkjos, minchan, dskiba

On Wed,  5 Aug 2026 18:09:01 -0700 Juan Yescas <jyescas@google.com> wrote:

> This patch series introduces the Page Alloc Hogger. The Page Alloc Hogger
> allows you to allocate memory pages from specific nodes, zones, migration
> types, and orders directly via debugfs. This provides key benefits for
> testing and debugging:

OK, so this is targeted at kernel developers.  And they may indeed find
it useful.  I see value in us developing a common way for developers to
apply well-targeted stress to MM.


Probably everyone has their own favorite memory stresstest suite.  Most
of these will be in userspace[*] but I see there is merit in doing it
in-kernel.  Any perspective you can add to this choice would be
interesting?


Some usage scenarioizing would help.  Is this being used within google?
If so, for what purpose and with what results?  Sell it to us - help
your audience understand what benefit it offers to them.


If this proposal has legs then we should Document/ it separately - that
big block comment in page_alloc_hogger.c will become unweildy.


One could consider plumbing this into selftests/ in some fashion, but I
wouldn't encourage that - longrunning torture tests aren't appropriate
for selftests, which are nice and snappy.  Perhaps a new
tools/testing/stresstests will one day appear.



> +obj-$(CONFIG_PAGEALLOC_HOGGER) += page_alloc_hogger.o

page_alloc or pagealloc.  Choose only one, lest you drive people crazy
for ever.



Sashiko went totally nuts.  Have fun with that ;) But I wouldn't do a
ton of work on this until you've heard positive noises from the MM team,
Guys, poke.  wdyt, is there potential here?

	https://sashiko.dev/#/patchset/20260806011048.517229-1-jyescas@google.com


[*] Back in the days when I was trying to get redhat ext3 and 2.5.x
    MM to do something other than lock up or crash, I wrote a userspace
    thing called "usemem".  In recent times I've seen people quoting
    usemem results and wondered "is that my thing".  So I looked it up.
    It is!  And it's now quite unrecognizable.

    Because, obviously, people found it useful and so they used it
    and added to it and added to it and more.

    And I expect the same will occur with "Page Alloc Hogger"
    (terrible name, btw.  How about "pagehog"?  "memhog"), if it is
    adopted.  People will use it and will add to it.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC PATCH v2 00/16] Page Alloc Hogger
  2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
                   ` (16 preceding siblings ...)
  2026-08-06  5:22 ` [RFC PATCH v2 00/16] Page Alloc Hogger Andrew Morton
@ 2026-08-06  9:48 ` Lorenzo Stoakes (ARM)
  2026-08-06 11:17   ` David Hildenbrand (Arm)
  17 siblings, 1 reply; 20+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-06  9:48 UTC (permalink / raw)
  To: Juan Yescas
  Cc: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE, android-mm, fvdl, tkjos,
	minchan, dskiba

Hi Juan,

While I think there's possibly value in people not re-implemented their own
allocation injector, I don't think there's value in having this be part of
core-mm.

I really don't want this to form part of any contract or to be blessed in
any way by core mm as it exposes internal implementation details and I
really want to avoid adding extra maintainer workload here.

I'd suggest keeping it as an out-of-tree module as David proposed
previously ([0]).

Alternatively, keeping it as part of tooling (e.g. in tools/testing) could
also work.

(This is no comment on how useful it might be for debugging or testing
scenarios :)

--
Cheers, Lorenzo

[0]:https://lore.kernel.org/all/97605949-82c5-49e0-84b6-b42e8078b55d@kernel.org/


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RFC PATCH v2 00/16] Page Alloc Hogger
  2026-08-06  9:48 ` Lorenzo Stoakes (ARM)
@ 2026-08-06 11:17   ` David Hildenbrand (Arm)
  0 siblings, 0 replies; 20+ messages in thread
From: David Hildenbrand (Arm) @ 2026-08-06 11:17 UTC (permalink / raw)
  To: Lorenzo Stoakes (ARM), Juan Yescas
  Cc: Andrew Morton, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
	Mike Rapoport, Suren Baghdasaryan, Michal Hocko, open list,
	open list:MEMORY MANAGEMENT - CORE, android-mm, fvdl, tkjos,
	minchan, dskiba

On 8/6/26 11:48, Lorenzo Stoakes (ARM) wrote:
> Hi Juan,
> 
> While I think there's possibly value in people not re-implemented their own
> allocation injector, I don't think there's value in having this be part of
> core-mm.
> 
> I really don't want this to form part of any contract or to be blessed in
> any way by core mm as it exposes internal implementation details and I
> really want to avoid adding extra maintainer workload here.
> 
> I'd suggest keeping it as an out-of-tree module as David proposed
> previously ([0]).
> 
> Alternatively, keeping it as part of tooling (e.g. in tools/testing) could
> also work.
Yes, I would prefer if all MM-related testing modules actually go somewhere in
tools/testing.

I commented on that recently when finding some of them in lib (and we also have
another GUP one at least in mm). Stuff that doesn't ultimately need to be there
should just be somewhere else.

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-08-06 11:17 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06  1:09 [RFC PATCH v2 00/16] Page Alloc Hogger Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 01/16] mm: Page Alloc Hogger module Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 02/16] mm: Define structs for allocation requests and store allocations Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 03/16] mm: Define the caches for the structs req_alloc and page_alloc Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 04/16] mm: Define function to create a dir for each online node Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 05/16] mm: Define function to create a dir for populated zone Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 06/16] mm: Define function to create a dir for each page order Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 07/16] mm: Define function to create a dir for each migrate type Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 08/16] mm: Define function that creates the "nr_pages_allocs" file Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 09/16] mm: Read the nr_pages_allocs value given by user Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 10/16] mm: Set the selected zone in gfp_t flags Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 11/16] mm: Sets the migrate type " Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 12/16] mm: Define the make_alloc() function Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 13/16] mm: Create the file associated with an allocation Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 14/16] mm: Free pages, remove files and clean cache when one alloc fails Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 15/16] mm: Create the "free" file to release the previously allocated pages Juan Yescas
2026-08-06  1:09 ` [RFC PATCH v2 16/16] mm: Release resources when the page alloc hogger module exits Juan Yescas
2026-08-06  5:22 ` [RFC PATCH v2 00/16] Page Alloc Hogger Andrew Morton
2026-08-06  9:48 ` Lorenzo Stoakes (ARM)
2026-08-06 11:17   ` David Hildenbrand (Arm)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).