newly plugged memory is marked as prot_sethuge via phys_pmd_init without setting PG_head. During memory unplug, free_hugepage_table frees the page table as 2M, but pagetable_free handles it as 4K. The following test case of memory unplug for a VM [1], tested in the environment [2], show that results. +-----------------------+------+------+ |Check System Memory |Plug |Unplug| |via free -h |256GB |256GB | +-----------------------+------+------+ | Free 4K page table |257GB |5.6GB | +-----------------------+------+------+ | Free 2M page table |257GB |1.7GB | +-----------------------+------+------+ [1] Qemu commands to unhotplug 256G memory for a VM: object_add memory-backend-ram,id=hotmem0,size=256G,share=on device_add virtio-mem-pci,id=vmem1,memdev=hotmem0,bus=port1 qom-set vmem1 requested-size 256G (Plug Memory) qom-set vmem1 requested-size 0G (Unplug Memory) [2] Hardware : Intel Icelake server Guest Kernel : v6.19-rc1 Qemu : v9.0.0 Launch VM: qemu-system-x86_64 -accel kvm -cpu host \ -drive file=./Centos10_cloud.qcow2,format=qcow2,if=virtio \ -drive file=./seed.img,format=raw,if=virtio \ -smp 3,cores=3,threads=1,sockets=1,maxcpus=3 \ -m 2G,slots=10,maxmem=2052472M \ -device pcie-root-port,id=port1,bus=pcie.0,slot=1,multifunction=on \ -device pcie-root-port,id=port2,bus=pcie.0,slot=2 \ -nographic -machine q35 \ -nic user,hostfwd=tcp::3000-:22 Guest kernel auto-onlines newly added memory blocks: echo online > /sys/devices/system/memory/auto_online_blocks Signed-off-by: Yuan Liu --- arch/x86/mm/init_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 9983017ecbe0..1044aafd5d94 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -1028,7 +1028,7 @@ static void __meminit free_pagetable(struct page *page, int order) free_reserved_pages(page, nr_pages); #endif } else { - pagetable_free(page_ptdesc(page)); + __free_pages(page, order); } } -- 2.47.3