国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Linux PM QoS framework(2)_PM QoS class

2019-11-09 17:37:49
字體:
來源:轉載
供稿:網友

本文轉自:http://www.wowotech.net/pm_subsystem/pm_qos_class.html

linux PM QoS framework(2)_PM QoS class

作者:wowo 發布于:2015-2-10 23:09 分類:電源管理子系統

1. 前言

回顧上一篇文章(Linux PM QoS framework(1)_概述和軟件架構),PM QoS framework抽象出4個系統級別的QoS constraint(統稱為PM QoS class),分別是cpu&dma latency、network latency、network throughput和memory bandwidth。并提供一系列的接口,動態的搜集、整理系統對這些constraint的需求情況。

2. API匯整

PM QoS class framework提供的API有2類:一類是以函數調用的形式,為kernel space的driver、service等提供的;另一類是以misc設備的形式,為用戶空間進程提供的。

2.1 向kernel其它driver提供的,用于提出PM QoS需求的API

void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class,                         s32 value); void pm_qos_update_request(struct pm_qos_request *req,                            s32 new_value); void pm_qos_update_request_timeout(struct pm_qos_request *req,                                    s32 new_value, unsigned long timeout_us); void pm_qos_remove_request(struct pm_qos_request *req);

int pm_qos_request_active(struct pm_qos_request *req);

1)pm_qos_add_request

該接口用于向PM QoS framework添加一個QoS請求,pm_qos_class為QoS請求的類型(kernel稱作pm qos class),value為期望的QoS值,不同的class有不同的含義。pm qos class的定義如下:

   1: /* include/linux/pm_qos.h */
   2: enum {
   3:         PM_QOS_RESERVED = 0,
   4:         PM_QOS_CPU_DMA_LATENCY,
   5:         PM_QOS_NETWORK_LATENCY,
   6:         PM_QOS_NETWORK_THROUGHPUT,
   7:         PM_QOS_MEMORY_BANDWIDTH,
   8:  
   9:         /* insert new class ID */
  10:         PM_QOS_NUM_CLASSES,
  11: };

PM_QOS_CPU_DMA_LATENCY,CPU和DMA的延遲(單位為us),它的實際意義是,當產生一個事件之后(如一個中斷),CPU或DMA的響應延遲。例如有些CPU的串口控制器,只有幾個byte的FIFO,當接收數據時,CPU或DMA必須在FIFO填滿前,將數據讀走,否則就可能丟失數據或者降低數據的傳輸速率。

后面幾個class,不再詳細說明。

以PM_QOS_CPU_DMA_LATENCY為例,pm_qos_add_request的邏輯可以總結為:我要求CPU&DMA的latency不大于‘value’個us。

另外,為了便于對已添加請求的維護(修改、移除等),framework會將該請求保存在一個句柄中,就是第一個參數--struct pm_qos_request指針。調用者不需要知道該結構的具體內容,只要定義一個變量,并把指針傳給pm_qos_add_request接口,以后使用該指針進行修改、移除等操作。

2)pm_qos_update_request/pm_qos_update_request_timeout

如果應用場景改變(如串口波特率變大,相應的響應延遲就要變小),可以通過該接口更新QoS請求。req為句柄指針,new_value為新的value。

pm_qos_update_request_timeout多了一個timeout參數,用于需要在一段時間(timeout時間)內修改QoS value的場景。framework會在timeout后,自動將QoS value修改為一個默認值(一般為無效值,代表不再對該QoS有要求)。

3)pm_qos_remove_request

如果對該pm qos class不再有要求,則可以調用該接口將請求移除。

4)pm_qos_request_active

該接口可以獲取某一個QoS請求的active狀態。

2.2 向kernel PM有關的service提供的,用于獲取、跟蹤指定PM QoS需求的API

int pm_qos_request(int pm_qos_class); int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier); int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier); 

每當有新的QoS請求時。framework都會根據該QoS class的含義,計算出滿足所有請求的一個極值(如最大值、最小值等等)。該值可以通過pm_qos_request接口獲得。例如cpuidle framework在選擇C state時,會通過該接口獲得系統對CPU&DMA latency的需求,并保證從C state返回時的延遲小于該value。

另外,如果某個實體在意某一個class的QoS value變化,可以通過pm_qos_add_notifier接口添加一個notifier,這樣當value變化時,framework便會通過notifier的回調函數,通知該實體。

同理,pm_qos_remove_notifier用于刪除notifier。

2.3 向per-device PM QoS framework提供,low level的PM QoS操作API

int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,                          enum pm_qos_req_action action, int value); bool pm_qos_update_flags(struct pm_qos_flags *pqf,                          struct pm_qos_flags_request *req,                          enum pm_qos_req_action action, s32 val);

s32 pm_qos_read_value(struct pm_qos_constraints *c);

QoS class和per-device PM QoS都是基于底層的pm qos constraint封裝而來的。對QoS class的使用者而言,可以不用關心這些底層細節。對per-device PM QoS framework而言,則需要利用它們實現自身的功能。

這些接口就是提供給per-device PM QoS framework的low level接口,后面再詳細介紹。

2.4 向用戶空間PRocess提供的,用于提出QoS需求的API

根據不同的PM QoS class,包括(cpu&dma latency、network latency等等):

/dev/cpu_dma_latency /dev/network_latency /dev/network_throughput /dev/memory_bandwidth 

打開文件,將會使用默認值向PM QoS framework添加一個QoS請求;關閉文件,會移除相應的請求;寫入value,更改請求的值;讀取文件,將會獲取QoS的極值。

具體和2.1中的各個接口類似,不再詳細說明了。

3. 實現思路和內部邏輯

3.1 主要數據結構

1)struct pm_qos_request,pm qos request句柄,用于request的add、update、remove等操作

   1: struct pm_qos_request {
   2:         struct plist_node node;
   3:         int pm_qos_class;
   4:         struct delayed_work work; /* for pm_qos_update_request_timeout */
   5: };

node,一個struct plist_node類型的節點,在保存request的value值(node.prio)的同時,可以將request按照一定的順序,保存在一個全局的鏈表中;

pm_qos_class,該request對應的qos class,可以為PM_QOS_CPU_DMA_LATENCY、PM_QOS_NETWORK_LATENCY、PM_QOS_NETWORK_THROUGHPUT、PM_QOS_MEMORY_BANDWIDTH中的一種;

一個delay work,用于實現pm_qos_update_request_timeout接口。

struct plist_node是一個按照優先級(prio)降序排列的雙向鏈表(Descending-priority-sorted double-linked),除了常規鏈表所具備的head和tail之外,有一個prio字段,剛好可以應用在PM QoS class的場景中。

2)struct pm_qos_constraints,pm qos的內部抽象,用于抽象某一特定的PM QoS class

   1: struct pm_qos_constraints {
   2:         struct plist_head list;
   3:         s32 target_value;       /* Do not change to 64 bit */
   4:         s32 default_value;
   5:         s32 no_constraint_value;
   6:         enum pm_qos_type type;
   7:         struct blocking_notifier_head *notifiers;
   8: };

list,鏈表頭,所有該class的request,都會掛到該list上;

target_value,該constraint的目標值,即可以滿足所有該class的request那個value。通常情況下,根據request的類型(enum pm_qos_type),可以是所有request中的最大值,所有request中的最小值,或者所有request的和;

default_value,該constraint的默認值,通常為0,表示沒有限制(或沒有要求);

no_constraint_value,當該class的qos不存在請求時,pm_qos_get_value返回的值,通常為默認值,表示沒有限制(或沒有要求);

type,該constraint的類型,具體請參考下面的描述;

notifiers,用于constraint value改變時通知其它driver。

enum pm_qos_type包括PM_QOS_MAX、PM_QOS_MIN和PM_QOS_SUM。PM_QOS_MAX表示在所有的request中取最大值,即可滿足所有的request,如network_throughput;PM_QOS_MIN表示在所有的request中取最小值,即可滿足所有的request,如cpu_dma_latency;PM_QOS_SUM表示在所有的request中取和,才能滿足所有的request,如memory_bandwidth。

當調用pm_qos_get_value接口時,framework會更具qos type,從list head中,取最小值、最大值或者所有值的和。

3.2 實現邏輯

QoS class framework為每個class定義了一個全局的struct pm_qos_constraints變量,用于保存所有該class的request。同時為每個class定義一個misc device變量,用于向用戶空間提供接口。最終,將這些信息組織在一個內部的數據結構中(struct pm_qos_object),如下(具體內容可參考kernel/power/qos.c,這里不再詳細介紹):

   1: struct pm_qos_object {
   2:         struct pm_qos_constraints *constraints;
   3:         struct miscdevice pm_qos_power_miscdev;
   4:         char *name;
   5: };
   6:  
   7: ...
   8:  
   9: static struct pm_qos_object *pm_qos_array[] = {
  10:         &null_pm_qos,
  11:         &cpu_dma_pm_qos,
  12:         &network_lat_pm_qos,
  13:         &network_throughput_pm_qos,
  14:         &memory_bandwidth_pm_qos,
  15: };

 

1)pm_qos_add_request

request add接口會以qos class為index,從qos array中取出constraint指針(pm_qos_array[pm_qos_class]->constraints),并指針和request的value為參數,調用pm_qos_update_target接口。

pm_qos_update_target會將該request添加到constraint的list中,并根據qos type,計算處該class qos的target value。

pm_qos_update_request/pm_qos_update_request_timeout的邏輯類似,不再詳細描述。

2)pm_qos_request

直接從該class對應的constraint變量中,獲取target value(已經在新的request被add之后更新)。

3)misc設備注冊

當kernel會在QoS class framework的初始化接口(pm_qos_power_init)中,調用misc_register,將各個class的miscdevice變量,注冊到kernel中。misc設備提供了open、release、read、write等接口(pm_qos_power_fops,具體可參考源文件),用于qos的request、update和remove。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广德县| 泰和县| 来凤县| 溧水县| 辽阳市| 冷水江市| 金溪县| 达拉特旗| 秦安县| 绍兴市| 福泉市| 禹城市| 榆树市| 安阳市| 宁武县| 屏东县| 麻江县| 和静县| 平潭县| 安义县| 新田县| 鹤峰县| 全南县| 乌拉特中旗| 略阳县| 深州市| 房山区| 湟中县| 图木舒克市| 武威市| 永清县| 河源市| 东乌珠穆沁旗| 万载县| 金川县| 驻马店市| 土默特左旗| 正蓝旗| 耿马| 环江| 永州市|