Linux 内核跟踪点 API¶
- 作者:
Jason Baron
- 作者:
William Cohen
简介¶
跟踪点是位于内核中关键点的静态探测点。“探测器”通过回调机制向跟踪点注册/注销。这些“探测器”是严格类型化的函数,它们被传递由每个跟踪点定义的一组唯一参数。
通过这种简单的回调机制,“探测器”可用于分析、调试和理解内核行为。有许多工具提供了使用“探测器”的框架。这些工具包括 Systemtap、ftrace 和 LTTng。
跟踪点通过各种宏定义在多个头文件中。因此,本文档的目的是清晰地说明所有可用的跟踪点。其目的是不仅要了解哪些跟踪点可用,还要了解未来可能在何处添加跟踪点。
所呈现的 API 具有以下形式的函数:trace_tracepointname(function parameters)
。这些是代码中随处可见的跟踪点回调。在 Documentation/trace/*
目录中介绍了在这些回调站点注册和注销探测点的内容。
IRQ¶
参数
int irq
irq 号
struct irqaction *action
指向
struct irqaction
的指针
描述
由 action 指向的 struct irqaction
包含有关处理程序的各种信息,包括设备名称 action->name 和设备 ID action->dev_id。与 irq_handler_exit 跟踪点结合使用时,我们可以计算出 irq 处理程序的延迟。
参数
int irq
irq 号
struct irqaction *action
指向
struct irqaction
的指针int ret
返回值
描述
如果 ret 值设置为 IRQ_HANDLED,则表示相应的 action->handler 已成功处理此 irq。否则,该 irq 可能是共享 irq 线,或者 irq 未成功处理。可与 irq_handler_entry 结合使用以了解 irq 处理程序的延迟。
-
void trace_softirq_entry(unsigned int vec_nr)¶
在 softirq 处理程序之前立即调用
参数
unsigned int vec_nr
softirq 向量号
描述
与 softirq_exit 跟踪点结合使用时,我们可以确定 softirq 处理程序例程。
-
void trace_softirq_exit(unsigned int vec_nr)¶
在 softirq 处理程序返回后立即调用
参数
unsigned int vec_nr
softirq 向量号
描述
与 softirq_entry 跟踪点结合使用时,我们可以确定 softirq 处理程序例程。
-
void trace_softirq_raise(unsigned int vec_nr)¶
当 softirq 被触发时立即调用
参数
unsigned int vec_nr
softirq 向量号
描述
与 softirq_entry 跟踪点结合使用时,我们可以确定 softirq 从触发到运行的延迟。
-
void trace_tasklet_entry(struct tasklet_struct *t, void *func)¶
在 tasklet 运行之前立即调用
参数
struct tasklet_struct *t
tasklet 指针
void *func
tasklet 回调或正在运行的函数
描述
用于查找单个 tasklet 的执行时间
-
void trace_tasklet_exit(struct tasklet_struct *t, void *func)¶
在 tasklet 运行后立即调用
参数
struct tasklet_struct *t
tasklet 指针
void *func
tasklet 回调或正在运行的函数
描述
用于查找单个 tasklet 的执行时间
信号¶
-
void trace_signal_generate(int sig, struct kernel_siginfo *info, struct task_struct *task, int group, int result)¶
当信号生成时调用
参数
int sig
信号编号
struct kernel_siginfo *info
指向 struct siginfo 的指针
struct task_struct *task
指向 struct task_struct 的指针
int group
共享或私有
int result
TRACE_SIGNAL_*
描述
当前进程将 ‘sig’ 信号与 ‘info’ siginfo 一起发送到 ‘task’ 进程。如果 ‘info’ 是 SEND_SIG_NOINFO 或 SEND_SIG_PRIV,则 ‘info’ 不是指针,您无法访问其字段。相反,SEND_SIG_NOINFO 表示 si_code 是 SI_USER,SEND_SIG_PRIV 表示 si_code 是 SI_KERNEL。
-
void trace_signal_deliver(int sig, struct kernel_siginfo *info, struct k_sigaction *ka)¶
当信号传递时调用
参数
int sig
信号编号
struct kernel_siginfo *info
指向 struct siginfo 的指针
struct k_sigaction *ka
指向 struct k_sigaction 的指针
描述
‘sig’ 信号与 ‘info’ siginfo 一起传递给当前进程,并将由 ‘ka’ 处理。ka->sa.sa_handler 可以是 SIG_IGN 或 SIG_DFL。请注意,signal_generate 跟踪点报告的某些信号可能会在到达此跟踪点之前丢失、被忽略或被修改(由调试器)。这意味着,这可以显示实际传递了哪些信号,但生成信号与传递信号的匹配可能不正确。
块 IO¶
-
void trace_block_touch_buffer(struct buffer_head *bh)¶
标记缓冲区已访问
参数
struct buffer_head *bh
正在访问的 buffer_head
描述
从 touch_buffer() 调用。
-
void trace_block_dirty_buffer(struct buffer_head *bh)¶
标记缓冲区脏
-
void trace_block_rq_requeue(struct request *rq)¶
将块 IO 请求放回队列
参数
struct request *rq
块 IO 操作请求
描述
块操作请求 rq 正在被放回队列 q。由于某种原因,该请求未完成,需要放回队列中。
-
void trace_block_rq_complete(struct request *rq, blk_status_t error, unsigned int nr_bytes)¶
设备驱动程序完成块 IO 操作
参数
struct request *rq
块操作请求
blk_status_t error
状态码
unsigned int nr_bytes
已完成字节数
描述
block_rq_complete 跟踪点事件表示设备驱动程序已完成操作请求的某个部分。如果 rq->bio 为 NULL
,则请求绝对没有额外的工作要做。如果 rq->bio 非空,则需要额外的工作来完成请求。
-
void trace_block_rq_error(struct request *rq, blk_status_t error, unsigned int nr_bytes)¶
设备驱动程序报告的块 IO 操作错误
参数
struct request *rq
块操作请求
blk_status_t error
状态码
unsigned int nr_bytes
已完成字节数
描述
block_rq_error 跟踪点事件表示设备驱动程序报告的操作请求的某个部分已失败。
-
void trace_block_rq_insert(struct request *rq)¶
将块操作请求插入队列
参数
struct request *rq
块 IO 操作请求
描述
在块操作请求 rq 插入队列 q 之前立即调用。可以检查操作请求 rq 结构中的字段,以确定待处理操作将访问哪个设备和扇区。
-
void trace_block_rq_issue(struct request *rq)¶
向设备驱动程序发出待处理的块 IO 请求操作
参数
struct request *rq
块 IO 操作请求
描述
当来自队列 q 的块操作请求 rq 被发送到设备驱动程序进行处理时调用。
-
void trace_block_rq_merge(struct request *rq)¶
将请求与调度器中的另一个请求合并
参数
struct request *rq
块 IO 操作请求
描述
当来自队列 q 的块操作请求 rq 与调度器中排队的另一个请求合并时调用。
-
void trace_block_io_start(struct request *rq)¶
插入一个请求以供执行
参数
struct request *rq
块 IO 操作请求
描述
当块操作请求 rq 排队等待执行时调用
-
void trace_block_io_done(struct request *rq)¶
块 IO 操作请求完成
参数
struct request *rq
块 IO 操作请求
描述
当块操作请求 rq 完成时调用
参数
struct request_queue *q
持有块操作的队列
struct bio *bio
块操作已完成
描述
此跟踪点表明此块 IO 操作 bio 没有进一步的工作要做。
参数
struct bio *bio
要合并的新块操作
描述
将块请求 bio 合并到现有块请求的末尾。
参数
struct bio *bio
要合并的新块操作
描述
将块 IO 操作 bio 合并到现有块请求的开头。
参数
struct bio *bio
新块操作
描述
即将把块 IO 操作 bio 放入队列 q。
参数
struct bio *bio
待处理的块 IO 操作(可以是
NULL
)
描述
已分配一个请求结构来处理块 IO 操作 bio。
-
void trace_block_plug(struct request_queue *q)¶
将操作请求保留在请求队列中
参数
struct request_queue *q
要阻塞的请求队列
描述
阻塞请求队列 q。不允许将块操作请求发送到设备驱动程序。相反,在队列中累积请求以提高块设备的吞吐量性能。
-
void trace_block_unplug(struct request_queue *q, unsigned int depth, bool explicit)¶
释放请求队列中的操作请求
参数
struct request_queue *q
要解除阻塞的请求队列
unsigned int depth
刚刚添加到队列中的请求数量
bool explicit
这是否是显式解除阻塞,还是来自 schedule() 的解除阻塞
描述
解除阻塞请求队列 q,因为设备驱动程序已安排处理请求队列中的元素。
参数
struct bio *bio
正在拆分的块操作
unsigned int new_sector
新 bio 的起始扇区
描述
bio 请求 bio 需要拆分为两个 bio 请求。新创建的 bio 请求从 new_sector 开始。这种拆分可能是由于硬件限制(例如操作在 RAID 系统中跨越设备边界)而必需的。
参数
struct bio *bio
修订后的操作
dev_t dev
操作的原始设备
sector_t from
操作的原始扇区
描述
逻辑设备的某个操作已映射到原始块设备。
-
void trace_block_rq_remap(struct request *rq, dev_t dev, sector_t from)¶
映射块操作请求
参数
struct request *rq
块 IO 操作请求
dev_t dev
操作的设备
sector_t from
操作的原始扇区
描述
队列 q 中的块操作请求 rq 已重新映射。块操作请求 rq 包含当前信息,而 from 包含原始扇区。
工作队列¶
-
void trace_workqueue_queue_work(int req_cpu, struct pool_workqueue *pwq, struct work_struct *work)¶
当一个工作入队时调用
参数
int req_cpu
请求的 CPU
struct pool_workqueue *pwq
指向 struct pool_workqueue 的指针
struct work_struct *work
指向 struct work_struct 的指针
描述
此事件在工作立即入队时发生,或者在延迟工作实际入队到工作队列时(即:一旦达到延迟)发生。
-
void trace_workqueue_activate_work(struct work_struct *work)¶
当一个工作被激活时调用
参数
struct work_struct *work
指向 struct work_struct 的指针
描述
此事件在入队工作被放入活动队列时发生,这在入队后立即发生,除非达到 max_active 限制。
-
void trace_workqueue_execute_start(struct work_struct *work)¶
在工作队列回调之前立即调用
参数
struct work_struct *work
指向 struct work_struct 的指针
描述
允许跟踪工作队列的执行。
-
void trace_workqueue_execute_end(struct work_struct *work, work_func_t function)¶
在工作队列回调之后立即调用
参数
struct work_struct *work
指向 struct work_struct 的指针
work_func_t function
指向工作函数(worker function)的指针
描述
允许跟踪工作队列的执行。