diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2014-08-13 03:02:04 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-08-13 04:20:42 -0400 |
commit | 9e813308a5c18c58f9ccae1ec72ed4e14eaf9025 (patch) | |
tree | 3e72135c0e403930b809112552e059deaa7e5c11 | |
parent | 85c1fafd7262e68ad821ee1808686b1392b1167d (diff) |
powerpc/thp: Add tracepoints to track hugepage invalidate
Add tracepoint to track hugepage invalidate. This help us
in debugging difficult to track bugs.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/mm/pgtable_64.c | 6 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_hash64.c | 4 | ||||
-rw-r--r-- | include/trace/events/thp.h | 88 |
3 files changed, 98 insertions, 0 deletions
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 948a81e02ddb..c8d709ab489d 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c | |||
@@ -54,6 +54,9 @@ | |||
54 | 54 | ||
55 | #include "mmu_decl.h" | 55 | #include "mmu_decl.h" |
56 | 56 | ||
57 | #define CREATE_TRACE_POINTS | ||
58 | #include <trace/events/thp.h> | ||
59 | |||
57 | /* Some sanity checking */ | 60 | /* Some sanity checking */ |
58 | #if TASK_SIZE_USER64 > PGTABLE_RANGE | 61 | #if TASK_SIZE_USER64 > PGTABLE_RANGE |
59 | #error TASK_SIZE_USER64 exceeds pagetable range | 62 | #error TASK_SIZE_USER64 exceeds pagetable range |
@@ -537,6 +540,7 @@ unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, | |||
537 | old = pmd_val(*pmdp); | 540 | old = pmd_val(*pmdp); |
538 | *pmdp = __pmd((old & ~clr) | set); | 541 | *pmdp = __pmd((old & ~clr) | set); |
539 | #endif | 542 | #endif |
543 | trace_hugepage_update(addr, old, clr, set); | ||
540 | if (old & _PAGE_HASHPTE) | 544 | if (old & _PAGE_HASHPTE) |
541 | hpte_do_hugepage_flush(mm, addr, pmdp, old); | 545 | hpte_do_hugepage_flush(mm, addr, pmdp, old); |
542 | return old; | 546 | return old; |
@@ -642,6 +646,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, | |||
642 | * If we didn't had the splitting flag set, go and flush the | 646 | * If we didn't had the splitting flag set, go and flush the |
643 | * HPTE entries. | 647 | * HPTE entries. |
644 | */ | 648 | */ |
649 | trace_hugepage_splitting(address, old); | ||
645 | if (!(old & _PAGE_SPLITTING)) { | 650 | if (!(old & _PAGE_SPLITTING)) { |
646 | /* We need to flush the hpte */ | 651 | /* We need to flush the hpte */ |
647 | if (old & _PAGE_HASHPTE) | 652 | if (old & _PAGE_HASHPTE) |
@@ -709,6 +714,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
709 | assert_spin_locked(&mm->page_table_lock); | 714 | assert_spin_locked(&mm->page_table_lock); |
710 | WARN_ON(!pmd_trans_huge(pmd)); | 715 | WARN_ON(!pmd_trans_huge(pmd)); |
711 | #endif | 716 | #endif |
717 | trace_hugepage_set_pmd(addr, pmd); | ||
712 | return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); | 718 | return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); |
713 | } | 719 | } |
714 | 720 | ||
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c index 9adda5790463..d2a94b85dbc2 100644 --- a/arch/powerpc/mm/tlb_hash64.c +++ b/arch/powerpc/mm/tlb_hash64.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <asm/tlb.h> | 30 | #include <asm/tlb.h> |
31 | #include <asm/bug.h> | 31 | #include <asm/bug.h> |
32 | 32 | ||
33 | #include <trace/events/thp.h> | ||
34 | |||
33 | DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); | 35 | DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); |
34 | 36 | ||
35 | /* | 37 | /* |
@@ -213,6 +215,8 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, | |||
213 | if (ptep == NULL) | 215 | if (ptep == NULL) |
214 | continue; | 216 | continue; |
215 | pte = pte_val(*ptep); | 217 | pte = pte_val(*ptep); |
218 | if (hugepage_shift) | ||
219 | trace_hugepage_invalidate(start, pte_val(pte)); | ||
216 | if (!(pte & _PAGE_HASHPTE)) | 220 | if (!(pte & _PAGE_HASHPTE)) |
217 | continue; | 221 | continue; |
218 | if (unlikely(hugepage_shift && pmd_trans_huge(*(pmd_t *)pte))) | 222 | if (unlikely(hugepage_shift && pmd_trans_huge(*(pmd_t *)pte))) |
diff --git a/include/trace/events/thp.h b/include/trace/events/thp.h new file mode 100644 index 000000000000..b59b065e9e5d --- /dev/null +++ b/include/trace/events/thp.h | |||
@@ -0,0 +1,88 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM thp | ||
3 | |||
4 | #if !defined(_TRACE_THP_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_THP_H | ||
6 | |||
7 | #include <linux/types.h> | ||
8 | #include <linux/tracepoint.h> | ||
9 | |||
10 | TRACE_EVENT(hugepage_invalidate, | ||
11 | |||
12 | TP_PROTO(unsigned long addr, unsigned long pte), | ||
13 | TP_ARGS(addr, pte), | ||
14 | TP_STRUCT__entry( | ||
15 | __field(unsigned long, addr) | ||
16 | __field(unsigned long, pte) | ||
17 | ), | ||
18 | |||
19 | TP_fast_assign( | ||
20 | __entry->addr = addr; | ||
21 | __entry->pte = pte; | ||
22 | ), | ||
23 | |||
24 | TP_printk("hugepage invalidate at addr 0x%lx and pte = 0x%lx", | ||
25 | __entry->addr, __entry->pte) | ||
26 | ); | ||
27 | |||
28 | TRACE_EVENT(hugepage_set_pmd, | ||
29 | |||
30 | TP_PROTO(unsigned long addr, unsigned long pmd), | ||
31 | TP_ARGS(addr, pmd), | ||
32 | TP_STRUCT__entry( | ||
33 | __field(unsigned long, addr) | ||
34 | __field(unsigned long, pmd) | ||
35 | ), | ||
36 | |||
37 | TP_fast_assign( | ||
38 | __entry->addr = addr; | ||
39 | __entry->pmd = pmd; | ||
40 | ), | ||
41 | |||
42 | TP_printk("Set pmd with 0x%lx with 0x%lx", __entry->addr, __entry->pmd) | ||
43 | ); | ||
44 | |||
45 | |||
46 | TRACE_EVENT(hugepage_update, | ||
47 | |||
48 | TP_PROTO(unsigned long addr, unsigned long pte, unsigned long clr, unsigned long set), | ||
49 | TP_ARGS(addr, pte, clr, set), | ||
50 | TP_STRUCT__entry( | ||
51 | __field(unsigned long, addr) | ||
52 | __field(unsigned long, pte) | ||
53 | __field(unsigned long, clr) | ||
54 | __field(unsigned long, set) | ||
55 | ), | ||
56 | |||
57 | TP_fast_assign( | ||
58 | __entry->addr = addr; | ||
59 | __entry->pte = pte; | ||
60 | __entry->clr = clr; | ||
61 | __entry->set = set; | ||
62 | |||
63 | ), | ||
64 | |||
65 | TP_printk("hugepage update at addr 0x%lx and pte = 0x%lx clr = 0x%lx, set = 0x%lx", __entry->addr, __entry->pte, __entry->clr, __entry->set) | ||
66 | ); | ||
67 | TRACE_EVENT(hugepage_splitting, | ||
68 | |||
69 | TP_PROTO(unsigned long addr, unsigned long pte), | ||
70 | TP_ARGS(addr, pte), | ||
71 | TP_STRUCT__entry( | ||
72 | __field(unsigned long, addr) | ||
73 | __field(unsigned long, pte) | ||
74 | ), | ||
75 | |||
76 | TP_fast_assign( | ||
77 | __entry->addr = addr; | ||
78 | __entry->pte = pte; | ||
79 | ), | ||
80 | |||
81 | TP_printk("hugepage splitting at addr 0x%lx and pte = 0x%lx", | ||
82 | __entry->addr, __entry->pte) | ||
83 | ); | ||
84 | |||
85 | #endif /* _TRACE_THP_H */ | ||
86 | |||
87 | /* This part must be outside protection */ | ||
88 | #include <trace/define_trace.h> | ||