On 10/9/2020 5:09 AM, Peter Zijlstra wrote:
(we might not need the #ifdef gunk, but I've not yet dug out my cross compilers this morning) --- --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -7009,6 +7009,7 @@ static u64 perf_virt_to_phys(u64 virt) */ static u64 __perf_get_page_size(struct mm_struct *mm, unsigned long addr) { + struct page *page; pgd_t *pgd; p4d_t *p4d; pud_t *pud; @@ -7030,15 +7031,27 @@ static u64 __perf_get_page_size(struct m if (!pud_present(*pud)) return 0;- if (pud_leaf(*pud))+ if (pud_leaf(*pud)) { +#ifdef pud_page + page = pud_page(*pud); + if (PageHuge(page)) + return page_size(compound_head(page));
I think the page_size() returns the Kernel Page Size of a compound page. What we want is the MMU page size. If it's for the generic code, I think it should be a problem for X86. Thanks, Kan
+#endif return 1ULL << PUD_SHIFT; + }pmd = pmd_offset(pud, addr);if (!pmd_present(*pmd)) return 0;- if (pmd_leaf(*pmd))+ if (pmd_leaf(*pmd)) { +#ifdef pmd_page + page = pmd_page(*pmd); + if (PageHuge(page)) + return page_size(compound_head(page)); +#endif return 1ULL << PMD_SHIFT; + }pte = pte_offset_map(pmd, addr);if (!pte_present(*pte)) { @@ -7046,6 +7059,10 @@ static u64 __perf_get_page_size(struct m return 0; }+ page = pte_page(*pte);+ if (PageHuge(page)) + return page_size(compound_head(page)); + pte_unmap(pte); return PAGE_SIZE; }

