transparent hugepage

@see Documentation/vm/transhuge.txt

怎么判断kernel确实给我们分配了一大块内存?

1. 修改build-initrd-img-busybox-dyn.sh把测试程序copy到initrd img里
2. bochs启动到busybox的shell里
3. bochs gui debugger里设breakpoint,查Sysmap可知do_execve的地址. b 0x1166000
4. 在busybox的shell里运行测试程序,当执行到 do_execve(char *filename, char *argv, char *envp, pt_regs) 时会break住,查看%rdi的内容可确定是在执行测试程序.
5. 再设breakpoint,查Sysmap可知vfs_write的地址. b 0x115f130
6. vfs_write(struct file *file, char *buf, size_t count, loff_t *pos), 查看%rsi的内容可确定执行到正确的位置.
7. 从%cr3里得到当前的pgd,运行 tools/calc-pgt addr 得到page table的情况,一路查下去pgd->pud->pmd->pte可知当前page table entry还没有,此时仅仅是在进程的process address space里做了标记而已.
8. 继续执行,再次break到vfs_write.同样查看%rsi的内容可确定执行到正确的位置.再查看page table, entry已经有了.

结论1

cat /sys/kernel/mm/transparent_hugepage/enabled
always [madvise] never
1. 简单的mmap不会分配大块内存,还是4K,4K的分配的
2. 使用posix_memalign也一样,还是4K,4K分配的
3. mmap后计算出对齐到2M的内存地址及余下的整2M的空间,调用 madvise(addr_aligned, length, MADV_HUGEPAGE),kernel此时会分配大块内存(2M)
4. 使用posix_memalign拿到一个对齐到2M的地址,再调用madvise,此时kernel会分配大块内存(2M)
5. 使用posix_memalign拿到一个对齐到1G的地址,再调用madvise,此时kernel依旧分配2M大小的内存,而不会分配1G的. (要想测试这种情况,.bochsrc要调整一下 memory: guest=20480, host=2048, bochs限制host_size最大2048,没有找到在哪里能调整)
6. mmap后直接调用madvise,不计算对齐后的地址,然后当使用这块内存时,刚开始的前边一小部分是4K,4K分配的,后边对齐到2M后就是2M,2M分配的了.果真是transparent hugepage.

结论2

cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
always的情况下,简单的mmap后,如果使用到的内存地址对齐到了2M上,那么kernel就真的分配2M的内存.不需要程序里额外做什么.
显然如果使用posix_memalign(),那么申请的内存当使用时都是2M,2M分配的.