powerpc/thp: Add tracepoints to track hugepage invalidate
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Wed, 13 Aug 2014 07:02:04 +0000 (12:32 +0530)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 13 Aug 2014 08:20:42 +0000 (18:20 +1000)
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>
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/tlb_hash64.c
include/trace/events/thp.h [new file with mode: 0644]

index 948a81e02ddb0194bbe5bade985adf6f9cfdf040..c8d709ab489d0ab5714fc35f0e7be2d542e2e472 100644 (file)
@@ -54,6 +54,9 @@
 
 #include "mmu_decl.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/thp.h>
+
 /* Some sanity checking */
 #if TASK_SIZE_USER64 > PGTABLE_RANGE
 #error TASK_SIZE_USER64 exceeds pagetable range
@@ -537,6 +540,7 @@ unsigned long pmd_hugepage_update(struct mm_struct *mm, unsigned long addr,
        old = pmd_val(*pmdp);
        *pmdp = __pmd((old & ~clr) | set);
 #endif
+       trace_hugepage_update(addr, old, clr, set);
        if (old & _PAGE_HASHPTE)
                hpte_do_hugepage_flush(mm, addr, pmdp, old);
        return old;
@@ -642,6 +646,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma,
         * If we didn't had the splitting flag set, go and flush the
         * HPTE entries.
         */
+       trace_hugepage_splitting(address, old);
        if (!(old & _PAGE_SPLITTING)) {
                /* We need to flush the hpte */
                if (old & _PAGE_HASHPTE)
@@ -709,6 +714,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
        assert_spin_locked(&mm->page_table_lock);
        WARN_ON(!pmd_trans_huge(pmd));
 #endif
+       trace_hugepage_set_pmd(addr, pmd);
        return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd));
 }
 
index 9adda5790463acb4dd82005459efe9abfe2c082e..d2a94b85dbc2453ef2d4aa525dff05e7c6e7237c 100644 (file)
@@ -30,6 +30,8 @@
 #include <asm/tlb.h>
 #include <asm/bug.h>
 
+#include <trace/events/thp.h>
+
 DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
 
 /*
@@ -213,6 +215,8 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
                if (ptep == NULL)
                        continue;
                pte = pte_val(*ptep);
+               if (hugepage_shift)
+                       trace_hugepage_invalidate(start, pte_val(pte));
                if (!(pte & _PAGE_HASHPTE))
                        continue;
                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 (file)
index 0000000..b59b065
--- /dev/null
@@ -0,0 +1,88 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM thp
+
+#if !defined(_TRACE_THP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_THP_H
+
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(hugepage_invalidate,
+
+           TP_PROTO(unsigned long addr, unsigned long pte),
+           TP_ARGS(addr, pte),
+           TP_STRUCT__entry(
+                   __field(unsigned long, addr)
+                   __field(unsigned long, pte)
+                   ),
+
+           TP_fast_assign(
+                   __entry->addr = addr;
+                   __entry->pte = pte;
+                   ),
+
+           TP_printk("hugepage invalidate at addr 0x%lx and pte = 0x%lx",
+                     __entry->addr, __entry->pte)
+);
+
+TRACE_EVENT(hugepage_set_pmd,
+
+           TP_PROTO(unsigned long addr, unsigned long pmd),
+           TP_ARGS(addr, pmd),
+           TP_STRUCT__entry(
+                   __field(unsigned long, addr)
+                   __field(unsigned long, pmd)
+                   ),
+
+           TP_fast_assign(
+                   __entry->addr = addr;
+                   __entry->pmd = pmd;
+                   ),
+
+           TP_printk("Set pmd with 0x%lx with 0x%lx", __entry->addr, __entry->pmd)
+);
+
+
+TRACE_EVENT(hugepage_update,
+
+           TP_PROTO(unsigned long addr, unsigned long pte, unsigned long clr, unsigned long set),
+           TP_ARGS(addr, pte, clr, set),
+           TP_STRUCT__entry(
+                   __field(unsigned long, addr)
+                   __field(unsigned long, pte)
+                   __field(unsigned long, clr)
+                   __field(unsigned long, set)
+                   ),
+
+           TP_fast_assign(
+                   __entry->addr = addr;
+                   __entry->pte = pte;
+                   __entry->clr = clr;
+                   __entry->set = set;
+
+                   ),
+
+           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)
+);
+TRACE_EVENT(hugepage_splitting,
+
+           TP_PROTO(unsigned long addr, unsigned long pte),
+           TP_ARGS(addr, pte),
+           TP_STRUCT__entry(
+                   __field(unsigned long, addr)
+                   __field(unsigned long, pte)
+                   ),
+
+           TP_fast_assign(
+                   __entry->addr = addr;
+                   __entry->pte = pte;
+                   ),
+
+           TP_printk("hugepage splitting at addr 0x%lx and pte = 0x%lx",
+                     __entry->addr, __entry->pte)
+);
+
+#endif /* _TRACE_THP_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>