ftrace macro

2024-06-03 15:38
文章标签 macro ftrace

本文主要是介绍ftrace macro,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!





* Usage
Two elements are required for tracepoints :
- A tracepoint definition, placed in a header file.
- The tracepoint statement, in C code.


数据结构和宏定义在文件
include/linux/tacepoint.h


struct tracepoint_func {
void *func;
void *data;
};


struct tracepoint {
const char *name; /* Tracepoint name */
struct static_key key;
void (*regfunc)(void);
void (*unregfunc)(void);
struct tracepoint_func __rcu *funcs;
};


extern int
tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
extern int
tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data);




在头文件中包含tracepoint.h, 并调用DECLARE_TRACE定义一组函数
#define TP_PROTO(args...) args
#define TP_ARGS(args...) args
#define TP_CONDITION(args...) args


#define DECLARE_TRACE(name, proto, args) \
__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \
PARAMS(void *__data, proto), \
PARAMS(__data, args))


#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
extern struct tracepoint __tracepoint_##name; \
static inline void trace_##name(proto) \
{ \
if (static_key_false(&__tracepoint_##name.key)) \
__DO_TRACE(&__tracepoint_##name, \
TP_PROTO(data_proto), \
TP_ARGS(data_args), \
TP_CONDITION(cond),,); \
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
rcu_read_lock_sched_notrace(); \
rcu_dereference_sched(__tracepoint_##name.funcs);\
rcu_read_unlock_sched_notrace(); \
} \
} \
__DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
PARAMS(cond), PARAMS(data_proto), PARAMS(data_args)) \
static inline int \
register_trace_##name(void (*probe)(data_proto), void *data) \
{ \
return tracepoint_probe_register(&__tracepoint_##name, \
(void *)probe, data); \
} \
static inline int \
unregister_trace_##name(void (*probe)(data_proto), void *data) \
{ \
return tracepoint_probe_unregister(&__tracepoint_##name,\
(void *)probe, data); \
} \
static inline void \
check_trace_callback_type_##name(void (*cb)(data_proto)) \
{ \
} \
static inline bool \
trace_##name##_enabled(void) \
{ \
return static_key_false(&__tracepoint_##name.key); \
}




DEFINE_TRACE:
#define DEFINE_TRACE_FN(name, reg, unreg) \
static const char __tpstrtab_##name[] \
__attribute__((section("__tracepoints_strings"))) = #name; \
struct tracepoint __tracepoint_##name \
__attribute__((section("__tracepoints"))) = \
{ __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
static struct tracepoint * const __tracepoint_ptr_##name __used \
__attribute__((section("__tracepoints_ptrs"))) = \
&__tracepoint_##name;


#define DEFINE_TRACE(name) \
DEFINE_TRACE_FN(name, NULL, NULL);






#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu) \
do { \
struct tracepoint_func *it_func_ptr; \
void *it_func; \
void *__data; \
\
if (!(cond)) \
return; \
prercu; \
rcu_read_lock_sched_notrace(); \
it_func_ptr = rcu_dereference_sched((tp)->funcs); \
if (it_func_ptr) { \
do { \
it_func = (it_func_ptr)->func; \
__data = (it_func_ptr)->data; \
((void(*)(proto))(it_func))(args); \
} while ((++it_func_ptr)->func); \
} \
rcu_read_unlock_sched_notrace(); \
postrcu; \
} while (0)


static inline void trace_##name(proto) \
{ \
if (static_key_false(&__tracepoint_##name.key)) \
__DO_TRACE(&__tracepoint_##name, \
TP_PROTO(data_proto), \
TP_ARGS(data_args), \
TP_CONDITION(cond),,); \
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
rcu_read_lock_sched_notrace(); \
rcu_dereference_sched(__tracepoint_##name.funcs);\
rcu_read_unlock_sched_notrace(); \
} \
}


在文件 trace/trace_sched_switch.c文件中看到了register,  而文件sample中没有看到


TRACE_EVENT是DECLARE_TRACE的变种:
#define TRACE_EVENT(name, proto, args, struct, assign, print) \
DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))


/*
 * For use with the TRACE_EVENT macro:
 *
 * We define a tracepoint, its arguments, its printk format
 * and its 'fast binary record' layout.
 *
 * Firstly, name your tracepoint via TRACE_EVENT(name : the
 * 'subsystem_event' notation is fine.
 *
 * Think about this whole construct as the
 * 'trace_sched_switch() function' from now on.
 *
 *
 *  TRACE_EVENT(sched_switch,
 *
 * *
 * * A function has a regular function arguments
 * * prototype, declare it via TP_PROTO():
 * *
 *
 * TP_PROTO(struct rq *rq, struct task_struct *prev,
 * struct task_struct *next),
 *
 * *
 * * Define the call signature of the 'function'.
 * * (Design sidenote: we use this instead of a
 * *  TP_PROTO1/TP_PROTO2/TP_PROTO3 ugliness.)
 * *
 *
 * TP_ARGS(rq, prev, next),
 *
 * *
 * * Fast binary tracing: define the trace record via
 * * TP_STRUCT__entry(). You can think about it like a
 * * regular C structure local variable definition.
 * *
 * * This is how the trace record is structured and will
 * * be saved into the ring buffer. These are the fields
 * * that will be exposed to user-space in
 * * /sys/kernel/debug/tracing/events/<*>/format.
 * *
 * * The declared 'local variable' is called '__entry'
 * *
 * * __field(pid_t, prev_prid) is equivalent to a standard declariton:
 * *
 * * pid_t prev_pid;
 * *
 * * __array(char, prev_comm, TASK_COMM_LEN) is equivalent to:
 * *
 * * char prev_comm[TASK_COMM_LEN];
 * *
 *
 * TP_STRUCT__entry(
 * __array( char, prev_comm, TASK_COMM_LEN )
 * __field( pid_t, prev_pid )
 * __field( int, prev_prio )
 * __array( char, next_comm, TASK_COMM_LEN )
 * __field( pid_t, next_pid )
 * __field( int, next_prio )
 * ),
 *
 * *
 * * Assign the entry into the trace record, by embedding
 * * a full C statement block into TP_fast_assign(). You
 * * can refer to the trace record as '__entry' -
 * * otherwise you can put arbitrary C code in here.
 * *
 * * Note: this C code will execute every time a trace event
 * * happens, on an active tracepoint.
 * *
 *
 * TP_fast_assign(
 * memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
 * __entry->prev_pid = prev->pid;
 * __entry->prev_prio = prev->prio;
 * memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
 * __entry->next_pid = next->pid;
 * __entry->next_prio = next->prio;
 * ),
 *
 * *
 * * Formatted output of a trace record via TP_printk().
 * * This is how the tracepoint will appear under ftrace
 * * plugins that make use of this tracepoint.
 * *
 * * (raw-binary tracing wont actually perform this step.)
 * *
 *
 * TP_printk("task %s:%d [%d] ==> %s:%d [%d]",
 * __entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
 * __entry->next_comm, __entry->next_pid, __entry->next_prio),
 *
 * );
 *
 * This macro construct is thus used for the regular printk format
 * tracing setup, it is used to construct a function pointer based
 * tracepoint callback (this is used by programmatic plugins and
 * can also by used by generic instrumentation like SystemTap), and
 * it is also used to expose a structured trace record in
 * /sys/kernel/debug/tracing/events/.
 *
 * A set of (un)registration functions can be passed to the variant
 * TRACE_EVENT_FN to perform any (un)registration work.
 */


这里TP_printk的意思是:
#define TP_printk(fmt, args...) fmt "\n", args

这篇关于ftrace macro的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027404

相关文章

分类问题的评价指标:多分类【Precision、 micro-P、macro-P】、【Recall、micro-R、macro-R】、【F1、 micro-F1、macro-F1】

一、混淆矩阵 对于二分类的模型,预测结果与实际结果分别可以取0和1。我们用N和P代替0和1,T和F表示预测正确和错误。将他们两两组合,就形成了下图所示的混淆矩阵(注意:组合结果都是针对预测结果而言的)。 由于1和0是数字,阅读性不好,所以我们分别用P和N表示1和0两种结果。变换之后为PP,PN,NP,NN,阅读性也很差,我并不能轻易地看出来预测的正确性与否。因此,为了能够更清楚地分辨各种预测情

Linux configure.ac:51: error: possibly undefined macro: AC_MSG_ERROR

bug: 解决方法: cd /usr/local/share/autoconf/autoconf cp *.m4 /usr/share/aclocal

【GNU笔记】内联函数与宏一样快 An Inline Function is As Fast As a Macro

内联函数与宏一样快 An Inline Function is As Fast As a Macro 通过声明内联函数,你可以指示 GCC 更快地调用该函数。GCC 可以实现这一点的一种方法是将该函数的代码集成到其调用者的代码中。这通过消除函数调用开销使执行速度更快;此外,如果任何实际参数值是常量,则它们的已知值可能允许在编译时进行简化,因此不需要包含所有内联函数的代码。对代码大小的影响是难以预

Linux内核 -- ftrace 调试工具培训

ftrace 技术培训文档 技术背景 ftrace 是 Linux 内核中的一个跟踪框架,用于调试和分析内核中的性能问题。它允许开发者跟踪内核函数的调用和执行情况,从而帮助定位性能瓶颈和异常行为。 编译和部署 ftrace 开启 ftrace 内核选项 配置内核选项: 在编译内核时,需要确保以下选项被启用。运行 make menuconfig,并在菜单中找到 ftrace 相关选项进行

freemarker macro(宏)的使用

本文转载自:http://blog.chinaunix.net/uid-725717-id-2060340.html 有人说用freemarker,但没有用到它的宏(macro),就=没有真正用过freemarker。说的就是宏是freemarker的一大特色。     宏的定义可以查看相关的文档,里面介绍得很清楚,下面来看看它的一个用法。     /WEB-INF/templat

C语言基础-macro和volatile

在C语言中,可以使用#define预处理指令来定义宏。宏是一种在编译时替换文本的工具,通常用于表示常量或执行简单的文本替换。 下面是一个定义“标准”宏MIN的例子,这个宏用于比较两个值并返回较小的那个: #include <stdio.h> // 使用#define定义一个名为MIN的宏 #define MIN(a, b) ((a) < (b) ? (a) : (b)) int mai

ARM 汇编 伪指令 MACRO及MEND

ARM 汇编 伪指令 MACRO及MEND MACRO伪操作标识 宏定义的开始,MEND标识宏定义的结束。 用MACRO 及MEND定义一段代码,称为宏定义体,这样在程序中就可以通过宏指令多次调用该代码段 语法格式 MACRO {$label}  macroname {$param

C++之boost库报错:note: in expansion of macro BOOST_MPL_ASSERT_NOT(八十六)

1.代码示例   1.下载编译、安装boost1.55版本https://sourceforge.net/projects/boost/files/boost/1.55.0解压编译# ./b2# cmake -DCMAKE_CXX_FLAGS="-Wno-error=old-style-cast"Or 在test.cmake添加set(CMAKE_CXX_FLAGS "-Wno-err

【driver5】调用堆栈函数,printk,动态打印,ftrace,proc,sysfs

文章目录 1.内核函数调用堆栈:4个函数2.printk:cat /proc/cmdline查看console=ttyS03.动态打印:printk是全局的且只能设打印等级,动态打印可控制选择模块的打印,在内核配置打开CONFIG_DYNAMIC_DEBUG4.ftrace:系统层面,功能需要打开,image大小会变大5.proc文件系统:/proc/cpuinfo,meminfo,net6

Redmine EXCEL VBA 表格式添加宏(Macro)

使用说明: EXCEL VBA Macro 宏命令,用于自动添加Redmine表格格式,省去手动添加的麻烦。 此版本为按钮封装版,只需将需要添加Redmine表格格式的表格贴进去,然后点击按钮即可添加Redmine表格格式。注:由于上一版本表格忘记保存为xlsm(在其他页面,与此页面没有关联),因此代码丢失,现已重写并保存为xlsm。给诸位带来不便,深表歉意。 Sub rebuild()