Linux 核心跟蹤點 API

作者:

Jason Baron

作者:

William Cohen

簡介

跟蹤點是位於核心中關鍵點的靜態探測點。“探測器”透過回撥機制向跟蹤點註冊/登出。這些“探測器”是嚴格型別化的函式,它們被傳遞由每個跟蹤點定義的一組唯一引數。

透過這種簡單的回撥機制,“探測器”可用於分析、除錯和理解核心行為。有許多工具提供了使用“探測器”的框架。這些工具包括 Systemtap、ftrace 和 LTTng。

跟蹤點透過各種宏定義在多個頭檔案中。因此,本文件的目的是清晰地說明所有可用的跟蹤點。其目的是不僅要了解哪些跟蹤點可用,還要了解未來可能在何處新增跟蹤點。

所呈現的 API 具有以下形式的函式:trace_tracepointname(function parameters)。這些是程式碼中隨處可見的跟蹤點回調。在 Documentation/trace/* 目錄中介紹了在這些回撥站點註冊和登出探測點的內容。

IRQ

void trace_irq_handler_entry(int irq, struct irqaction *action)

在 irq 動作處理程式之前立即呼叫

引數

int irq

irq 號

struct irqaction *action

指向 struct irqaction 的指標

描述

action 指向的 struct irqaction 包含有關處理程式的各種資訊,包括裝置名稱 action->name 和裝置 ID action->dev_id。與 irq_handler_exit 跟蹤點結合使用時,我們可以計算出 irq 處理程式的延遲。

void trace_irq_handler_exit(int irq, struct irqaction *action, int ret)

在 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)

標記緩衝區髒

引數

struct buffer_head *bh

正在變髒的 buffer_head

描述

mark_buffer_dirty() 呼叫。

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->bioNULL,則請求絕對沒有額外的工作要做。如果 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 完成時呼叫

void trace_block_bio_complete(struct request_queue *q, struct bio *bio)

完成塊操作的所有工作

引數

struct request_queue *q

持有塊操作的佇列

struct bio *bio

塊操作已完成

描述

此跟蹤點表明此塊 IO 操作 bio 沒有進一步的工作要做。

void trace_block_bio_backmerge(struct bio *bio)

將塊操作合併到現有操作的末尾

引數

struct bio *bio

要合併的新塊操作

描述

將塊請求 bio 合併到現有塊請求的末尾。

void trace_block_bio_frontmerge(struct bio *bio)

將塊操作合併到現有操作的開頭

引數

struct bio *bio

要合併的新塊操作

描述

將塊 IO 操作 bio 合併到現有塊請求的開頭。

void trace_block_bio_queue(struct bio *bio)

將新的塊 IO 操作放入佇列

引數

struct bio *bio

新塊操作

描述

即將把塊 IO 操作 bio 放入佇列 q

void trace_block_getrq(struct bio *bio)

在佇列中獲取一個用於塊 IO 操作的空閒請求條目

引數

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,因為裝置驅動程式已安排處理請求佇列中的元素。

void trace_block_split(struct bio *bio, unsigned int new_sector)

將單個 bio 結構拆分為兩個 bio 結構

引數

struct bio *bio

正在拆分的塊操作

unsigned int new_sector

新 bio 的起始扇區

描述

bio 請求 bio 需要拆分為兩個 bio 請求。新建立的 bio 請求從 new_sector 開始。這種拆分可能是由於硬體限制(例如操作在 RAID 系統中跨越裝置邊界)而必需的。

void trace_block_bio_remap(struct bio *bio, dev_t dev, sector_t from)

將邏輯裝置的請求對映到原始裝置

引數

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)的指標

描述

允許跟蹤工作佇列的執行。