Re: [RFC PATCH 00/16] Page Alloc Hogger

From: Juan Yescas

Date: Tue Jul 28 2026 - 21:03:39 EST


On Tue, Jul 28, 2026 at 12:29 PM David Hildenbrand (Arm)
<david@xxxxxxxxxx> wrote:
>
> On 7/23/26 09:47, Juan Yescas 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:
>
> Would it be feasible to carry this as an OOT debugging module? Would a lot of
> symbols be missing to achieve that?
>

Thanks David for the comment.

The only symbol that would be needed to have this module as OOT is
"migratetype_names".

However, although this module was originally designed to debug CMA
issues, it can be
easily used to debug issues in kswapd, direct reclaims, OOM killer,
etc. We could even
use this module to add kunit test cases.

Let's take for example this case. We want to allocate Unmovable memory and check
that the allocation came from Movable, as per the buddy allocator
fallback mechanism.
How can we do that in user space?

$ 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

// Allocate Unmovable memory (note that there are NO Unmovable pages,
so the allocation will fall back from Movable)
$ echo 1221 > /sys/kernel/debug/mm/node-0/zone-Normal/order-10/migrate-Unmovable/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 701
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 1 0 0
1 1 1 1 1 1 0 0
Node 0, zone Normal, type Movable 1 0 1
1 1 1 1 1 1 1 7
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 14 1458 0
0 64 0
Node 0, zone Normal 2440 102 2
0 16 0

// Now we want to test that Reclaimable memory allocations fall back
from ZONE_DMA and Migrate Movable

$ echo 600 > /sys/kernel/debug/mm/node-0/zone-Normal/order-10/migrate-Reclaimable/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 1 1 0 0 1 0
Node 0, zone DMA, type Movable 1 1 1
0 1 1 2 2 1 3 99
Node 0, zone DMA, type Reclaimable 1 0 0
1 0 0 1 0 1 1 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 1 0 0
1 1 1 1 1 1 0 0
Node 0, zone Normal, type Movable 0 0 0
1 0 0 1 0 1 0 7
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 16 254 1202
0 64 0
Node 0, zone Normal 2440 102 2
0 16 0

// Now, we want to free all the MIGRATE_UNMOVABLE allocations and
sleep 1 second for every
// allocation and see how the pages return to the MIGRATE_UNMOVABLE bucket:

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

// in another console

watch cat /proc/pagetypeinfo
2026-07-29 00:28:49

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 1 1 0 0 1 0
Node 0, zone DMA, type Movable 1 1 1
0 1 1 2 2 1 3 99
Node 0, zone DMA, type Reclaimable 1 0 0
1 0 0 1 0 1 1 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 1 0 0
1 1 1 1 1 1 0 698
Node 0, zone Normal, type Movable 1 0 0
1 0 0 0 0 1 0 7
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 16 254 1202
0 64 0
Node 0, zone Normal 2440 102 2
0 16 0

Achieving the same result in a user program is not as straightforward.

The Page Alloc Hogger gives us the flexibility to allocate from any
valid memory we desire.

As I mentioned before, it allows us to test/check/analyze/generate:

- kwapd triggers
- direct reclaims
- OOM killer
- generate page fragmentation using simple scripts instead of complex programs

Greetigns

Juan


> --
> Cheers,
>
> David