← Documents Documentation/power/pm_qos_interface.rst GitHub 원문 ↗

Linux 6.18.37 · Power

PM Quality Of Service Interface

CPU latency와 장치별 resume·active-state latency 및 flag 요청의 집계, notifier, sysfs, 특별값 처리 규칙을 설명합니다.

Source pathDocumentation/power/pm_qos_interface.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

pm_qos_interface.rst:1-211

PM QoS는 여러 요청 중 가장 엄격한 latency를 선택하고 flag 요구를 합쳐 유효값을 만듭니다. Handle 수명, 값 변경 때만 발생하는 notification, `any`와 `auto`의 제어권 차이를 이해하는 것이 핵심입니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ===============================
2 PM Quality Of Service Interface
3 ===============================
4
5 This interface provides a kernel and user mode interface for registering
6 performance expectations by drivers, subsystems and user space applications on
7 one of the parameters.
8
9 Two different PM QoS frameworks are available:
10 * CPU latency QoS.
11 * The per-device PM QoS framework provides the API to manage the
12 per-device latency constraints and PM QoS flags.
13
14 The latency unit used in the PM QoS framework is the microsecond (usec).
15
16
17 1. PM QoS framework
18 ===================
19
20 A global list of CPU latency QoS requests is maintained along with an aggregated
21 (effective) target value. The aggregated target value is updated with changes
22 to the request list or elements of the list. For CPU latency QoS, the
23 aggregated target value is simply the min of the request values held in the list
24 elements.
25
26 Note: the aggregated target value is implemented as an atomic variable so that
27 reading the aggregated value does not require any locking mechanism.
28
29 From kernel space the use of this interface is simple:
30
31 void cpu_latency_qos_add_request(handle, target_value):
32 Will insert an element into the CPU latency QoS list with the target value.
33 Upon change to this list the new target is recomputed and any registered
34 notifiers are called only if the target value is now different.
35 Clients of PM QoS need to save the returned handle for future use in other
36 PM QoS API functions.
37
38 void cpu_latency_qos_update_request(handle, new_target_value):
39 Will update the list element pointed to by the handle with the new target
40 value and recompute the new aggregated target, calling the notification tree
41 if the target is changed.
42
43 void cpu_latency_qos_remove_request(handle):
44 Will remove the element. After removal it will update the aggregate target
45 and call the notification tree if the target was changed as a result of
46 removing the request.
47
48 int cpu_latency_qos_limit():
49 Returns the aggregated value for the CPU latency QoS.
50
51 int cpu_latency_qos_request_active(handle):
52 Returns if the request is still active, i.e. it has not been removed from the
53 CPU latency QoS list.
54
55
56 From user space:
57
58 The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU
59 latency QoS.
60
61 Only processes can register a PM QoS request. To provide for automatic
62 cleanup of a process, the interface requires the process to register its
63 parameter requests as follows.
64
65 To register the default PM QoS target for the CPU latency QoS, the process must
66 open /dev/cpu_dma_latency.
67
68 As long as the device node is held open that process has a registered
69 request on the parameter.
70
71 To change the requested target value, the process needs to write an s32 value to
72 the open device node. Alternatively, it can write a hex string for the value
73 using the 10 char long format e.g. "0x12345678". This translates to a
74 cpu_latency_qos_update_request() call.
75
76 To remove the user mode request for a target value simply close the device
77 node.
78
79
80 2. PM QoS per-device latency and flags framework
81 ================================================
82
83 For each device, there are three lists of PM QoS requests. Two of them are
84 maintained along with the aggregated targets of resume latency and active
85 state latency tolerance (in microseconds) and the third one is for PM QoS flags.
86 Values are updated in response to changes of the request list.
87
88 The target values of resume latency and active state latency tolerance are
89 simply the minimum of the request values held in the parameter list elements.
90 The PM QoS flags aggregate value is a gather (bitwise OR) of all list elements'
91 values. One device PM QoS flag is defined currently: PM_QOS_FLAG_NO_POWER_OFF.
92
93 Note: The aggregated target values are implemented in such a way that reading
94 the aggregated value does not require any locking mechanism.
95
96
97 From kernel mode the use of this interface is the following:
98
99 int dev_pm_qos_add_request(device, handle, type, value):
100 Will insert an element into the list for that identified device with the
101 target value. Upon change to this list the new target is recomputed and any
102 registered notifiers are called only if the target value is now different.
103 Clients of dev_pm_qos need to save the handle for future use in other
104 dev_pm_qos API functions.
105
106 int dev_pm_qos_update_request(handle, new_value):
107 Will update the list element pointed to by the handle with the new target
108 value and recompute the new aggregated target, calling the notification
109 trees if the target is changed.
110
111 int dev_pm_qos_remove_request(handle):
112 Will remove the element. After removal it will update the aggregate target
113 and call the notification trees if the target was changed as a result of
114 removing the request.
115
116 s32 dev_pm_qos_read_value(device, type):
117 Returns the aggregated value for a given device's constraints list.
118
119 enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
120 Check PM QoS flags of the given device against the given mask of flags.
121 The meaning of the return values is as follows:
122
123 PM_QOS_FLAGS_ALL:
124 All flags from the mask are set
125 PM_QOS_FLAGS_SOME:
126 Some flags from the mask are set
127 PM_QOS_FLAGS_NONE:
128 No flags from the mask are set
129 PM_QOS_FLAGS_UNDEFINED:
130 The device's PM QoS structure has not been initialized
131 or the list of requests is empty.
132
133 int dev_pm_qos_add_ancestor_request(dev, handle, type, value)
134 Add a PM QoS request for the first direct ancestor of the given device whose
135 power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests)
136 or whose power.set_latency_tolerance callback pointer is not NULL (for
137 DEV_PM_QOS_LATENCY_TOLERANCE requests).
138
139 int dev_pm_qos_expose_latency_limit(device, value)
140 Add a request to the device's PM QoS list of resume latency constraints and
141 create a sysfs attribute pm_qos_resume_latency_us under the device's power
142 directory allowing user space to manipulate that request.
143
144 void dev_pm_qos_hide_latency_limit(device)
145 Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
146 PM QoS list of resume latency constraints and remove sysfs attribute
147 pm_qos_resume_latency_us from the device's power directory.
148
149 int dev_pm_qos_expose_flags(device, value)
150 Add a request to the device's PM QoS list of flags and create sysfs attribute
151 pm_qos_no_power_off under the device's power directory allowing user space to
152 change the value of the PM_QOS_FLAG_NO_POWER_OFF flag.
153
154 void dev_pm_qos_hide_flags(device)
155 Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS
156 list of flags and remove sysfs attribute pm_qos_no_power_off from the device's
157 power directory.
158
159 Notification mechanisms:
160
161 The per-device PM QoS framework has a per-device notification tree.
162
163 int dev_pm_qos_add_notifier(device, notifier, type):
164 Adds a notification callback function for the device for a particular request
165 type.
166
167 The callback is called when the aggregated value of the device constraints
168 list is changed.
169
170 int dev_pm_qos_remove_notifier(device, notifier, type):
171 Removes the notification callback function for the device.
172
173
174 Active state latency tolerance
175 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
176
177 This device PM QoS type is used to support systems in which hardware may switch
178 to energy-saving operation modes on the fly. In those systems, if the operation
179 mode chosen by the hardware attempts to save energy in an overly aggressive way,
180 it may cause excess latencies to be visible to software, causing it to miss
181 certain protocol requirements or target frame or sample rates etc.
182
183 If there is a latency tolerance control mechanism for a given device available
184 to software, the .set_latency_tolerance callback in that device's dev_pm_info
185 structure should be populated. The routine pointed to by it is should implement
186 whatever is necessary to transfer the effective requirement value to the
187 hardware.
188
189 Whenever the effective latency tolerance changes for the device, its
190 .set_latency_tolerance() callback will be executed and the effective value will
191 be passed to it. If that value is negative, which means that the list of
192 latency tolerance requirements for the device is empty, the callback is expected
193 to switch the underlying hardware latency tolerance control mechanism to an
194 autonomous mode if available. If that value is PM_QOS_LATENCY_ANY, in turn, and
195 the hardware supports a special "no requirement" setting, the callback is
196 expected to use it. That allows software to prevent the hardware from
197 automatically updating the device's latency tolerance in response to its power
198 state changes (e.g. during transitions from D3cold to D0), which generally may
199 be done in the autonomous latency tolerance control mode.
200
201 If .set_latency_tolerance() is present for the device, sysfs attribute
202 pm_qos_latency_tolerance_us will be present in the devivce's power directory.
203 Then, user space can use that attribute to specify its latency tolerance
204 requirement for the device, if any. Writing "any" to it means "no requirement,
205 but do not let the hardware control latency tolerance" and writing "auto" to it
206 allows the hardware to be switched to the autonomous mode if there are no other
207 requirements from the kernel side in the device's list.
208
209 Kernel code can use the functions described above along with the
210 DEV_PM_QOS_LATENCY_TOLERANCE device PM QoS type to add, remove and update
211 latency tolerance requirements for devices.
212

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

PM QoS 개요

1-16

이 인터페이스는 드라이버, 서브시스템, 사용자 공간 애플리케이션이 특정 매개변수에 대한 성능 기대치를 등록할 수 있도록 커널 모드와 사용자 모드 인터페이스를 제공합니다.

사용 가능한 프레임워크는 CPU latency QoS와 장치별 PM QoS입니다. 장치별 프레임워크는 장치의 latency constraint와 PM QoS flag를 관리하는 API를 제공합니다.

PM QoS 프레임워크에서 latency의 단위는 microsecond(usec)입니다.

PM QoS 프레임워크
범위관리 대상단위
CPU 전체CPU latency QoS requestmicrosecond
개별 장치resume latency, active-state latency tolerance, flagsmicrosecond 또는 flag

전역 CPU 지연 요구와 장치별 요구를 별도로 집계합니다.

===============================
PM Quality Of Service Interface
===============================

This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
one of the parameters.

Two different PM QoS frameworks are available:
 * CPU latency QoS.
 * The per-device PM QoS framework provides the API to manage the
   per-device latency constraints and PM QoS flags.

The latency unit used in the PM QoS framework is the microsecond (usec).

CPU latency QoS와 커널 API

17-55

CPU latency QoS request의 전역 목록과 집계된 유효 target 값을 함께 유지합니다. 요청 목록이나 목록 원소가 바뀔 때 target을 갱신하며, CPU latency QoS의 유효값은 목록에 들어 있는 요청값 중 최솟값입니다.

집계 target은 atomic variable로 구현되므로 값을 읽을 때 locking mechanism이 필요하지 않습니다.

`cpu_latency_qos_add_request(handle, target_value)`는 target 값으로 새 원소를 CPU latency QoS 목록에 넣습니다. 목록 변경 후 target을 다시 계산하고 값이 실제로 달라졌을 때만 등록된 notifier를 호출합니다. 클라이언트는 다른 PM QoS API에서 사용하도록 반환된 handle을 보관해야 합니다.

`cpu_latency_qos_update_request(handle, new_target_value)`는 handle이 가리키는 목록 원소를 새 target으로 갱신하고 집계 target을 다시 계산합니다. 집계값이 바뀌면 notification tree를 호출합니다.

`cpu_latency_qos_remove_request(handle)`는 원소를 제거한 뒤 집계 target을 갱신하고, 제거로 값이 달라진 경우 notification tree를 호출합니다.

`cpu_latency_qos_limit()`는 CPU latency QoS의 집계값을 반환합니다. `cpu_latency_qos_request_active(handle)`는 요청이 목록에서 제거되지 않고 여전히 active인지 반환합니다.

CPU latency 집계
add / update / remove requestrecompute minimumatomic effective targetnotify only when changed

모든 변경은 최솟값을 다시 계산한 뒤 변화가 있을 때만 알립니다.

CPU latency 커널 API
API동작
cpu_latency_qos_add_request요청 추가와 handle 보관
cpu_latency_qos_update_request요청값 변경
cpu_latency_qos_remove_request요청 제거
cpu_latency_qos_limit집계 최솟값 조회
cpu_latency_qos_request_active요청 활성 여부 조회

Handle은 요청의 전체 수명 동안 유지합니다.

1. PM QoS framework
===================

A global list of CPU latency QoS requests is maintained along with an aggregated
(effective) target value.  The aggregated target value is updated with changes
to the request list or elements of the list.  For CPU latency QoS, the
aggregated target value is simply the min of the request values held in the list
elements.

Note: the aggregated target value is implemented as an atomic variable so that
reading the aggregated value does not require any locking mechanism.

From kernel space the use of this interface is simple:

void cpu_latency_qos_add_request(handle, target_value):
  Will insert an element into the CPU latency QoS list with the target value.
  Upon change to this list the new target is recomputed and any registered
  notifiers are called only if the target value is now different.
  Clients of PM QoS need to save the returned handle for future use in other
  PM QoS API functions.

void cpu_latency_qos_update_request(handle, new_target_value):
  Will update the list element pointed to by the handle with the new target
  value and recompute the new aggregated target, calling the notification tree
  if the target is changed.

void cpu_latency_qos_remove_request(handle):
  Will remove the element.  After removal it will update the aggregate target
  and call the notification tree if the target was changed as a result of
  removing the request.

int cpu_latency_qos_limit():
  Returns the aggregated value for the CPU latency QoS.

int cpu_latency_qos_request_active(handle):
  Returns if the request is still active, i.e. it has not been removed from the
  CPU latency QoS list.

사용자 공간 CPU latency 요청

56-79

CPU latency QoS를 위해 `/dev/cpu_dma_latency` 장치 노드 하나를 노출합니다. PM QoS request는 process만 등록할 수 있으며, process 종료 시 자동으로 정리되도록 열린 파일의 수명과 요청의 수명을 연결합니다.

기본 CPU latency QoS target을 등록하려면 process가 `/dev/cpu_dma_latency`를 엽니다. 장치 노드를 열어 둔 동안 해당 process의 요청이 등록된 상태로 유지됩니다.

요청 target을 바꾸려면 열린 장치 노드에 `s32` 값을 씁니다. 또는 `"0x12345678"`처럼 10자 형식의 16진 문자열을 쓸 수 있으며, 이는 `cpu_latency_qos_update_request()` 호출로 변환됩니다.

사용자 모드 target 요청을 제거하려면 장치 노드를 닫기만 하면 됩니다.

사용자 공간 요청 수명
open /dev/cpu_dma_latencydefault request registeredwrite s32 or 10-character hex to updateclose filerequest removed

File descriptor의 수명이 요청 등록과 자동 정리를 결정합니다.

From user space:

The infrastructure exposes one device node, /dev/cpu_dma_latency, for the CPU
latency QoS.

Only processes can register a PM QoS request.  To provide for automatic
cleanup of a process, the interface requires the process to register its
parameter requests as follows.

To register the default PM QoS target for the CPU latency QoS, the process must
open /dev/cpu_dma_latency.

As long as the device node is held open that process has a registered
request on the parameter.

To change the requested target value, the process needs to write an s32 value to
the open device node.  Alternatively, it can write a hex string for the value
using the 10 char long format e.g. "0x12345678".  This translates to a
cpu_latency_qos_update_request() call.

To remove the user mode request for a target value simply close the device
node.

장치별 latency와 flag 집계

80-97

각 장치에는 PM QoS request 목록이 세 개 있습니다. 두 목록은 resume latency와 active-state latency tolerance의 집계 target을 microsecond 단위로 유지하고, 세 번째 목록은 PM QoS flag를 유지합니다. 요청 목록이 바뀌면 해당 값도 갱신됩니다.

Resume latency와 active-state latency tolerance의 target은 각 목록 원소 중 최솟값입니다. PM QoS flag 집계값은 모든 원소를 bitwise OR로 모은 값입니다. 현재 정의된 장치 PM QoS flag는 `PM_QOS_FLAG_NO_POWER_OFF` 하나입니다.

집계 target 값은 읽을 때 locking mechanism이 필요하지 않도록 구현되어 있습니다.

장치별 세 요청 목록
목록집계 규칙의미
Resume latencyminimumResume 허용 지연
Active-state latency toleranceminimum활성 상태에서 허용할 지연
PM QoS flagsbitwise ORPM_QOS_FLAG_NO_POWER_OFF 등의 요구

Latency는 가장 엄격한 최솟값을, flag는 모든 요구의 합집합을 사용합니다.

2. PM QoS per-device latency and flags framework
================================================

For each device, there are three lists of PM QoS requests. Two of them are
maintained along with the aggregated targets of resume latency and active
state latency tolerance (in microseconds) and the third one is for PM QoS flags.
Values are updated in response to changes of the request list.

The target values of resume latency and active state latency tolerance are
simply the minimum of the request values held in the parameter list elements.
The PM QoS flags aggregate value is a gather (bitwise OR) of all list elements'
values.  One device PM QoS flag is defined currently: PM_QOS_FLAG_NO_POWER_OFF.

Note: The aggregated target values are implemented in such a way that reading
the aggregated value does not require any locking mechanism.


From kernel mode the use of this interface is the following:

장치별 요청 API

98-138

`dev_pm_qos_add_request(device, handle, type, value)`는 지정한 장치의 해당 목록에 target 원소를 넣습니다. 새 target을 계산한 뒤 값이 달라진 경우에만 notifier를 호출하며, 클라이언트는 후속 `dev_pm_qos` API를 위해 handle을 보관해야 합니다.

`dev_pm_qos_update_request(handle, new_value)`는 handle이 가리키는 원소를 갱신하고 집계 target을 다시 계산합니다. 값이 바뀌면 notification tree를 호출합니다.

`dev_pm_qos_remove_request(handle)`는 원소를 제거하고 집계 target을 갱신하며, 제거 결과 값이 바뀐 경우 notification tree를 호출합니다. `dev_pm_qos_read_value(device, type)`은 지정한 장치 constraint 목록의 집계값을 반환합니다.

`dev_pm_qos_flags(device, mask)`는 장치의 PM QoS flag를 mask와 비교합니다. `PM_QOS_FLAGS_ALL`은 mask의 모든 flag가 설정됨, `PM_QOS_FLAGS_SOME`은 일부만 설정됨, `PM_QOS_FLAGS_NONE`은 하나도 설정되지 않음을 뜻합니다. `PM_QOS_FLAGS_UNDEFINED`는 장치의 PM QoS 구조가 초기화되지 않았거나 요청 목록이 비어 있음을 뜻합니다.

`dev_pm_qos_add_ancestor_request(dev, handle, type, value)`는 조건을 충족하는 첫 direct ancestor에 요청을 추가합니다. `DEV_PM_QOS_RESUME_LATENCY`라면 `power.ignore_children`이 설정되지 않은 조상을, `DEV_PM_QOS_LATENCY_TOLERANCE`라면 `power.set_latency_tolerance` callback pointer가 `NULL`이 아닌 조상을 선택합니다.

dev_pm_qos_flags() 결과
결과의미
PM_QOS_FLAGS_ALLMask의 모든 flag 설정
PM_QOS_FLAGS_SOMEMask의 일부 flag 설정
PM_QOS_FLAGS_NONEMask의 flag가 하나도 없음
PM_QOS_FLAGS_UNDEFINED구조 미초기화 또는 빈 요청 목록

Mask의 flag와 현재 집계값의 관계를 네 상태로 반환합니다.


int dev_pm_qos_add_request(device, handle, type, value):
  Will insert an element into the list for that identified device with the
  target value.  Upon change to this list the new target is recomputed and any
  registered notifiers are called only if the target value is now different.
  Clients of dev_pm_qos need to save the handle for future use in other
  dev_pm_qos API functions.

int dev_pm_qos_update_request(handle, new_value):
  Will update the list element pointed to by the handle with the new target
  value and recompute the new aggregated target, calling the notification
  trees if the target is changed.

int dev_pm_qos_remove_request(handle):
  Will remove the element.  After removal it will update the aggregate target
  and call the notification trees if the target was changed as a result of
  removing the request.

s32 dev_pm_qos_read_value(device, type):
  Returns the aggregated value for a given device's constraints list.

enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
  Check PM QoS flags of the given device against the given mask of flags.
  The meaning of the return values is as follows:

        PM_QOS_FLAGS_ALL:
                All flags from the mask are set
        PM_QOS_FLAGS_SOME:
                Some flags from the mask are set
        PM_QOS_FLAGS_NONE:
                No flags from the mask are set
        PM_QOS_FLAGS_UNDEFINED:
                The device's PM QoS structure has not been initialized
                or the list of requests is empty.

int dev_pm_qos_add_ancestor_request(dev, handle, type, value)
  Add a PM QoS request for the first direct ancestor of the given device whose
  power.ignore_children flag is unset (for DEV_PM_QOS_RESUME_LATENCY requests)
  or whose power.set_latency_tolerance callback pointer is not NULL (for
  DEV_PM_QOS_LATENCY_TOLERANCE requests).

sysfs 노출과 notifier

139-173

`dev_pm_qos_expose_latency_limit(device, value)`는 장치의 resume latency constraint 목록에 요청을 추가하고 장치 `power` 디렉터리에 `pm_qos_resume_latency_us` sysfs attribute를 만들어 사용자 공간이 그 요청을 조작할 수 있게 합니다.

`dev_pm_qos_hide_latency_limit(device)`는 `dev_pm_qos_expose_latency_limit()`가 추가한 요청을 제거하고 `pm_qos_resume_latency_us` attribute도 없앱니다.

`dev_pm_qos_expose_flags(device, value)`는 장치 flag 목록에 요청을 추가하고 `power` 디렉터리에 `pm_qos_no_power_off` sysfs attribute를 만들어 사용자 공간이 `PM_QOS_FLAG_NO_POWER_OFF` 값을 바꿀 수 있게 합니다.

`dev_pm_qos_hide_flags(device)`는 expose 함수가 추가한 flag 요청과 `pm_qos_no_power_off` attribute를 제거합니다.

장치별 PM QoS 프레임워크에는 장치마다 notification tree가 있습니다. `dev_pm_qos_add_notifier(device, notifier, type)`는 특정 request type의 callback을 추가하며 장치 constraint 목록의 집계값이 바뀔 때 호출됩니다. `dev_pm_qos_remove_notifier(device, notifier, type)`는 그 callback을 제거합니다.

장치 PM QoS sysfs
Exposesysfs attributeHide
dev_pm_qos_expose_latency_limitpower/pm_qos_resume_latency_usdev_pm_qos_hide_latency_limit
dev_pm_qos_expose_flagspower/pm_qos_no_power_offdev_pm_qos_hide_flags

Expose와 hide 함수가 요청과 attribute를 한 쌍으로 관리합니다.

int dev_pm_qos_expose_latency_limit(device, value)
  Add a request to the device's PM QoS list of resume latency constraints and
  create a sysfs attribute pm_qos_resume_latency_us under the device's power
  directory allowing user space to manipulate that request.

void dev_pm_qos_hide_latency_limit(device)
  Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
  PM QoS list of resume latency constraints and remove sysfs attribute
  pm_qos_resume_latency_us from the device's power directory.

int dev_pm_qos_expose_flags(device, value)
  Add a request to the device's PM QoS list of flags and create sysfs attribute
  pm_qos_no_power_off under the device's power directory allowing user space to
  change the value of the PM_QOS_FLAG_NO_POWER_OFF flag.

void dev_pm_qos_hide_flags(device)
  Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS
  list of flags and remove sysfs attribute pm_qos_no_power_off from the device's
  power directory.

Notification mechanisms:

The per-device PM QoS framework has a per-device notification tree.

int dev_pm_qos_add_notifier(device, notifier, type):
  Adds a notification callback function for the device for a particular request
  type.

  The callback is called when the aggregated value of the device constraints
  list is changed.

int dev_pm_qos_remove_notifier(device, notifier, type):
  Removes the notification callback function for the device.

Active-state latency tolerance

174-200

이 장치 PM QoS type은 hardware가 동작 중에 energy-saving mode로 전환할 수 있는 system을 지원합니다. Hardware가 지나치게 공격적으로 energy를 절약하면 software가 볼 수 있는 latency가 커져 protocol requirement나 목표 frame/sample rate를 놓칠 수 있습니다.

Software가 사용할 수 있는 latency tolerance 제어 장치가 있다면 해당 장치 `dev_pm_info` 구조의 `.set_latency_tolerance` callback을 채워야 합니다. 그 routine은 유효 requirement 값을 hardware에 전달하는 데 필요한 동작을 구현해야 합니다.

장치의 유효 latency tolerance가 바뀔 때마다 `.set_latency_tolerance()`를 호출해 새 유효값을 전달합니다. 값이 음수이면 요구 목록이 비었다는 뜻이므로, 가능하다면 hardware의 latency tolerance 제어를 autonomous mode로 전환해야 합니다.

값이 `PM_QOS_LATENCY_ANY`이고 hardware가 특별한 `no requirement` 설정을 지원한다면 그 설정을 사용해야 합니다. 이 방식은 software가 hardware의 autonomous latency control을 허용하지 않으면서 요구사항이 없음을 나타냅니다. 따라서 D3cold에서 D0로 전환할 때처럼 power-state 변경에 따라 hardware가 latency tolerance를 자동 갱신하는 동작을 막을 수 있습니다.

Latency tolerance 특별값
유효값callback 동작
Negative요청 목록이 비었으므로 가능하면 autonomous mode
PM_QOS_LATENCY_ANYNo requirement를 사용하되 hardware의 자동 제어는 허용하지 않음
0 이상 값해당 latency requirement를 hardware에 적용

빈 목록과 명시적인 제한 없음은 hardware 자율 제어 권한이 다릅니다.

Active state latency tolerance
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This device PM QoS type is used to support systems in which hardware may switch
to energy-saving operation modes on the fly.  In those systems, if the operation
mode chosen by the hardware attempts to save energy in an overly aggressive way,
it may cause excess latencies to be visible to software, causing it to miss
certain protocol requirements or target frame or sample rates etc.

If there is a latency tolerance control mechanism for a given device available
to software, the .set_latency_tolerance callback in that device's dev_pm_info
structure should be populated.  The routine pointed to by it is should implement
whatever is necessary to transfer the effective requirement value to the
hardware.

Whenever the effective latency tolerance changes for the device, its
.set_latency_tolerance() callback will be executed and the effective value will
be passed to it.  If that value is negative, which means that the list of
latency tolerance requirements for the device is empty, the callback is expected
to switch the underlying hardware latency tolerance control mechanism to an
autonomous mode if available.  If that value is PM_QOS_LATENCY_ANY, in turn, and
the hardware supports a special "no requirement" setting, the callback is
expected to use it.  That allows software to prevent the hardware from
automatically updating the device's latency tolerance in response to its power
state changes (e.g. during transitions from D3cold to D0), which generally may
be done in the autonomous latency tolerance control mode.

Latency tolerance의 사용자 공간 제어

201-211

장치에 `.set_latency_tolerance()`가 있으면 장치의 `power` 디렉터리에 `pm_qos_latency_tolerance_us` sysfs attribute가 나타납니다. 사용자 공간은 이 attribute로 장치의 latency tolerance requirement를 지정할 수 있습니다.

`any`를 쓰면 요구사항은 없지만 hardware가 latency tolerance를 제어하게 두지 않는다는 뜻입니다. `auto`를 쓰면 장치 목록에 커널 측의 다른 요구가 없을 때 hardware를 autonomous mode로 전환할 수 있습니다.

커널 코드는 앞에서 설명한 함수와 `DEV_PM_QOS_LATENCY_TOLERANCE` 장치 PM QoS type을 함께 사용해 장치의 latency tolerance requirement를 추가, 제거, 갱신할 수 있습니다.

pm_qos_latency_tolerance_us 입력
입력의미
수치명시적인 microsecond tolerance
any요구 없음, hardware 자율 제어 금지
auto커널 요청이 없으면 autonomous mode 허용

사용자 입력은 제한 없음과 자율 제어 허용을 구분합니다.

If .set_latency_tolerance() is present for the device, sysfs attribute
pm_qos_latency_tolerance_us will be present in the devivce's power directory.
Then, user space can use that attribute to specify its latency tolerance
requirement for the device, if any.  Writing "any" to it means "no requirement,
but do not let the hardware control latency tolerance" and writing "auto" to it
allows the hardware to be switched to the autonomous mode if there are no other
requirements from the kernel side in the device's list.

Kernel code can use the functions described above along with the
DEV_PM_QOS_LATENCY_TOLERANCE device PM QoS type to add, remove and update
latency tolerance requirements for devices.