2017-10-06 27 views
1

我正在寫一些內核驅動程序,我需要檢查哪個線程在另一個核心上的某個點上運行。我的驅動程序在每個內核上運行一個內核線程,我需要不時同步一些線程來完成某些任務。我可以從調試日誌中觀察到有時一個線程太多地等待其他線程。我做了一些補丁,我將__preempt_count存儲在其他內核上,以檢查是否有softirq/hardirq或搶佔失效延遲我的線程。 我還使用FTRACE檢查irqsoff和preemptirqsoff,以關閉IRQ的最大持續時間並禁用先佔權。在基於SMP的linux系統中訪問另一個cpu的「current_task」指針

到現在爲止,我能夠發現kerneloops線程,這是禁用中斷高達20毫秒,我發現太長。 做了一個systemctl disable kerneloops並擺脫了這個問題。

現在我似乎處理一些搶先禁用窗口。對於未來的驅動程序分析,我需要一種方法來確定哪些線程正在其他內核的特定時間點執行。我試圖用FTRACE主要與IRQ進入/退出事件,我也用trace_printk推一些調試日誌中ftrace緩衝區有一個日誌一切,等

然而,有一兩件事,我會喜歡做的是訪問其他內核的current_task結構(current ptr)並打印comm字段,該字段給出任務的名稱(或pid值)。 但是我很難完成這件事。

對於__preempt_count我沒有問題:

int *p = per_cpu_ptr(&__preempt_count,cpu); 
pr_info("Preempt count of cpu%u is 0x%08x\n",cpu,*p); 

到目前爲止,我曾與聲明或每CPU變量訪問沒有問題,但由於某些原因,current_task指針試圖訪問它時,會觸發頁面錯誤。

char buf[10]; 
struct task_struct *task = per_cpu_ptr(current_task,cpu); 
snprintf(buf,8,"%s",task->comm); 
pr_info("Task name: %s",buf); 

以上代碼總是觸發頁面錯誤,NULL PTR喇嘛喇嘛。 直到現在我找不到原因。我試圖打印task的指針值,我得到了相同的頁面錯誤。

可能是因爲該地址無法被其他內核訪問?在內核空間中不應該是這種情況。到目前爲止,我還沒有發現每個核心變量的問題,我在這方面發揮了很大的作用。

底線:訪問其他內核的current_task並打印comm/pid字段的正確方法是什麼?

非常感謝,

丹尼爾

回答

0

我終於想通了,什麼是錯的。 __preempt_countcurrent_task之間的區別是第一個被定義爲一個int變量,而第二個被定義爲結構的指針。換句話說,第一個被定義爲一個變量,第二個被定義爲一個指針。

現在,深入瞭解每個cpu變量,它們只是編譯器在單獨的內存位置(如數組)中分配的變量。當調用變量Foo的per_cpu_ptr時,宏將計算類似Foo[cpu]的東西,但這意味着per_cpu_ptr需要變量的實際基地址,即&,以便它可以計算從此開始的相對地址值。

申報時間:foo = per_cpu_ptr(&__preempt_count,cpu),這個地址已經給出= &__preempt_count

申報時間:bar = per_cpu_ptr(current_task,cpu),該地址沒有給出,因爲&丟失在這裏。 current_task是一個指針,但不是current_task數組的基地址。

在上述兩種情況下,參數per_cpu_ptr都是一個指針,但在這裏我的理解是錯誤的,我不清楚實際上我需要傳遞的變量的指針,現在很明顯:我必須通過變量的基地址(var或指針無關緊要),以便宏可以計算該cpu的相對地址。

因此右接近於工作是:

bar = per_cpu(current_task,cpu)這轉化爲*per_cpu_var(&current_task,cpu)

直接

bar = *per_cpu_var(&current_task,cpu);

相關問題