From: Liu Shixin liushixin2@huawei.com
hulk inclusion category: feature bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I4QSHG CVE: NA
--------------------------------
Add tracepoints for dynamic_hugetlb to track the process of page split, page merge, page migration, page allocation and page free.
Signed-off-by: Liu Shixin liushixin2@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/trace/events/dynamic_hugetlb.h | 121 +++++++++++++++++++++++++ mm/dynamic_hugetlb.c | 22 ++++- 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 include/trace/events/dynamic_hugetlb.h
diff --git a/include/trace/events/dynamic_hugetlb.h b/include/trace/events/dynamic_hugetlb.h new file mode 100644 index 000000000000..1de0df5df793 --- /dev/null +++ b/include/trace/events/dynamic_hugetlb.h @@ -0,0 +1,121 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM dynamic_hugetlb + +#if !defined(_TRACE_DHUGETLB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_DHUGETLB_H + +#include <linux/tracepoint.h> +#include <trace/events/mmflags.h> + +#define DHUGETLB_SPLIT 0x01u +#define DHUGETLB_MERGE 0x02u +#define DHUGETLB_MIGRATE 0x04u +#define DHUGETLB_RESV 0x08u +#define DHUGETLB_UNRESV 0x10u +#define DHUGETLB_ALLOC 0x20u +#define DHUGETLB_FREE 0x40u + +#define __def_action_names \ + {(unsigned long)DHUGETLB_SPLIT, "split page"}, \ + {(unsigned long)DHUGETLB_MERGE, "merge page"}, \ + {(unsigned long)DHUGETLB_MIGRATE, "migrate page"}, \ + {(unsigned long)DHUGETLB_RESV, "resv page"}, \ + {(unsigned long)DHUGETLB_UNRESV, "unresv page"}, \ + {(unsigned long)DHUGETLB_ALLOC, "alloc page"}, \ + {(unsigned long)DHUGETLB_FREE, "free page"} + +#define show_action(action) \ + (action) ? __print_flags(action, "", \ + __def_action_names \ + ) : "none" + +TRACE_EVENT(dynamic_hugetlb_split_merge, + + TP_PROTO(const void *hpool, struct page *page, unsigned long action, unsigned long size), + + TP_ARGS(hpool, page, action, size), + + TP_STRUCT__entry( + __field( const void *, hpool ) + __field( unsigned long, pfn ) + __field( unsigned long, action ) + __field( unsigned long, size ) + ), + + TP_fast_assign( + __entry->hpool = hpool; + __entry->pfn = page ? page_to_pfn(page) : -1UL; + __entry->action = action; + __entry->size = size; + ), + + TP_printk("hpool=%p page=%p pfn=%lu action=%s size=%lu", + __entry->hpool, + __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL, + __entry->pfn, + show_action(__entry->action), + __entry->size) +); + +TRACE_EVENT(dynamic_hugetlb_acct_memory, + + TP_PROTO(const void *hpool, unsigned long count, unsigned long action, unsigned long size), + + TP_ARGS(hpool, count, action, size), + + TP_STRUCT__entry( + __field( const void *, hpool ) + __field( unsigned long, count ) + __field( unsigned long, action ) + __field( unsigned long, size ) + ), + + TP_fast_assign( + __entry->hpool = hpool; + __entry->size = size; + __entry->count = count; + __entry->action = action; + ), + + TP_printk("hpool=%p action=%s size = %lu mmap_count=%lu", + __entry->hpool, + show_action(__entry->action), + __entry->size, + __entry->count) +); + +TRACE_EVENT(dynamic_hugetlb_alloc_free, + + TP_PROTO(const void *hpool, struct page *page, unsigned long count, unsigned long action, unsigned long size), + + TP_ARGS(hpool, page, count, action, size), + + TP_STRUCT__entry( + __field( const void *, hpool ) + __field( unsigned long, pfn ) + __field( unsigned long, count ) + __field( unsigned long, action ) + __field( unsigned long, size ) + ), + + TP_fast_assign( + __entry->hpool = hpool; + __entry->pfn = page ? page_to_pfn(page) : -1UL; + __entry->count = count; + __entry->action = action; + __entry->size = size; + ), + + TP_printk("hpool=%p page=%p pfn=%lu action=%s size = %lu free_count=%lu", + __entry->hpool, + __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL, + __entry->pfn, + show_action(__entry->action), + __entry->size, + __entry->count) +); + +#endif /* _TRACE_DHUGETLB_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/mm/dynamic_hugetlb.c b/mm/dynamic_hugetlb.c index 73795d533f7e..1faac3b4572b 100644 --- a/mm/dynamic_hugetlb.c +++ b/mm/dynamic_hugetlb.c @@ -10,6 +10,11 @@
#include "internal.h"
+#if (defined CONFIG_DYNAMIC_HUGETLB) && (!defined __GENKSYMS__) +#define CREATE_TRACE_POINTS +#include <trace/events/dynamic_hugetlb.h> +#endif + static bool enable_dhugetlb = false; DEFINE_STATIC_KEY_FALSE(dhugetlb_enabled_key);
@@ -110,6 +115,7 @@ static int hpool_split_page(struct dhugetlb_pool *hpool, int hpages_pool_idx) split_page->start_pfn = page_to_pfn(page); list_add(&split_page->head_pages, &hpages_pool->hugepage_splitlists); hpages_pool->split_normal_pages++; + trace_dynamic_hugetlb_split_merge(hpool, page, DHUGETLB_SPLIT, page_size(page));
switch (hpages_pool_idx) { case HUGE_PAGES_POOL_1G: @@ -245,6 +251,7 @@ static int hpool_merge_page(struct dhugetlb_pool *hpool, int hpages_pool_idx, bo src_hpages_pool->free_normal_pages--; } add_new_page_to_pool(hpool, page, hpages_pool_idx); + trace_dynamic_hugetlb_split_merge(hpool, page, DHUGETLB_MERGE, page_size(page)); return 0; next: continue; @@ -602,10 +609,14 @@ int dhugetlb_acct_memory(struct hstate *h, long delta, struct hugetlbfs_inode_in if (delta > 0 && delta <= hpages_pool->free_huge_pages - hpages_pool->resv_huge_pages) { hpages_pool->resv_huge_pages += delta; ret = 0; + trace_dynamic_hugetlb_acct_memory(hpool, hpages_pool->resv_huge_pages, + DHUGETLB_RESV, huge_page_size(h)); } else if (delta < 0) { hpages_pool->resv_huge_pages -= (unsigned long)(-delta); WARN_ON(hpages_pool->resv_huge_pages < 0); ret = 0; + trace_dynamic_hugetlb_acct_memory(hpool, hpages_pool->resv_huge_pages, + DHUGETLB_UNRESV, huge_page_size(h)); } spin_unlock(&hpool->lock);
@@ -636,7 +647,11 @@ struct page *alloc_huge_page_from_dhugetlb_pool(struct hstate *h, struct dhugetl if (need_unreserved) { SetHPageRestoreReserve(page); hpages_pool->resv_huge_pages--; + trace_dynamic_hugetlb_acct_memory(hpool, hpages_pool->resv_huge_pages, + DHUGETLB_UNRESV, huge_page_size(h)); } + trace_dynamic_hugetlb_alloc_free(hpool, page, hpages_pool->free_huge_pages, + DHUGETLB_ALLOC, huge_page_size(h)); } if (page) { INIT_LIST_HEAD(&page->lru); @@ -673,8 +688,13 @@ void free_huge_page_to_dhugetlb_pool(struct page *page, bool restore_reserve) list_add(&page->lru, &hpages_pool->hugepage_freelists); hpages_pool->free_huge_pages++; hpages_pool->used_huge_pages--; - if (restore_reserve) + if (restore_reserve) { hpages_pool->resv_huge_pages++; + trace_dynamic_hugetlb_acct_memory(hpool, hpages_pool->resv_huge_pages, + DHUGETLB_RESV, huge_page_size(h)); + } + trace_dynamic_hugetlb_alloc_free(hpool, page, hpages_pool->free_huge_pages, + DHUGETLB_FREE, huge_page_size(h)); spin_unlock(&hpool->lock); put_hpool(hpool); }