PM 服務質量介面¶
此介面為驅動程式、子系統和使用者空間應用程式提供一個核心和使用者模式介面,用於註冊對一個或多個引數的效能期望。
- 有兩個不同的 PM QoS 框架可用
CPU 延遲 QoS。
每個裝置的 PM QoS 框架提供了用於管理每個裝置的延遲約束和 PM QoS 標誌的 API。
PM QoS 框架中使用的延遲單位是微秒 (usec)。
1. PM QoS 框架¶
維護著一個 CPU 延遲 QoS 請求的全域性列表,以及一個聚合的(有效的)目標值。聚合的目標值會隨著請求列表或列表元素的變化而更新。對於 CPU 延遲 QoS,聚合的目標值僅僅是列表元素中儲存的請求值的最小值。
注意:聚合的目標值實現為一個原子變數,因此讀取聚合值不需要任何鎖定機制。
從核心空間使用此介面很簡單
- void cpu_latency_qos_add_request(handle, target_value)
將一個元素插入到具有目標值的 CPU 延遲 QoS 列表中。在此列表發生更改時,將重新計算新的目標值,並且只有在目標值現在不同時,才會呼叫任何已註冊的通知程式。PM QoS 的客戶端需要儲存返回的控制代碼,以便將來在其他 PM QoS API 函式中使用。
- void cpu_latency_qos_update_request(handle, new_target_value)
將使用新的目標值更新由控制代碼指向的列表元素,並重新計算新的聚合目標,如果目標已更改,則呼叫通知樹。
- void cpu_latency_qos_remove_request(handle)
將刪除該元素。刪除後,它將更新聚合目標,並且如果刪除請求導致目標更改,則呼叫通知樹。
- int cpu_latency_qos_limit()
返回 CPU 延遲 QoS 的聚合值。
- int cpu_latency_qos_request_active(handle)
返回請求是否仍然有效,即是否尚未從 CPU 延遲 QoS 列表中刪除。
- int cpu_latency_qos_add_notifier(notifier)
將通知回撥函式新增到 CPU 延遲 QoS。當 CPU 延遲 QoS 的聚合值更改時,將呼叫該回調。
- int cpu_latency_qos_remove_notifier(notifier)
從 CPU 延遲 QoS 中刪除通知回撥函式。
從使用者空間
該基礎架構公開了一個裝置節點 /dev/cpu_dma_latency,用於 CPU 延遲 QoS。
只有程序可以註冊 PM QoS 請求。為了提供程序的自動清理,該介面要求程序按以下方式註冊其引數請求。
要註冊 CPU 延遲 QoS 的預設 PM QoS 目標,程序必須開啟 /dev/cpu_dma_latency。
只要裝置節點保持開啟,該程序就對該引數具有已註冊的請求。
要更改請求的目標值,程序需要將 s32 值寫入到開啟的裝置節點。或者,它可以寫入一個十六進位制字串,該值的格式為 10 個字元長,例如“0x12345678”。這會轉換為 cpu_latency_qos_update_request() 呼叫。
要刪除使用者模式的目標值請求,只需關閉裝置節點即可。
2. PM QoS 每個裝置的延遲和標誌框架¶
對於每個裝置,都有三個 PM QoS 請求列表。其中兩個列表與恢復延遲和活動狀態延遲容忍度(以微秒為單位)的聚合目標一起維護,第三個列表用於 PM QoS 標誌。這些值會響應請求列表的變化而更新。
恢復延遲和活動狀態延遲容忍度的目標值僅僅是引數列表元素中儲存的請求值的最小值。PM QoS 標誌的聚合值是所有列表元素值的收集(按位 OR)。當前定義了一個裝置 PM QoS 標誌:PM_QOS_FLAG_NO_POWER_OFF。
注意:聚合的目標值的實現方式使得讀取聚合值不需要任何鎖定機制。
從核心模式使用此介面的方式如下
- int dev_pm_qos_add_request(device, handle, type, value)
將一個元素插入到該標識裝置的列表中,並具有目標值。在此列表發生更改時,將重新計算新的目標值,並且只有在目標值現在不同時,才會呼叫任何已註冊的通知程式。dev_pm_qos 的客戶端需要儲存控制代碼,以便將來在其他 dev_pm_qos API 函式中使用。
- int dev_pm_qos_update_request(handle, new_value)
將使用新的目標值更新由控制代碼指向的列表元素,並重新計算新的聚合目標,如果目標已更改,則呼叫通知樹。
- int dev_pm_qos_remove_request(handle)
將刪除該元素。刪除後,它將更新聚合目標,並且如果刪除請求導致目標更改,則呼叫通知樹。
- s32 dev_pm_qos_read_value(device, type)
返回給定裝置的約束列表的聚合值。
- enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
根據給定的標誌掩碼檢查給定裝置的 PM QoS 標誌。返回值含義如下
- PM_QOS_FLAGS_ALL
設定了來自掩碼的所有標誌
- PM_QOS_FLAGS_SOME
設定了來自掩碼的某些標誌
- PM_QOS_FLAGS_NONE
未設定來自掩碼的任何標誌
- PM_QOS_FLAGS_UNDEFINED
尚未初始化裝置的 PM QoS 結構,或者請求列表為空。
- int dev_pm_qos_add_ancestor_request(dev, handle, type, value)
為給定裝置的第一個直接祖先新增 PM QoS 請求,該祖先的 power.ignore_children 標誌未設定(對於 DEV_PM_QOS_RESUME_LATENCY 請求)或其 power.set_latency_tolerance 回撥指標不為 NULL(對於 DEV_PM_QOS_LATENCY_TOLERANCE 請求)。
- int dev_pm_qos_expose_latency_limit(device, value)
將請求新增到裝置的恢復延遲約束的 PM QoS 列表,並在裝置的電源目錄下建立一個 sysfs 屬性 pm_qos_resume_latency_us,允許使用者空間操作該請求。
- void dev_pm_qos_hide_latency_limit(device)
從裝置的恢復延遲約束的 PM QoS 列表中刪除由 dev_pm_qos_expose_latency_limit() 新增的請求,並從裝置的電源目錄中刪除 sysfs 屬性 pm_qos_resume_latency_us。
- int dev_pm_qos_expose_flags(device, value)
將請求新增到裝置的標誌的 PM QoS 列表,並在裝置的電源目錄下建立一個 sysfs 屬性 pm_qos_no_power_off,允許使用者空間更改 PM_QOS_FLAG_NO_POWER_OFF 標誌的值。
- void dev_pm_qos_hide_flags(device)
從裝置的標誌的 PM QoS 列表中刪除由 dev_pm_qos_expose_flags() 新增的請求,並從裝置的電源目錄中刪除 sysfs 屬性 pm_qos_no_power_off。
通知機制
每個裝置的 PM QoS 框架都有一個每個裝置的通知樹。
- int dev_pm_qos_add_notifier(device, notifier, type)
為裝置的特定請求型別新增通知回撥函式。
當裝置約束列表的聚合值更改時,將呼叫該回調。
- int dev_pm_qos_remove_notifier(device, notifier, type)
刪除裝置的通知回撥函式。
活動狀態延遲容忍度¶
此裝置 PM QoS 型別用於支援硬體可以動態切換到節能操作模式的系統。在這些系統中,如果硬體選擇的操作模式嘗試以過於激進的方式節省能源,則可能會導致軟體看到過多的延遲,導致軟體錯過某些協議要求或目標幀或採樣率等。
如果軟體可以使用給定裝置的延遲容忍度控制機制,則應填充該裝置的 dev_pm_info 結構中的 .set_latency_tolerance 回撥。它指向的例程應實現將有效需求值傳輸到硬體所需的任何操作。
每當裝置的有效延遲容忍度更改時,將執行其 .set_latency_tolerance() 回撥,並將有效值傳遞給它。如果該值為負數,這意味著該裝置的延遲容忍度需求列表為空,則回撥應將底層硬體延遲容忍度控制機制切換到自主模式(如果可用)。反之,如果該值為 PM_QOS_LATENCY_ANY,並且硬體支援特殊的“無要求”設定,則回撥應使用它。這允許軟體阻止硬體自動更新裝置的延遲容忍度以響應其電源狀態變化(例如,在從 D3cold 到 D0 的轉換過程中),這通常可以在自主延遲容忍度控制模式下完成。
如果裝置存在 .set_latency_tolerance(),則 sysfs 屬性 pm_qos_latency_tolerance_us 將出現在裝置的電源目錄中。然後,使用者空間可以使用該屬性來指定其對裝置的延遲容忍度要求(如果有)。寫入“any”表示“無要求,但不要讓硬體控制延遲容忍度”,寫入“auto”允許硬體切換到自主模式,如果裝置的列表中沒有來自核心端的其他要求。
核心程式碼可以使用上面描述的函式以及 DEV_PM_QOS_LATENCY_TOLERANCE 裝置 PM QoS 型別來新增、刪除和更新裝置的延遲容忍度要求。