Workqueue Introduction

前幾天在公司收到一題analyze performance的issue

後來比對了前後兩份log,看到kworker這些threads兩份行為不太一樣,有一份的kworker一直wake up然後preempt cpu resource,看了很欠揍,但我也不知道kworker到底是三小,所以上網查了一下跟trace code QQ

(雖然這題issue最後”應該”不是kworker的問題XD)


在kernel space中,driver都不太傾向自己創建一個thread去處理自己的任務,所以workqueue在這裡起了很大的作用,workqueue會收集各式各樣不同的driver丟過來的工作,可以節省很多resource(一個共享經濟的概念),透過process context的模式來處理這些work。

有個東西跟workqueue很像的概念叫tasklet,但它屬於interrupt context,如果今天driver來的事情很急且很小的話就適合tasklet,這樣比較貼近interrupt的使用。但不急不趕甚至要做的事情比較多就可以用workqueue,畢竟workqueue屬於process,是可以接受被scheduler排程的,甚至是sleep。

下面是一些名詞介紹。


work: 託付要執行的任務。


workqueue: 擺放工作的queue,蠻好理解的XD。


work_pool: worker工人的集合代表,一個類似ASUS Talent pool的概念XD。-


worker: kernel創建出來的worker,worker會從workqueue,去拉work出來做,如果沒有任何工作worker會先idle一段時間再進入sleep,工人的數量kernel會依據work的數量做動態的增減。


慣老闆我手上的s6工人滿滿阿…


Data Struct

這邊只貼這個惹

把work加入workqueue的方式好像有兩種,如下:

INIT_WORK(_work, _func) => schedule_work(_work)

INIT_DELAYED_WORK(_work, _func)   =>schedule_delayed_work(_work)

前面都是做work初始化的動作,後面是把work加入workqueue,第二種是希望這個work可以延遲一段時間在執行,延遲的時間大概跟他DS中的timer有關係。

之後就交給worker來處理了吧?,看到kworker醒來大概是同事的code裡面有一直丟work的樣子,那時候trace code好像有看到struct work的variable…

這篇先打這樣好了,最近快把自己操死了,上週騎自行車昨天又跑了快九公里的慢跑(雖然今天只跑了四公里多XD),之後再看看要打啥,HIDL好像真的蠻多人看,幾乎天天都有人看。