[Crash-utility] [PATCH v4] arm64/x86_64: show zero pfn information when using vtop
Rongwei Wang
rongwei.wang at linux.alibaba.com
Mon May 29 12:02:01 UTC 2023
Hi Kazu, lijiang
As lijiang mentioned in previous email, I add below comments into commit
part:
1. only supports displaying zero page for THP(except for 1G THP)
2. do not support for the hugetlb cases
And no changes in code.
-wrw
On 2023/5/29 19:55, Rongwei Wang wrote:
> Now vtop can not show us the page is zero pfn
> when PTE or PMD has attached ZERO PAGE. This
> patch supports show this information directly
> when using vtop, likes:
>
> crash> vtop -c 13674 ffff8917e000
> VIRTUAL PHYSICAL
> ffff8917e000 836e71000
>
> PAGE DIRECTORY: ffff000802f8d000
> PGD: ffff000802f8dff8 => 884e29003
> PUD: ffff000844e29ff0 => 884e93003
> PMD: ffff000844e93240 => 840413003
> PTE: ffff000800413bf0 => 160000836e71fc3
> PAGE: 836e71000 (ZERO PAGE)
> ...
>
> If huge page found:
>
> crash> vtop -c 14538 ffff95800000
> VIRTUAL PHYSICAL
> ffff95800000 910c00000
>
> PAGE DIRECTORY: ffff000801fa0000
> PGD: ffff000801fa0ff8 => 884f53003
> PUD: ffff000844f53ff0 => 8426cb003
> PMD: ffff0008026cb560 => 60000910c00fc1
> PAGE: 910c00000 (2MB, ZERO PAGE)
> ...
>
> That seems be sensible with this patch. And there
> are two points have to be noted for 'ZERO PAGE'
> label:
> 1. only supports displaying zero page for THP(except for 1G THP)
> 2. do not support for the hugetlb cases
>
> Signed-off-by: Rongwei Wang <rongwei.wang at linux.alibaba.com>
> ---
> arm64.c | 24 ++++++++++++++++--------
> defs.h | 5 +++++
> memory.c | 23 +++++++++++++++++++++++
> x86_64.c | 9 +++++----
> 4 files changed, 49 insertions(+), 12 deletions(-)
>
> diff --git a/arm64.c b/arm64.c
> index 56fb841..efbdccb 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -1787,7 +1787,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if ((pgd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
> ulong sectionbase = (pgd_val & SECTION_PAGE_MASK_512MB) & PHYS_MASK;
> if (verbose) {
> - fprintf(fp, " PAGE: %lx (512MB)\n\n", sectionbase);
> + fprintf(fp, " PAGE: %lx (512MB%s)\n\n", sectionbase,
> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
> arm64_translate_pte(pgd_val, 0, 0);
> }
> *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
> @@ -1806,7 +1807,8 @@ arm64_vtop_2level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if (pte_val & PTE_VALID) {
> *paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
> if (verbose) {
> - fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
> + fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
> arm64_translate_pte(pte_val, 0, 0);
> }
> } else {
> @@ -1859,7 +1861,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
> ulong sectionbase = PTE_TO_PHYS(pmd_val) & SECTION_PAGE_MASK_512MB;
> if (verbose) {
> - fprintf(fp, " PAGE: %lx (512MB)\n\n", sectionbase);
> + fprintf(fp, " PAGE: %lx (512MB%s)\n\n", sectionbase,
> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
> arm64_translate_pte(pmd_val, 0, 0);
> }
> *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
> @@ -1878,7 +1881,8 @@ arm64_vtop_3level_64k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if (pte_val & PTE_VALID) {
> *paddr = PTE_TO_PHYS(pte_val) + PAGEOFFSET(vaddr);
> if (verbose) {
> - fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
> + fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
> arm64_translate_pte(pte_val, 0, 0);
> }
> } else {
> @@ -1940,7 +1944,8 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
> ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
> if (verbose) {
> - fprintf(fp, " PAGE: %lx (2MB)\n\n", sectionbase);
> + fprintf(fp, " PAGE: %lx (2MB%s)\n\n", sectionbase,
> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
> arm64_translate_pte(pmd_val, 0, 0);
> }
> *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
> @@ -1959,7 +1964,8 @@ arm64_vtop_3level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if (pte_val & PTE_VALID) {
> *paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
> if (verbose) {
> - fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
> + fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
> arm64_translate_pte(pte_val, 0, 0);
> }
> } else {
> @@ -2029,7 +2035,8 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if ((pmd_val & PMD_TYPE_MASK) == PMD_TYPE_SECT) {
> ulong sectionbase = (pmd_val & SECTION_PAGE_MASK_2MB) & PHYS_MASK;
> if (verbose) {
> - fprintf(fp, " PAGE: %lx (2MB)\n\n", sectionbase);
> + fprintf(fp, " PAGE: %lx (2MB%s)\n\n", sectionbase,
> + IS_ZEROPAGE(sectionbase) ? ", ZERO PAGE" : "");
> arm64_translate_pte(pmd_val, 0, 0);
> }
> *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
> @@ -2048,7 +2055,8 @@ arm64_vtop_4level_4k(ulong pgd, ulong vaddr, physaddr_t *paddr, int verbose)
> if (pte_val & PTE_VALID) {
> *paddr = (PAGEBASE(pte_val) & PHYS_MASK) + PAGEOFFSET(vaddr);
> if (verbose) {
> - fprintf(fp, " PAGE: %lx\n\n", PAGEBASE(*paddr));
> + fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr),
> + IS_ZEROPAGE(PAGEBASE(*paddr)) ? "(ZERO PAGE)" : "");
> arm64_translate_pte(pte_val, 0, 0);
> }
> } else {
> diff --git a/defs.h b/defs.h
> index 12ad6aa..a6e4ef3 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2618,6 +2618,8 @@ struct vm_table { /* kernel VM-related data */
> char *name;
> } *pageflags_data;
> ulong max_mem_section_nr;
> + ulong zero_paddr;
> + ulong huge_zero_paddr;
> };
>
> #define NODES (0x1)
> @@ -2999,6 +3001,9 @@ struct load_module {
> #define VIRTPAGEBASE(X) (((ulong)(X)) & (ulong)machdep->pagemask)
> #define PHYSPAGEBASE(X) (((physaddr_t)(X)) & (physaddr_t)machdep->pagemask)
>
> +#define IS_ZEROPAGE(paddr) ((paddr) == vt->zero_paddr || \
> + (paddr) == vt->huge_zero_paddr)
> +
> /*
> * Sparse memory stuff
> * These must follow the definitions in the kernel mmzone.h
> diff --git a/memory.c b/memory.c
> index 0568f18..d791283 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1208,6 +1208,27 @@ vm_init(void)
> machdep->memory_size()));
> vt->paddr_prlen = strlen(buf);
>
> + vt->zero_paddr = ~0UL;
> + if (kernel_symbol_exists("zero_pfn")) {
> + ulong zero_pfn;
> +
> + if (readmem(symbol_value("zero_pfn"), KVADDR,
> + &zero_pfn, sizeof(zero_pfn),
> + "read zero_pfn", QUIET|RETURN_ON_ERROR))
> + vt->zero_paddr = zero_pfn << PAGESHIFT();
> + }
> +
> + vt->huge_zero_paddr = ~0UL;
> + if (kernel_symbol_exists("huge_zero_pfn")) {
> + ulong huge_zero_pfn;
> +
> + if (readmem(symbol_value("huge_zero_pfn"), KVADDR,
> + &huge_zero_pfn, sizeof(huge_zero_pfn),
> + "read huge_zero_pfn", QUIET|RETURN_ON_ERROR) &&
> + huge_zero_pfn != ~0UL)
> + vt->huge_zero_paddr = huge_zero_pfn << PAGESHIFT();
> + }
> +
> if (vt->flags & PERCPU_KMALLOC_V1)
> vt->dump_kmem_cache = dump_kmem_cache_percpu_v1;
> else if (vt->flags & PERCPU_KMALLOC_V2)
> @@ -14063,6 +14084,8 @@ dump_vm_table(int verbose)
> } else {
> fprintf(fp, " node_online_map: (unused)\n");
> }
> + fprintf(fp, " zero_paddr: %lx\n", vt->zero_paddr);
> + fprintf(fp, " huge_zero_paddr: %lx\n", vt->huge_zero_paddr);
> fprintf(fp, " nr_vm_stat_items: %d\n", vt->nr_vm_stat_items);
> fprintf(fp, " vm_stat_items: %s", (vt->flags & VM_STAT) ?
> "\n" : "(not used)\n");
> diff --git a/x86_64.c b/x86_64.c
> index 5019c69..693a08b 100644
> --- a/x86_64.c
> +++ b/x86_64.c
> @@ -2114,8 +2114,9 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
> goto no_upage;
> if (pmd_pte & _PAGE_PSE) {
> if (verbose) {
> - fprintf(fp, " PAGE: %lx (2MB)\n\n",
> - PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK);
> + fprintf(fp, " PAGE: %lx (2MB%s)\n\n",
> + PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK,
> + IS_ZEROPAGE(PAGEBASE(pmd_pte) & PHYSICAL_PAGE_MASK) ? ", ZERO PAGE" : "");
> x86_64_translate_pte(pmd_pte, 0, 0);
> }
>
> @@ -2143,8 +2144,8 @@ x86_64_uvtop_level4(struct task_context *tc, ulong uvaddr, physaddr_t *paddr, in
> *paddr = (PAGEBASE(pte) & PHYSICAL_PAGE_MASK) + PAGEOFFSET(uvaddr);
>
> if (verbose) {
> - fprintf(fp, " PAGE: %lx\n\n",
> - PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK);
> + fprintf(fp, " PAGE: %lx %s\n\n", PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK,
> + IS_ZEROPAGE(PAGEBASE(*paddr) & PHYSICAL_PAGE_MASK) ? "(ZERO PAGE)" : "");
> x86_64_translate_pte(pte, 0, 0);
> }
>
More information about the Crash-utility
mailing list