hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8S9BY CVE: NA
--------------------------------
Add tracepoints for dynamic_hugetlb to track demotion, promotion, HugeTLB reserved pages, HugeTLB page allocation and HugeTLB page free.
Signed-off-by: Liu Shixin liushixin2@huawei.com --- include/trace/events/dynamic_pool.h | 174 ++++++++++++++++++++++++++++ mm/dynamic_pool.c | 15 ++- 2 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 include/trace/events/dynamic_pool.h
diff --git a/include/trace/events/dynamic_pool.h b/include/trace/events/dynamic_pool.h new file mode 100644 index 000000000000..f20360e0f00f --- /dev/null +++ b/include/trace/events/dynamic_pool.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM dynamic_pool + +#if !defined(_TRACE_DPOOL_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_DPOOL_H + +#include <linux/types.h> +#include <linux/tracepoint.h> +#include <trace/events/mmflags.h> + +#define show_size(type) \ + __print_symbolic(type, \ + { PAGES_POOL_1G, "1G" }, \ + { PAGES_POOL_2M, "2M" }, \ + { PAGES_POOL_4K, "4K" }) + +TRACE_EVENT(dpool_demote, + + TP_PROTO(struct dynamic_pool *dpool, int type, struct page *page, + int ret), + + TP_ARGS(dpool, type, page, ret), + + TP_STRUCT__entry( + __field(struct dynamic_pool *, dpool) + __field(int, type) + __field(unsigned long, pfn) + __field(int, ret) + ), + + TP_fast_assign( + __entry->dpool = dpool; + __entry->type = type; + __entry->pfn = page ? page_to_pfn(page) : -1UL; + __entry->ret = ret; + ), + + TP_printk("dpool=%p size=%s page=%p pfn=%lx ret=%d", + __entry->dpool, + show_size(__entry->type), + __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL, + __entry->pfn, + __entry->ret) +); + +TRACE_EVENT(dpool_promote, + + TP_PROTO(struct dynamic_pool *dpool, int type, struct page *page, + int ret), + + TP_ARGS(dpool, type, page, ret), + + TP_STRUCT__entry( + __field(struct dynamic_pool *, dpool) + __field(int, type) + __field(unsigned long, pfn) + __field(int, ret) + ), + + TP_fast_assign( + __entry->dpool = dpool; + __entry->type = type; + __entry->pfn = page ? page_to_pfn(page) : -1UL; + __entry->ret = ret; + ), + + TP_printk("dpool=%p size=%s page=%p pfn=%lx ret=%d", + __entry->dpool, + show_size(__entry->type), + __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL, + __entry->pfn, + __entry->ret) +); + +TRACE_EVENT(dpool_acct_memory, + + TP_PROTO(struct dynamic_pool *dpool, int type, long delta, + unsigned long resv, int ret), + + TP_ARGS(dpool, type, delta, resv, ret), + + TP_STRUCT__entry( + __field(struct dynamic_pool *, dpool) + __field(int, type) + __field(long, delta) + __field(unsigned long, resv) + __field(int, ret) + ), + + TP_fast_assign( + __entry->dpool = dpool; + __entry->type = type; + __entry->delta = delta; + __entry->resv = resv; + __entry->ret = ret; + ), + + TP_printk("dpool=%p size=%s delta=%ld resv=%lu ret=%d", + __entry->dpool, + show_size(__entry->type), + __entry->delta, + __entry->resv, + __entry->ret) +); + +TRACE_EVENT(dpool_alloc_hugepage, + + TP_PROTO(struct dynamic_pool *dpool, int type, struct folio *folio, + unsigned long free, unsigned long resv), + + TP_ARGS(dpool, type, folio, free, resv), + + TP_STRUCT__entry( + __field(struct dynamic_pool *, dpool) + __field(int, type) + __field(unsigned long, pfn) + __field(unsigned long, free) + __field(unsigned long, resv) + ), + + TP_fast_assign( + __entry->dpool = dpool; + __entry->type = type; + __entry->pfn = folio ? folio_pfn(folio) : -1UL; + __entry->free = free; + __entry->resv = resv; + ), + + TP_printk("dpool=%p size=%s page=%p pfn=%lx free=%lu resv=%lu", + __entry->dpool, + show_size(__entry->type), + __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL, + __entry->pfn, + __entry->free, + __entry->resv) +); + +TRACE_EVENT(dpool_free_hugepage, + + TP_PROTO(struct dynamic_pool *dpool, int type, struct folio *folio, + unsigned long free, unsigned long resv), + + TP_ARGS(dpool, type, folio, free, resv), + + TP_STRUCT__entry( + __field(struct dynamic_pool *, dpool) + __field(int, type) + __field(unsigned long, pfn) + __field(unsigned long, free) + __field(unsigned long, resv) + ), + + TP_fast_assign( + __entry->dpool = dpool; + __entry->type = type; + __entry->pfn = folio ? folio_pfn(folio) : -1UL; + __entry->free = free; + __entry->resv = resv; + ), + + TP_printk("dpool=%p size=%s page=%p pfn=%lx free=%lu resv=%lu", + __entry->dpool, + show_size(__entry->type), + __entry->pfn != -1UL ? pfn_to_page(__entry->pfn) : NULL, + __entry->pfn, + __entry->free, + __entry->resv) +); + +#endif /* _TRACE_DPOOL_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> diff --git a/mm/dynamic_pool.c b/mm/dynamic_pool.c index 8ed60c5f21dc..7880cde277a7 100644 --- a/mm/dynamic_pool.c +++ b/mm/dynamic_pool.c @@ -11,6 +11,9 @@ #include <linux/dynamic_pool.h> #include "internal.h"
+#define CREATE_TRACE_POINTS +#include <trace/events/dynamic_pool.h> + static bool enable_dhugetlb;
/* Indicate the enabled of dynamic pool */ @@ -215,7 +218,7 @@ static int dpool_demote_pool_locked(struct dynamic_pool *dpool, int type) { struct pages_pool *src_pool, *dst_pool; struct split_page *spage = NULL; - struct page *page; + struct page *page = NULL; int ret = -ENOMEM;
lockdep_assert_held(&dpool->lock); @@ -256,6 +259,7 @@ static int dpool_demote_pool_locked(struct dynamic_pool *dpool, int type) } else { kfree(spage); } + trace_dpool_demote(dpool, type, page, ret);
return ret; } @@ -339,6 +343,7 @@ static int dpool_promote_pool(struct dynamic_pool *dpool, int type) { struct pages_pool *src_pool, *dst_pool; struct split_page *spage, *spage_next; + struct page *page = NULL; int ret = -ENOMEM;
@@ -385,6 +390,7 @@ static int dpool_promote_pool(struct dynamic_pool *dpool, int type) }
if (!ret) { + page = pfn_to_page(spage->start_pfn); list_del(&spage->entry); dst_pool->split_pages--; } @@ -393,6 +399,7 @@ static int dpool_promote_pool(struct dynamic_pool *dpool, int type) spin_unlock(&dpool->lock); if (!ret) kfree(spage); + trace_dpool_promote(dpool, type, page, ret);
return ret; } @@ -789,6 +796,8 @@ int dynamic_pool_hugetlb_acct_memory(struct hstate *h, long delta, ret = 0; } spin_unlock_irqrestore(&dpool->lock, flags); + trace_dpool_acct_memory(dpool, type, delta, pool->resv_huge_pages, + ret);
return ret; } @@ -839,6 +848,8 @@ struct folio *dynamic_pool_alloc_hugepage(struct hugetlbfs_inode_info *p,
unlock: spin_unlock_irqrestore(&dpool->lock, flags); + trace_dpool_alloc_hugepage(dpool, type, folio, pool->free_huge_pages, + pool->resv_huge_pages);
return folio; } @@ -881,6 +892,8 @@ void dynamic_pool_free_hugepage(struct folio *folio, bool restore_reserve) unlock: spin_unlock_irqrestore(&dpool->lock, flags); dpool_put(dpool); + trace_dpool_free_hugepage(dpool, type, folio, pool->free_huge_pages, + pool->resv_huge_pages); }
/* === dynamic pool function ========================================== */