linux/samples/ftrace/ftrace-ops.c

// SPDX-License-Identifier: GPL-2.0-only

#define pr_fmt(fmt)

#include <linux/ftrace.h>
#include <linux/ktime.h>
#include <linux/module.h>

#include <asm/barrier.h>

/*
 * Arbitrary large value chosen to be sufficiently large to minimize noise but
 * sufficiently small to complete quickly.
 */
static unsigned int nr_function_calls =;
module_param(nr_function_calls, uint, 0);
MODULE_PARM_DESC();

/*
 * The number of ops associated with a call site affects whether a tracer can
 * be called directly or whether it's necessary to go via the list func, which
 * can be significantly more expensive.
 */
static unsigned int nr_ops_relevant =;
module_param(nr_ops_relevant, uint, 0);
MODULE_PARM_DESC();

/*
 * On architectures where all call sites share the same trampoline, having
 * tracers enabled for distinct functions can force the use of the list func
 * and incur overhead for all call sites.
 */
static unsigned int nr_ops_irrelevant;
module_param(nr_ops_irrelevant, uint, 0);
MODULE_PARM_DESC();

/*
 * On architectures with DYNAMIC_FTRACE_WITH_REGS, saving the full pt_regs can
 * be more expensive than only saving the minimal necessary regs.
 */
static bool save_regs;
module_param(save_regs, bool, 0);
MODULE_PARM_DESC();

static bool assist_recursion;
module_param(assist_recursion, bool, 0);
MODULE_PARM_DESC();

static bool assist_rcu;
module_param(assist_rcu, bool, 0);
MODULE_PARM_DESC();

/*
 * By default, a trivial tracer is used which immediately returns to mimimize
 * overhead. Sometimes a consistency check using a more expensive tracer is
 * desireable.
 */
static bool check_count;
module_param(check_count, bool, 0);
MODULE_PARM_DESC();

/*
 * Usually it's not interesting to leave the ops registered after the test
 * runs, but sometimes it can be useful to leave them registered so that they
 * can be inspected through the tracefs 'enabled_functions' file.
 */
static bool persist;
module_param(persist, bool, 0);
MODULE_PARM_DESC();

/*
 * Marked as noinline to ensure that an out-of-line traceable copy is
 * generated by the compiler.
 *
 * The barrier() ensures the compiler won't elide calls by determining there
 * are no side-effects.
 */
static noinline void tracee_relevant(void)
{}

/*
 * Marked as noinline to ensure that an out-of-line traceable copy is
 * generated by the compiler.
 *
 * The barrier() ensures the compiler won't elide calls by determining there
 * are no side-effects.
 */
static noinline void tracee_irrelevant(void)
{}

struct sample_ops {};

static void ops_func_nop(unsigned long ip, unsigned long parent_ip,
			 struct ftrace_ops *op,
			 struct ftrace_regs *fregs)
{}

static void ops_func_count(unsigned long ip, unsigned long parent_ip,
			   struct ftrace_ops *op,
			   struct ftrace_regs *fregs)
{}

static struct sample_ops *ops_relevant;
static struct sample_ops *ops_irrelevant;

static struct sample_ops *ops_alloc_init(void *tracee, ftrace_func_t func,
					 unsigned long flags, int nr)
{}

static void ops_destroy(struct sample_ops *ops, int nr)
{}

static void ops_check(struct sample_ops *ops, int nr,
		      unsigned int expected_count)
{}

static ftrace_func_t tracer_relevant =;
static ftrace_func_t tracer_irrelevant =;

static int __init ftrace_ops_sample_init(void)
{}
module_init();

static void __exit ftrace_ops_sample_exit(void)
{}
module_exit(ftrace_ops_sample_exit);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();