Re: [PATCH RFC] arm64: show zero pfn information when using vtop

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023/05/01 1:16, Rongwei Wang wrote:
> Hello,
> 
> Recently I handle some stuff about zero page with crash. I'm always use 
> vtop to check
> 
> whether an virtual address has been set the zero page. But, it can not 
> directly show whether a page
> 
> is zero page or not. So I try to add this patch to support this.
> 
> And I'm not sure this idea is nice to be accepted, so just realize it on 
> arm64 platform. I can finish others
> 
> arch if it accepted.

Sorry for the delay, I had been on holidays last week.

I think this is a nice suggestion and would like to accept it also for 
other architectures.

> 
> 
> Thanks for your time.
> 
> On 2023/5/1 00:02, 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)
>>
>>        PTE        PHYSICAL   FLAGS
>> 160000836e71fc3  836e71000  
>> (VALID|USER|RDONLY|SHARED|AF|NG|PXN|UXN|SPECIAL)
>>
>>        VMA           START       END     FLAGS FILE
>> ffff000844f51860 ffff8917c000 ffff8957d000 100073
>>
>>        PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
>> fffffe001fbb9c40  836e71000                0        0  1 
>> 2ffffc000001000 reserved
>>
>> 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)
>>
>>       PTE        PHYSICAL   FLAGS
>> 60000910c00fc1  910c00000  (VALID|USER|RDONLY|SHARED|AF|NG|PXN|UXN)
>>
>>        VMA           START       END     FLAGS FILE
>> ffff0000caa711e0 ffff956a9000 ffff95aaa000 100073
>>
>>        PAGE         PHYSICAL      MAPPING       INDEX CNT FLAGS
>> fffffe0023230000  910c00000                0        0  1 
>> 6ffffc000010000 head
>>
>> That seems be sensible with this patch.
>>
>> Signed-off-by: Rongwei Wang <rongwei.wang@xxxxxxxxxxxxxxxxx>
>> ---
>>   arm64.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++------
>>   defs.h  |  5 ++++
>>   2 files changed, 88 insertions(+), 9 deletions(-)
>>
>> diff --git a/arm64.c b/arm64.c
>> index 56fb841..264572d 100644
>> --- a/arm64.c
>> +++ b/arm64.c
>> @@ -419,7 +419,25 @@ arm64_init(int when)
>>           /* use machdep parameters */
>>           arm64_calc_phys_offset();
>>           arm64_calc_physvirt_offset();
>> -
>> +
>> +        if (kernel_symbol_exists("zero_pfn")) {
>> +                ulong zero_pfn = 0;
>> +
>> +                if (readmem(symbol_value("zero_pfn"), KVADDR,
>> +                          &zero_pfn, sizeof(zero_pfn),
>> +                          "read zero_pfn", QUIET|RETURN_ON_ERROR))
>> +                    machdep->zero_pfn = zero_pfn;
>> +        }
>> +
>> +        if (kernel_symbol_exists("huge_zero_pfn")) {
>> +                ulong huge_zero_pfn = 0;
>> +
>> +                if (readmem(symbol_value("huge_zero_pfn"), KVADDR,
>> +                          &huge_zero_pfn, sizeof(huge_zero_pfn),
>> +                          "read huge_zero_pfn", QUIET|RETURN_ON_ERROR))
>> +                    machdep->huge_zero_pfn = huge_zero_pfn;
>> +        }

so, for other architectures, are you going to move these to vm_init() or 
somewhere?

And zero_paddr might be better than zero_pfn to reduce the calculation 
on printing, e.g. vt->zero_paddr = zero_pfn << PAGESHIFT().

>> +
>>           if (CRASHDEBUG(1)) {
>>               if (machdep->flags & NEW_VMEMMAP)
>>                   fprintf(fp, "kimage_voffset: %lx\n",
>> @@ -1787,7 +1805,14 @@ 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);
>> +            if (kernel_symbol_exists("huge_zero_pfn")) {
>> +                if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (512MB, ZERO PAGE)\n\n",
>> +                        HUGE_ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx  (512MB)\n\n", 
>> sectionbase);
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
>>               arm64_translate_pte(pgd_val, 0, 0);
>>           }
>>           *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
>> @@ -1806,7 +1831,14 @@ 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));
>> +            if (kernel_symbol_exists("zero_pfn")) {
>> +                if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
>> +                        ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));

These blocks look a bit verbose and it would be better to not call 
kernel_symbol_exists() each time, if possible.

Can it be changed to something like this?

   if (vt->zero_paddr && PAGEBASE(*paddr) == vt->zero_paddr) {

or this.

   fprintf(fp, "  PAGE: %lx  %s\n\n", PAGEBASE(*paddr),
           vt->zero_paddr && PAGEBASE(*paddr) == vt->zero_paddr ?
               "(ZERO PAGE)" : "");

Thanks,
Kazu

>>               arm64_translate_pte(pte_val, 0, 0);
>>           }
>>       } else {
>> @@ -1859,7 +1891,14 @@ 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);
>> +            if (kernel_symbol_exists("huge_zero_pfn")) {
>> +                if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (512MB, ZERO PAGE)\n\n",
>> +                        HUGE_ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx  (512MB)\n\n", 
>> sectionbase);
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx  (512MB)\n\n", sectionbase);
>>               arm64_translate_pte(pmd_val, 0, 0);
>>           }
>>           *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_512MB);
>> @@ -1878,7 +1917,14 @@ 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));
>> +            if (kernel_symbol_exists("zero_pfn")) {
>> +                if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
>> +                        ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>>               arm64_translate_pte(pte_val, 0, 0);
>>           }
>>       } else {
>> @@ -1940,7 +1986,14 @@ 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);
>> +            if (kernel_symbol_exists("huge_zero_pfn")) {
>> +                if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (2MB, ZERO PAGE)\n\n",
>> +                        HUGE_ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
>>               arm64_translate_pte(pmd_val, 0, 0);
>>           }
>>           *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
>> @@ -1959,7 +2012,14 @@ 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));
>> +            if (kernel_symbol_exists("zero_pfn")) {
>> +                if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
>> +                        ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>>               arm64_translate_pte(pte_val, 0, 0);
>>           }
>>       } else {
>> @@ -2029,7 +2089,14 @@ 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);
>> +            if (kernel_symbol_exists("huge_zero_pfn")) {
>> +                if (sectionbase == (HUGE_ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (2MB, ZERO PAGE)\n\n",
>> +                        HUGE_ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx  (2MB)\n\n", sectionbase);
>>               arm64_translate_pte(pmd_val, 0, 0);
>>           }
>>           *paddr = sectionbase + (vaddr & ~SECTION_PAGE_MASK_2MB);
>> @@ -2048,7 +2115,14 @@ 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));
>> +            if (kernel_symbol_exists("zero_pfn")) {
>> +                if (PAGEBASE(*paddr) == (ZEROPFN() << PAGESHIFT()))
>> +                    fprintf(fp, "  PAGE: %lx  (ZERO PAGE)\n\n",
>> +                        ZEROPFN() << PAGESHIFT());
>> +                else
>> +                    fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>> +            } else
>> +                fprintf(fp, "  PAGE: %lx\n\n", PAGEBASE(*paddr));
>>               arm64_translate_pte(pte_val, 0, 0);
>>           }
>>       } else {
>> diff --git a/defs.h b/defs.h
>> index 12ad6aa..4ed2d0a 100644
>> --- a/defs.h
>> +++ b/defs.h
>> @@ -1071,6 +1071,8 @@ struct machdep_table {
>>           void (*show_interrupts)(int, ulong *);
>>       int (*is_page_ptr)(ulong, physaddr_t *);
>>       int (*get_cpu_reg)(int, int, const char *, int, void *);
>> +    ulong zero_pfn;
>> +    ulong huge_zero_pfn;
>>   };
>>   /*
>> @@ -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 ZEROPFN()    (machdep->zero_pfn)
>> +#define HUGE_ZEROPFN()   (machdep->huge_zero_pfn)
>> +
>>   /*
>>    * Sparse memory stuff
>>    *  These must follow the definitions in the kernel mmzone.h
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux