root/include/trace/events/ksm.h
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM ksm

#if !defined(_TRACE_KSM_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_KSM_H

#include <linux/tracepoint.h>

/**
 * ksm_scan_template - called for start / stop scan
 *
 * @seq:                sequence number of scan
 * @rmap_entries:       actual number of rmap entries
 *
 * Allows to trace the start / stop of a ksm scan.
 */
DECLARE_EVENT_CLASS(ksm_scan_template,

        TP_PROTO(int seq, u32 rmap_entries),

        TP_ARGS(seq, rmap_entries),

        TP_STRUCT__entry(
                __field(int,    seq)
                __field(u32,    rmap_entries)
        ),

        TP_fast_assign(
                __entry->seq            = seq;
                __entry->rmap_entries   = rmap_entries;
        ),

        TP_printk("seq %d rmap size %d",
                        __entry->seq, __entry->rmap_entries)
);

/**
 * ksm_start_scan - called after a new ksm scan is started
 *
 * @seq:                sequence number of scan
 * @rmap_entries:       actual number of rmap entries
 *
 * Allows to trace the start of a ksm scan.
 */
DEFINE_EVENT(ksm_scan_template, ksm_start_scan,

        TP_PROTO(int seq, u32 rmap_entries),

        TP_ARGS(seq, rmap_entries)
);

/**
 * ksm_stop_scan - called after a new ksm scan has completed
 *
 * @seq:                sequence number of scan
 * @rmap_entries:       actual number of rmap entries
 *
 * Allows to trace the completion of a ksm scan.
 */
DEFINE_EVENT(ksm_scan_template, ksm_stop_scan,

        TP_PROTO(int seq, u32 rmap_entries),

        TP_ARGS(seq, rmap_entries)
);

/**
 * ksm_enter - called after a new process has been added / removed from ksm
 *
 * @mm:                 address of the mm object of the process
 *
 * Allows to trace the when a process has been added or removed from ksm.
 */
DECLARE_EVENT_CLASS(ksm_enter_exit_template,

        TP_PROTO(void *mm),

        TP_ARGS(mm),

        TP_STRUCT__entry(
                __field(void *,         mm)
        ),

        TP_fast_assign(
                __entry->mm     = mm;
        ),

        TP_printk("mm %p", __entry->mm)
);

/**
 * ksm_enter - called after a new process has been added to ksm
 *
 * @mm:                 address of the mm object of the process
 *
 * Allows to trace the when a process has been added to ksm.
 */
DEFINE_EVENT(ksm_enter_exit_template, ksm_enter,

        TP_PROTO(void *mm),

        TP_ARGS(mm)
);

/**
 * ksm_exit - called after a new process has been removed from ksm
 *
 * @mm:                 address of the mm object of the process
 *
 * Allows to trace the when a process has been removed from ksm.
 */
DEFINE_EVENT(ksm_enter_exit_template, ksm_exit,

        TP_PROTO(void *mm),

        TP_ARGS(mm)
);

/**
 * ksm_merge_one_page - called after a page has been merged
 *
 * @pfn:                page frame number of ksm page
 * @rmap_item:          address of rmap_item  object
 * @mm:                 address of the process mm struct
 * @err:                success
 *
 * Allows to trace the ksm merging of individual pages.
 */
TRACE_EVENT(ksm_merge_one_page,

        TP_PROTO(unsigned long pfn, void *rmap_item, void *mm, int err),

        TP_ARGS(pfn, rmap_item, mm, err),

        TP_STRUCT__entry(
                __field(unsigned long,  pfn)
                __field(void *,         rmap_item)
                __field(void *,         mm)
                __field(int,            err)
        ),

        TP_fast_assign(
                __entry->pfn            = pfn;
                __entry->rmap_item      = rmap_item;
                __entry->mm             = mm;
                __entry->err            = err;
        ),

        TP_printk("ksm pfn %lu rmap_item %p mm %p error %d",
                        __entry->pfn, __entry->rmap_item, __entry->mm, __entry->err)
);

/**
 * ksm_merge_with_ksm_page - called after a page has been merged with a ksm page
 *
 * @ksm_page:           address ksm page
 * @pfn:                page frame number of ksm page
 * @rmap_item:          address of rmap_item  object
 * @mm:                 address of the mm object of the process
 * @err:                success
 *
 * Allows to trace the merging of a page with a ksm page.
 */
TRACE_EVENT(ksm_merge_with_ksm_page,

        TP_PROTO(void *ksm_page, unsigned long pfn, void *rmap_item, void *mm, int err),

        TP_ARGS(ksm_page, pfn, rmap_item, mm, err),

        TP_STRUCT__entry(
                __field(void *,         ksm_page)
                __field(unsigned long,  pfn)
                __field(void *,         rmap_item)
                __field(void *,         mm)
                __field(int,            err)
        ),

        TP_fast_assign(
                __entry->ksm_page       = ksm_page;
                __entry->pfn            = pfn;
                __entry->rmap_item      = rmap_item;
                __entry->mm             = mm;
                __entry->err            = err;
        ),

        TP_printk("%spfn %lu rmap_item %p mm %p error %d",
                  (__entry->ksm_page ? "ksm " : ""),
                  __entry->pfn, __entry->rmap_item, __entry->mm, __entry->err)
);

/**
 * ksm_remove_ksm_page - called after a ksm page has been removed
 *
 * @pfn:                page frame number of ksm page
 *
 * Allows to trace the removing of stable ksm pages.
 */
TRACE_EVENT(ksm_remove_ksm_page,

        TP_PROTO(unsigned long pfn),

        TP_ARGS(pfn),

        TP_STRUCT__entry(
                __field(unsigned long, pfn)
        ),

        TP_fast_assign(
                __entry->pfn = pfn;
        ),

        TP_printk("pfn %lu", __entry->pfn)
);

/**
 * ksm_remove_rmap_item - called after a rmap_item has been removed from the
 *                        stable tree
 *
 * @pfn:                page frame number of ksm page
 * @rmap_item:          address of rmap_item  object
 * @mm:                 address of the process mm struct
 *
 * Allows to trace the removal of pages from the stable tree list.
 */
TRACE_EVENT(ksm_remove_rmap_item,

        TP_PROTO(unsigned long pfn, void *rmap_item, void *mm),

        TP_ARGS(pfn, rmap_item, mm),

        TP_STRUCT__entry(
                __field(unsigned long,  pfn)
                __field(void *,         rmap_item)
                __field(void *,         mm)
        ),

        TP_fast_assign(
                __entry->pfn            = pfn;
                __entry->rmap_item      = rmap_item;
                __entry->mm             = mm;
        ),

        TP_printk("pfn %lu rmap_item %p mm %p",
                        __entry->pfn, __entry->rmap_item, __entry->mm)
);

/**
 * ksm_advisor - called after the advisor has run
 *
 * @scan_time:          scan time in seconds
 * @pages_to_scan:      new pages_to_scan value
 * @cpu_percent:        cpu usage in percent
 *
 * Allows to trace the ksm advisor.
 */
TRACE_EVENT(ksm_advisor,

        TP_PROTO(s64 scan_time, unsigned long pages_to_scan,
                 unsigned int cpu_percent),

        TP_ARGS(scan_time, pages_to_scan, cpu_percent),

        TP_STRUCT__entry(
                __field(s64,            scan_time)
                __field(unsigned long,  pages_to_scan)
                __field(unsigned int,   cpu_percent)
        ),

        TP_fast_assign(
                __entry->scan_time      = scan_time;
                __entry->pages_to_scan  = pages_to_scan;
                __entry->cpu_percent    = cpu_percent;
        ),

        TP_printk("ksm scan time %lld pages_to_scan %lu cpu percent %u",
                        __entry->scan_time, __entry->pages_to_scan,
                        __entry->cpu_percent)
);

#endif /* _TRACE_KSM_H */

/* This part must be outside protection */
#include <trace/define_trace.h>