Re: [RFC PATCH v2 00/16] Page Alloc Hogger
From: Juan Yescas
Date: Tue Aug 11 2026 - 14:13:40 EST
On Wed, Aug 5, 2026 at 10:22 PM Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> On Wed, 5 Aug 2026 18:09:01 -0700 Juan Yescas <jyescas@xxxxxxxxxx> 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?
>
Thanks for your comments and apologies for the delay in getting back
to you, I was gathering some examples.
I think some scenarios and tests are hard to reproduce using userspace
memory stresstests. For example memory fragmentation in one node or
fragmentation
in one zone, or fragmentation by migrate type. Testing memory fallbacks, etc.
This proposal makes these scenarios easy to reproduce.
>
> Some usage scenarioizing would help. Is this being used within google?
We are planning to add kselftests that create memory pressure in the system
and test that kswapd, oom, lmkd, compaction, etc., are called accordingly.
This tool will also be used to run benchmarks comparing 4KB vs 16kb
pagesizes under
various conditions (low memory, high memory fragmentation). Currently, in order
to create memory pressure, we modify the dts or set the mem kernel parameter to
reduce the available RAM and then cycle through apps for hours to get the
memory fragmented. With this tool, we can create memory pressure and memory
fragmentation pretty straightforward and then run the benchmarks under these
conditions.
> If so, for what purpose and with what results? Sell it to us - help
> your audience understand what benefit it offers to them.
>
That is a good point. Although this tool was written for devices using
less than 32 GBs
of memory, it could be used for servers. For example, if you want to
create memory
pressure in the different Nodes or zones in the server, you can easily
do it by running
# Alloc 500 GiB node 0 zone DMA
echo 128000 > /sys/kernel/debug/mm/node-0/zone-DMA/order-10/migrate-Reclaimable/nr_pages_allocs
# Alloc 1000 GiB node 1 zone Normal
echo 256000 > /sys/kernel/debug/mm/node-1/zone-Normal/order-10/migrate-Reclaimable/nr_pages_allocs
# Alloc 500 GiB node 2 zone Normal
echo 128000 > /sys/kernel/debug/mm/node-1/zone-Normal/order-10/migrate-Reclaimable/nr_pages_allocs
or you can run this script to allocate 500GiB across all nodes in the system:
for node in `set 0 16`; do echo 128000 >
/sys/kernel/debug/mm/node-$node/zone-Normal/order-10/migrate-Reclaimable/nr_pages_allocs;
done
When my team want to reproduce memory issues due to fragmentation, it is not
straightforward to set the memory into this state consistently with
our current tools.
Let's say that we are debugging an issue where we have enough memory
but the high
high-order allocations are failing due to memory fragmentation which
was caused by
pinned pages in the different page blocks of the zone. How could we
reproduce this fragmentation
artificially in Node 0/Zone Normal?
# 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 708
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 31
Node 0, zone DMA, type Isolate 0 0 0 0 0 0
0 0 0 0 0
Node 0, zone Normal, type Unmovable 492 445 301 31 6 3
1 0 1 1 0
Node 0, zone Normal, type Movable 387 366 357 345 341 341
329 303 291 278 559
Node 0, zone Normal, type Reclaimable 861 825 1516 1387 1176 832
473 371 361 226 10
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 1472 0 0
64 0
Node 0, zone Normal 20 1796 728 0
16 0
We could write a custom program that mmap/mlock enough memory, and then release
all pages except one in each page block. What if we want to fragment
also the zone DMA?
Using the driver proposed here, we could fragment the memory with this script:
# Allocate memory from Node 0/Zone Normal/Order 0/Migrate Reclaimable
echo 307200 > /sys/kernel/debug/mm/node-0/zone-Normal/order-0/migrate-Reclaimable/nr_pages_allocs
for i in `seq 1 307200`; do \
v=$(expr $i % 1024 != 0); \
# Release everything but one page from each page block
if [ $v = 1 ]; then echo $i > /sys/kernel/debug/mm/free; echo
"Releasing $i"; fi; \
done
# Allocate memory from Node 0/Zone Normal/Order 0/Migrate Movable
echo 307200 > /sys/kernel/debug/mm/node-0/zone-Normal/order-0/migrate-Movable/nr_pages_allocs
for i in `seq 307201 614400`; do \
v=$(expr $i % 1024 != 0); \
if [ $v = 1 ]; then echo $i > /sys/kernel/debug/mm/free; echo
"Releasing $i"; fi; \
done
After running the shell script, we have fragmented the memory;
# 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 708
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 31
Node 0, zone DMA, type Isolate 0 0 0 0 0 0
0 0 0 0 0
Node 0, zone Normal, type Unmovable 492 445 301 31 6 3
1 0 1 1 0
Node 0, zone Normal, type Movable 387 366 357 345 341 341
329 303 291 278 559
Node 0, zone Normal, type Reclaimable 861 825 1516 1387 1176 832
473 371 361 226 10
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 1472 0 0
64 0
Node 0, zone Normal 20 1796 728 0
16 0
If we want to do the same with Node 0/Zone DMA, we only execute:
echo 307200 > /sys/kernel/debug/mm/node-0/zone-DMA/order-0/migrate-Reclaimable/nr_pages_allocs
for i in `seq 614401 921600`; do \
v=$(expr $i % 1024 != 0); \
if [ $v = 1 ]; then echo $i > /sys/kernel/debug/mm/free; echo
"Releasing $i"; fi; \
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 406
Node 0, zone DMA, type Reclaimable 293 293 292 292 292 293
293 293 293 292 2
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 31
Node 0, zone DMA, type Isolate 0 0 0 0 0 0
0 0 0 0 0
Node 0, zone Normal, type Unmovable 566 377 261 33 7 3
1 0 1 1 1
Node 0, zone Normal, type Movable 290 352 344 336 330 329
321 301 296 279 559
Node 0, zone Normal, type Reclaimable 1109 1024 1928 1641 1168 521
498 374 361 226 9
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 868 604 0
64 0
Node 0, zone Normal 22 1796 726 0
16 0
As we can see, it is pretty straightforward to artificially reproduce
the fragmentation using
a script.
> If this proposal has legs then we should Document/ it separately - that
> big block comment in page_alloc_hogger.c will become unweildy.
>
I agree, I am happy to move it under Document/ if the tool is useful
for other kernel developers.
>
> 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.
>
Good point, I can do that. Thanks for pointing it out.
>
>
> 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@xxxxxxxxxx
>
>
> [*] 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.
>
I agree that the name is not good. I like "pagehog".
Thanks for taking the time to review it.
Greetings
Juan
>
>