mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
![Masami Hiramatsu](/assets/img/avatar_default.png)
The fprobe is a wrapper API for ftrace function tracer. Unlike kprobes, this probes only supports the function entry, but this can probe multiple functions by one fprobe. The usage is similar, user will set their callback to fprobe::entry_handler and call register_fprobe*() with probed functions. There are 3 registration interfaces, - register_fprobe() takes filtering patterns of the functin names. - register_fprobe_ips() takes an array of ftrace-location addresses. - register_fprobe_syms() takes an array of function names. The registered fprobes can be unregistered with unregister_fprobe(). e.g. struct fprobe fp = { .entry_handler = user_handler }; const char *targets[] = { "func1", "func2", "func3"}; ... ret = register_fprobe_syms(&fp, targets, ARRAY_SIZE(targets)); ... unregister_fprobe(&fp); Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org> Tested-by: Steven Rostedt (Google) <rostedt@goodmis.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/164735283857.1084943.1154436951479395551.stgit@devnote2
87 lines
2.2 KiB
C
87 lines
2.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Simple ftrace probe wrapper */
|
|
#ifndef _LINUX_FPROBE_H
|
|
#define _LINUX_FPROBE_H
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/ftrace.h>
|
|
|
|
/**
|
|
* struct fprobe - ftrace based probe.
|
|
* @ops: The ftrace_ops.
|
|
* @nmissed: The counter for missing events.
|
|
* @flags: The status flag.
|
|
* @entry_handler: The callback function for function entry.
|
|
*/
|
|
struct fprobe {
|
|
#ifdef CONFIG_FUNCTION_TRACER
|
|
/*
|
|
* If CONFIG_FUNCTION_TRACER is not set, CONFIG_FPROBE is disabled too.
|
|
* But user of fprobe may keep embedding the struct fprobe on their own
|
|
* code. To avoid build error, this will keep the fprobe data structure
|
|
* defined here, but remove ftrace_ops data structure.
|
|
*/
|
|
struct ftrace_ops ops;
|
|
#endif
|
|
unsigned long nmissed;
|
|
unsigned int flags;
|
|
void (*entry_handler)(struct fprobe *fp, unsigned long entry_ip, struct pt_regs *regs);
|
|
};
|
|
|
|
#define FPROBE_FL_DISABLED 1
|
|
|
|
static inline bool fprobe_disabled(struct fprobe *fp)
|
|
{
|
|
return (fp) ? fp->flags & FPROBE_FL_DISABLED : false;
|
|
}
|
|
|
|
#ifdef CONFIG_FPROBE
|
|
int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter);
|
|
int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num);
|
|
int register_fprobe_syms(struct fprobe *fp, const char **syms, int num);
|
|
int unregister_fprobe(struct fprobe *fp);
|
|
#else
|
|
static inline int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
static inline int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
static inline int register_fprobe_syms(struct fprobe *fp, const char **syms, int num)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
static inline int unregister_fprobe(struct fprobe *fp)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* disable_fprobe() - Disable fprobe
|
|
* @fp: The fprobe to be disabled.
|
|
*
|
|
* This will soft-disable @fp. Note that this doesn't remove the ftrace
|
|
* hooks from the function entry.
|
|
*/
|
|
static inline void disable_fprobe(struct fprobe *fp)
|
|
{
|
|
if (fp)
|
|
fp->flags |= FPROBE_FL_DISABLED;
|
|
}
|
|
|
|
/**
|
|
* enable_fprobe() - Enable fprobe
|
|
* @fp: The fprobe to be enabled.
|
|
*
|
|
* This will soft-enable @fp.
|
|
*/
|
|
static inline void enable_fprobe(struct fprobe *fp)
|
|
{
|
|
if (fp)
|
|
fp->flags &= ~FPROBE_FL_DISABLED;
|
|
}
|
|
|
|
#endif
|