hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/drivers/cpuidle/sysfs.c
....@@ -18,14 +18,6 @@
1818
1919 #include "cpuidle.h"
2020
21
-static unsigned int sysfs_switch;
22
-static int __init cpuidle_sysfs_setup(char *unused)
23
-{
24
- sysfs_switch = 1;
25
- return 1;
26
-}
27
-__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
28
-
2921 static ssize_t show_available_governors(struct device *dev,
3022 struct device_attribute *attr,
3123 char *buf)
....@@ -35,10 +27,10 @@
3527
3628 mutex_lock(&cpuidle_lock);
3729 list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
38
- if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) -
39
- CPUIDLE_NAME_LEN - 2))
30
+ if (i >= (ssize_t) (PAGE_SIZE - (CPUIDLE_NAME_LEN + 2)))
4031 goto out;
41
- i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name);
32
+
33
+ i += scnprintf(&buf[i], CPUIDLE_NAME_LEN + 1, "%s ", tmp->name);
4234 }
4335
4436 out:
....@@ -85,74 +77,58 @@
8577 struct device_attribute *attr,
8678 const char *buf, size_t count)
8779 {
88
- char gov_name[CPUIDLE_NAME_LEN];
89
- int ret = -EINVAL;
90
- size_t len = count;
80
+ char gov_name[CPUIDLE_NAME_LEN + 1];
81
+ int ret;
9182 struct cpuidle_governor *gov;
9283
93
- if (!len || len >= sizeof(gov_name))
84
+ ret = sscanf(buf, "%" __stringify(CPUIDLE_NAME_LEN) "s", gov_name);
85
+ if (ret != 1)
9486 return -EINVAL;
9587
96
- memcpy(gov_name, buf, len);
97
- gov_name[len] = '\0';
98
- if (gov_name[len - 1] == '\n')
99
- gov_name[--len] = '\0';
100
-
10188 mutex_lock(&cpuidle_lock);
102
-
89
+ ret = -EINVAL;
10390 list_for_each_entry(gov, &cpuidle_governors, governor_list) {
104
- if (strlen(gov->name) == len && !strcmp(gov->name, gov_name)) {
91
+ if (!strncmp(gov->name, gov_name, CPUIDLE_NAME_LEN)) {
10592 ret = cpuidle_switch_governor(gov);
10693 break;
10794 }
10895 }
109
-
11096 mutex_unlock(&cpuidle_lock);
11197
112
- if (ret)
113
- return ret;
114
- else
115
- return count;
98
+ return ret ? ret : count;
11699 }
117100
101
+static DEVICE_ATTR(available_governors, 0444, show_available_governors, NULL);
118102 static DEVICE_ATTR(current_driver, 0444, show_current_driver, NULL);
103
+static DEVICE_ATTR(current_governor, 0644, show_current_governor,
104
+ store_current_governor);
119105 static DEVICE_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
120106
121
-static struct attribute *cpuidle_default_attrs[] = {
107
+static struct attribute *cpuidle_attrs[] = {
108
+ &dev_attr_available_governors.attr,
122109 &dev_attr_current_driver.attr,
110
+ &dev_attr_current_governor.attr,
123111 &dev_attr_current_governor_ro.attr,
124112 NULL
125113 };
126114
127
-static DEVICE_ATTR(available_governors, 0444, show_available_governors, NULL);
128
-static DEVICE_ATTR(current_governor, 0644, show_current_governor,
129
- store_current_governor);
130
-
131
-static struct attribute *cpuidle_switch_attrs[] = {
132
- &dev_attr_available_governors.attr,
133
- &dev_attr_current_driver.attr,
134
- &dev_attr_current_governor.attr,
135
- NULL
136
-};
137
-
138115 static struct attribute_group cpuidle_attr_group = {
139
- .attrs = cpuidle_default_attrs,
116
+ .attrs = cpuidle_attrs,
140117 .name = "cpuidle",
141118 };
142119
143120 /**
144121 * cpuidle_add_interface - add CPU global sysfs attributes
122
+ * @dev: the target device
145123 */
146124 int cpuidle_add_interface(struct device *dev)
147125 {
148
- if (sysfs_switch)
149
- cpuidle_attr_group.attrs = cpuidle_switch_attrs;
150
-
151126 return sysfs_create_group(&dev->kobj, &cpuidle_attr_group);
152127 }
153128
154129 /**
155130 * cpuidle_remove_interface - remove CPU global sysfs attributes
131
+ * @dev: the target device
156132 */
157133 void cpuidle_remove_interface(struct device *dev)
158134 {
....@@ -164,11 +140,6 @@
164140 ssize_t (*show)(struct cpuidle_device *, char *);
165141 ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
166142 };
167
-
168
-#define define_one_ro(_name, show) \
169
- static struct cpuidle_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
170
-#define define_one_rw(_name, show, store) \
171
- static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store)
172143
173144 #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
174145
....@@ -255,25 +226,6 @@
255226 return sprintf(buf, "%u\n", state->_name);\
256227 }
257228
258
-#define define_store_state_ull_function(_name) \
259
-static ssize_t store_state_##_name(struct cpuidle_state *state, \
260
- struct cpuidle_state_usage *state_usage, \
261
- const char *buf, size_t size) \
262
-{ \
263
- unsigned long long value; \
264
- int err; \
265
- if (!capable(CAP_SYS_ADMIN)) \
266
- return -EPERM; \
267
- err = kstrtoull(buf, 0, &value); \
268
- if (err) \
269
- return err; \
270
- if (value) \
271
- state_usage->_name = 1; \
272
- else \
273
- state_usage->_name = 0; \
274
- return size; \
275
-}
276
-
277229 #define define_show_state_ull_function(_name) \
278230 static ssize_t show_state_##_name(struct cpuidle_state *state, \
279231 struct cpuidle_state_usage *state_usage, \
....@@ -292,15 +244,68 @@
292244 return sprintf(buf, "%s\n", state->_name);\
293245 }
294246
295
-define_show_state_function(exit_latency)
296
-define_show_state_function(target_residency)
247
+#define define_show_state_time_function(_name) \
248
+static ssize_t show_state_##_name(struct cpuidle_state *state, \
249
+ struct cpuidle_state_usage *state_usage, \
250
+ char *buf) \
251
+{ \
252
+ return sprintf(buf, "%llu\n", ktime_to_us(state->_name##_ns)); \
253
+}
254
+
255
+define_show_state_time_function(exit_latency)
256
+define_show_state_time_function(target_residency)
297257 define_show_state_function(power_usage)
298258 define_show_state_ull_function(usage)
299
-define_show_state_ull_function(time)
259
+define_show_state_ull_function(rejected)
300260 define_show_state_str_function(name)
301261 define_show_state_str_function(desc)
302
-define_show_state_ull_function(disable)
303
-define_store_state_ull_function(disable)
262
+define_show_state_ull_function(above)
263
+define_show_state_ull_function(below)
264
+
265
+static ssize_t show_state_time(struct cpuidle_state *state,
266
+ struct cpuidle_state_usage *state_usage,
267
+ char *buf)
268
+{
269
+ return sprintf(buf, "%llu\n", ktime_to_us(state_usage->time_ns));
270
+}
271
+
272
+static ssize_t show_state_disable(struct cpuidle_state *state,
273
+ struct cpuidle_state_usage *state_usage,
274
+ char *buf)
275
+{
276
+ return sprintf(buf, "%llu\n",
277
+ state_usage->disable & CPUIDLE_STATE_DISABLED_BY_USER);
278
+}
279
+
280
+static ssize_t store_state_disable(struct cpuidle_state *state,
281
+ struct cpuidle_state_usage *state_usage,
282
+ const char *buf, size_t size)
283
+{
284
+ unsigned int value;
285
+ int err;
286
+
287
+ if (!capable(CAP_SYS_ADMIN))
288
+ return -EPERM;
289
+
290
+ err = kstrtouint(buf, 0, &value);
291
+ if (err)
292
+ return err;
293
+
294
+ if (value)
295
+ state_usage->disable |= CPUIDLE_STATE_DISABLED_BY_USER;
296
+ else
297
+ state_usage->disable &= ~CPUIDLE_STATE_DISABLED_BY_USER;
298
+
299
+ return size;
300
+}
301
+
302
+static ssize_t show_state_default_status(struct cpuidle_state *state,
303
+ struct cpuidle_state_usage *state_usage,
304
+ char *buf)
305
+{
306
+ return sprintf(buf, "%s\n",
307
+ state->flags & CPUIDLE_FLAG_OFF ? "disabled" : "enabled");
308
+}
304309
305310 define_one_state_ro(name, show_state_name);
306311 define_one_state_ro(desc, show_state_desc);
....@@ -308,8 +313,12 @@
308313 define_one_state_ro(residency, show_state_target_residency);
309314 define_one_state_ro(power, show_state_power_usage);
310315 define_one_state_ro(usage, show_state_usage);
316
+define_one_state_ro(rejected, show_state_rejected);
311317 define_one_state_ro(time, show_state_time);
312318 define_one_state_rw(disable, show_state_disable, store_state_disable);
319
+define_one_state_ro(above, show_state_above);
320
+define_one_state_ro(below, show_state_below);
321
+define_one_state_ro(default_status, show_state_default_status);
313322
314323 static struct attribute *cpuidle_state_default_attrs[] = {
315324 &attr_name.attr,
....@@ -318,8 +327,12 @@
318327 &attr_residency.attr,
319328 &attr_power.attr,
320329 &attr_usage.attr,
330
+ &attr_rejected.attr,
321331 &attr_time.attr,
322332 &attr_disable.attr,
333
+ &attr_above.attr,
334
+ &attr_below.attr,
335
+ &attr_default_status.attr,
323336 NULL
324337 };
325338
....@@ -328,6 +341,7 @@
328341 struct cpuidle_state_usage *state_usage;
329342 struct completion kobj_unregister;
330343 struct kobject kobj;
344
+ struct cpuidle_device *device;
331345 };
332346
333347 #ifdef CONFIG_SUSPEND
....@@ -385,15 +399,16 @@
385399 #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
386400 #define kobj_to_state(k) (kobj_to_state_obj(k)->state)
387401 #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage)
402
+#define kobj_to_device(k) (kobj_to_state_obj(k)->device)
388403 #define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
389404
390405 static ssize_t cpuidle_state_show(struct kobject *kobj, struct attribute *attr,
391
- char * buf)
406
+ char *buf)
392407 {
393408 int ret = -EIO;
394409 struct cpuidle_state *state = kobj_to_state(kobj);
395410 struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
396
- struct cpuidle_state_attr * cattr = attr_to_stateattr(attr);
411
+ struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
397412
398413 if (cattr->show)
399414 ret = cattr->show(state, state_usage, buf);
....@@ -408,9 +423,13 @@
408423 struct cpuidle_state *state = kobj_to_state(kobj);
409424 struct cpuidle_state_usage *state_usage = kobj_to_state_usage(kobj);
410425 struct cpuidle_state_attr *cattr = attr_to_stateattr(attr);
426
+ struct cpuidle_device *dev = kobj_to_device(kobj);
411427
412428 if (cattr->store)
413429 ret = cattr->store(state, state_usage, buf, size);
430
+
431
+ /* reset poll time cache */
432
+ dev->poll_limit_ns = 0;
414433
415434 return ret;
416435 }
....@@ -462,6 +481,7 @@
462481 }
463482 kobj->state = &drv->states[i];
464483 kobj->state_usage = &device->states_usage[i];
484
+ kobj->device = device;
465485 init_completion(&kobj->kobj_unregister);
466486
467487 ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle,
....@@ -580,7 +600,7 @@
580600
581601 /**
582602 * cpuidle_add_driver_sysfs - adds the driver name sysfs attribute
583
- * @device: the target device
603
+ * @dev: the target device
584604 */
585605 static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev)
586606 {
....@@ -612,7 +632,7 @@
612632
613633 /**
614634 * cpuidle_remove_driver_sysfs - removes the driver name sysfs attribute
615
- * @device: the target device
635
+ * @dev: the target device
616636 */
617637 static void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev)
618638 {