hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/powercap/idle_inject.c
....@@ -19,8 +19,8 @@
1919 * The idle + run duration is specified via separate helpers and that allows
2020 * idle injection to be started.
2121 *
22
- * The idle injection kthreads will call play_idle() with the idle duration
23
- * specified as per the above.
22
+ * The idle injection kthreads will call play_idle_precise() with the idle
23
+ * duration and max allowed latency specified as per the above.
2424 *
2525 * After all of them have been woken up, a timer is set to start the next idle
2626 * injection cycle.
....@@ -43,6 +43,7 @@
4343 #include <linux/sched.h>
4444 #include <linux/slab.h>
4545 #include <linux/smpboot.h>
46
+#include <linux/idle_inject.h>
4647
4748 #include <uapi/linux/sched/types.h>
4849
....@@ -59,15 +60,17 @@
5960 /**
6061 * struct idle_inject_device - idle injection data
6162 * @timer: idle injection period timer
62
- * @idle_duration_ms: duration of CPU idle time to inject
63
- * @run_duration_ms: duration of CPU run time to allow
63
+ * @idle_duration_us: duration of CPU idle time to inject
64
+ * @run_duration_us: duration of CPU run time to allow
65
+ * @latency_us: max allowed latency
6466 * @cpumask: mask of CPUs affected by idle injection
6567 */
6668 struct idle_inject_device {
6769 struct hrtimer timer;
68
- unsigned int idle_duration_ms;
69
- unsigned int run_duration_ms;
70
- unsigned long int cpumask[0];
70
+ unsigned int idle_duration_us;
71
+ unsigned int run_duration_us;
72
+ unsigned int latency_us;
73
+ unsigned long cpumask[];
7174 };
7275
7376 static DEFINE_PER_CPU(struct idle_inject_thread, idle_inject_thread);
....@@ -98,22 +101,22 @@
98101 *
99102 * This function is called when the idle injection timer expires. It wakes up
100103 * idle injection tasks associated with the timer and they, in turn, invoke
101
- * play_idle() to inject a specified amount of CPU idle time.
104
+ * play_idle_precise() to inject a specified amount of CPU idle time.
102105 *
103106 * Return: HRTIMER_RESTART.
104107 */
105108 static enum hrtimer_restart idle_inject_timer_fn(struct hrtimer *timer)
106109 {
107
- unsigned int duration_ms;
110
+ unsigned int duration_us;
108111 struct idle_inject_device *ii_dev =
109112 container_of(timer, struct idle_inject_device, timer);
110113
111
- duration_ms = READ_ONCE(ii_dev->run_duration_ms);
112
- duration_ms += READ_ONCE(ii_dev->idle_duration_ms);
114
+ duration_us = READ_ONCE(ii_dev->run_duration_us);
115
+ duration_us += READ_ONCE(ii_dev->idle_duration_us);
113116
114117 idle_inject_wakeup(ii_dev);
115118
116
- hrtimer_forward_now(timer, ms_to_ktime(duration_ms));
119
+ hrtimer_forward_now(timer, ns_to_ktime(duration_us * NSEC_PER_USEC));
117120
118121 return HRTIMER_RESTART;
119122 }
....@@ -122,8 +125,8 @@
122125 * idle_inject_fn - idle injection work function
123126 * @cpu: the CPU owning the task
124127 *
125
- * This function calls play_idle() to inject a specified amount of CPU idle
126
- * time.
128
+ * This function calls play_idle_precise() to inject a specified amount of CPU
129
+ * idle time.
127130 */
128131 static void idle_inject_fn(unsigned int cpu)
129132 {
....@@ -138,35 +141,46 @@
138141 */
139142 iit->should_run = 0;
140143
141
- play_idle(READ_ONCE(ii_dev->idle_duration_ms));
144
+ play_idle_precise(READ_ONCE(ii_dev->idle_duration_us) * NSEC_PER_USEC,
145
+ READ_ONCE(ii_dev->latency_us) * NSEC_PER_USEC);
142146 }
143147
144148 /**
145149 * idle_inject_set_duration - idle and run duration update helper
146
- * @run_duration_ms: CPU run time to allow in milliseconds
147
- * @idle_duration_ms: CPU idle time to inject in milliseconds
150
+ * @run_duration_us: CPU run time to allow in microseconds
151
+ * @idle_duration_us: CPU idle time to inject in microseconds
148152 */
149153 void idle_inject_set_duration(struct idle_inject_device *ii_dev,
150
- unsigned int run_duration_ms,
151
- unsigned int idle_duration_ms)
154
+ unsigned int run_duration_us,
155
+ unsigned int idle_duration_us)
152156 {
153
- if (run_duration_ms && idle_duration_ms) {
154
- WRITE_ONCE(ii_dev->run_duration_ms, run_duration_ms);
155
- WRITE_ONCE(ii_dev->idle_duration_ms, idle_duration_ms);
157
+ if (run_duration_us && idle_duration_us) {
158
+ WRITE_ONCE(ii_dev->run_duration_us, run_duration_us);
159
+ WRITE_ONCE(ii_dev->idle_duration_us, idle_duration_us);
156160 }
157161 }
158162
159163 /**
160164 * idle_inject_get_duration - idle and run duration retrieval helper
161
- * @run_duration_ms: memory location to store the current CPU run time
162
- * @idle_duration_ms: memory location to store the current CPU idle time
165
+ * @run_duration_us: memory location to store the current CPU run time
166
+ * @idle_duration_us: memory location to store the current CPU idle time
163167 */
164168 void idle_inject_get_duration(struct idle_inject_device *ii_dev,
165
- unsigned int *run_duration_ms,
166
- unsigned int *idle_duration_ms)
169
+ unsigned int *run_duration_us,
170
+ unsigned int *idle_duration_us)
167171 {
168
- *run_duration_ms = READ_ONCE(ii_dev->run_duration_ms);
169
- *idle_duration_ms = READ_ONCE(ii_dev->idle_duration_ms);
172
+ *run_duration_us = READ_ONCE(ii_dev->run_duration_us);
173
+ *idle_duration_us = READ_ONCE(ii_dev->idle_duration_us);
174
+}
175
+
176
+/**
177
+ * idle_inject_set_latency - set the maximum latency allowed
178
+ * @latency_us: set the latency requirement for the idle state
179
+ */
180
+void idle_inject_set_latency(struct idle_inject_device *ii_dev,
181
+ unsigned int latency_us)
182
+{
183
+ WRITE_ONCE(ii_dev->latency_us, latency_us);
170184 }
171185
172186 /**
....@@ -181,10 +195,10 @@
181195 */
182196 int idle_inject_start(struct idle_inject_device *ii_dev)
183197 {
184
- unsigned int idle_duration_ms = READ_ONCE(ii_dev->idle_duration_ms);
185
- unsigned int run_duration_ms = READ_ONCE(ii_dev->run_duration_ms);
198
+ unsigned int idle_duration_us = READ_ONCE(ii_dev->idle_duration_us);
199
+ unsigned int run_duration_us = READ_ONCE(ii_dev->run_duration_us);
186200
187
- if (!idle_duration_ms || !run_duration_ms)
201
+ if (!idle_duration_us || !run_duration_us)
188202 return -EINVAL;
189203
190204 pr_debug("Starting injecting idle cycles on CPUs '%*pbl'\n",
....@@ -193,7 +207,8 @@
193207 idle_inject_wakeup(ii_dev);
194208
195209 hrtimer_start(&ii_dev->timer,
196
- ms_to_ktime(idle_duration_ms + run_duration_ms),
210
+ ns_to_ktime((idle_duration_us + run_duration_us) *
211
+ NSEC_PER_USEC),
197212 HRTIMER_MODE_REL);
198213
199214 return 0;
....@@ -254,9 +269,7 @@
254269 */
255270 static void idle_inject_setup(unsigned int cpu)
256271 {
257
- struct sched_param param = { .sched_priority = MAX_USER_RT_PRIO / 2 };
258
-
259
- sched_setscheduler(current, SCHED_FIFO, &param);
272
+ sched_set_fifo(current);
260273 }
261274
262275 /**
....@@ -296,6 +309,7 @@
296309 cpumask_copy(to_cpumask(ii_dev->cpumask), cpumask);
297310 hrtimer_init(&ii_dev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
298311 ii_dev->timer.function = idle_inject_timer_fn;
312
+ ii_dev->latency_us = UINT_MAX;
299313
300314 for_each_cpu(cpu, to_cpumask(ii_dev->cpumask)) {
301315