cpufreq_times.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /* drivers/cpufreq/cpufreq_times.c
  2. *
  3. * Copyright (C) 2018 Google, Inc.
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/cpufreq.h>
  16. #include <linux/cpufreq_times.h>
  17. #include <linux/hashtable.h>
  18. #include <linux/init.h>
  19. #include <linux/jiffies.h>
  20. #include <linux/proc_fs.h>
  21. #include <linux/sched.h>
  22. #include <linux/seq_file.h>
  23. #include <linux/slab.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/threads.h>
  26. #define UID_HASH_BITS 10
  27. static DECLARE_HASHTABLE(uid_hash_table, UID_HASH_BITS);
  28. static DEFINE_SPINLOCK(task_time_in_state_lock); /* task->time_in_state */
  29. static DEFINE_SPINLOCK(uid_lock); /* uid_hash_table */
  30. struct concurrent_times {
  31. atomic64_t active[NR_CPUS];
  32. atomic64_t policy[NR_CPUS];
  33. };
  34. struct uid_entry {
  35. uid_t uid;
  36. unsigned int max_state;
  37. struct hlist_node hash;
  38. struct rcu_head rcu;
  39. struct concurrent_times *concurrent_times;
  40. u64 time_in_state[0];
  41. };
  42. /**
  43. * struct cpu_freqs - per-cpu frequency information
  44. * @offset: start of these freqs' stats in task time_in_state array
  45. * @max_state: number of entries in freq_table
  46. * @last_index: index in freq_table of last frequency switched to
  47. * @freq_table: list of available frequencies
  48. */
  49. struct cpu_freqs {
  50. unsigned int offset;
  51. unsigned int max_state;
  52. unsigned int last_index;
  53. unsigned int freq_table[0];
  54. };
  55. static struct cpu_freqs *all_freqs[NR_CPUS];
  56. static unsigned int next_offset;
  57. /* Caller must hold rcu_read_lock() */
  58. static struct uid_entry *find_uid_entry_rcu(uid_t uid)
  59. {
  60. struct uid_entry *uid_entry;
  61. hash_for_each_possible_rcu(uid_hash_table, uid_entry, hash, uid) {
  62. if (uid_entry->uid == uid)
  63. return uid_entry;
  64. }
  65. return NULL;
  66. }
  67. /* Caller must hold uid lock */
  68. static struct uid_entry *find_uid_entry_locked(uid_t uid)
  69. {
  70. struct uid_entry *uid_entry;
  71. hash_for_each_possible(uid_hash_table, uid_entry, hash, uid) {
  72. if (uid_entry->uid == uid)
  73. return uid_entry;
  74. }
  75. return NULL;
  76. }
  77. /* Caller must hold uid lock */
  78. static struct uid_entry *find_or_register_uid_locked(uid_t uid)
  79. {
  80. struct uid_entry *uid_entry, *temp;
  81. struct concurrent_times *times;
  82. unsigned int max_state = READ_ONCE(next_offset);
  83. size_t alloc_size = sizeof(*uid_entry) + max_state *
  84. sizeof(uid_entry->time_in_state[0]);
  85. uid_entry = find_uid_entry_locked(uid);
  86. if (uid_entry) {
  87. if (uid_entry->max_state == max_state)
  88. return uid_entry;
  89. /* uid_entry->time_in_state is too small to track all freqs, so
  90. * expand it.
  91. */
  92. temp = __krealloc(uid_entry, alloc_size, GFP_ATOMIC);
  93. if (!temp)
  94. return uid_entry;
  95. temp->max_state = max_state;
  96. memset(temp->time_in_state + uid_entry->max_state, 0,
  97. (max_state - uid_entry->max_state) *
  98. sizeof(uid_entry->time_in_state[0]));
  99. if (temp != uid_entry) {
  100. hlist_replace_rcu(&uid_entry->hash, &temp->hash);
  101. kfree_rcu(uid_entry, rcu);
  102. }
  103. return temp;
  104. }
  105. uid_entry = kzalloc(alloc_size, GFP_ATOMIC);
  106. if (!uid_entry)
  107. return NULL;
  108. times = kzalloc(sizeof(*times), GFP_ATOMIC);
  109. if (!times) {
  110. kfree(uid_entry);
  111. return NULL;
  112. }
  113. uid_entry->uid = uid;
  114. uid_entry->max_state = max_state;
  115. uid_entry->concurrent_times = times;
  116. hash_add_rcu(uid_hash_table, &uid_entry->hash, uid);
  117. return uid_entry;
  118. }
  119. static int single_uid_time_in_state_show(struct seq_file *m, void *ptr)
  120. {
  121. struct uid_entry *uid_entry;
  122. unsigned int i;
  123. uid_t uid = from_kuid_munged(current_user_ns(), *(kuid_t *)m->private);
  124. if (uid == overflowuid)
  125. return -EINVAL;
  126. rcu_read_lock();
  127. uid_entry = find_uid_entry_rcu(uid);
  128. if (!uid_entry) {
  129. rcu_read_unlock();
  130. return 0;
  131. }
  132. for (i = 0; i < uid_entry->max_state; ++i) {
  133. u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]);
  134. seq_write(m, &time, sizeof(time));
  135. }
  136. rcu_read_unlock();
  137. return 0;
  138. }
  139. static void *uid_seq_start(struct seq_file *seq, loff_t *pos)
  140. {
  141. if (*pos >= HASH_SIZE(uid_hash_table))
  142. return NULL;
  143. return &uid_hash_table[*pos];
  144. }
  145. static void *uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  146. {
  147. do {
  148. (*pos)++;
  149. if (*pos >= HASH_SIZE(uid_hash_table))
  150. return NULL;
  151. } while (hlist_empty(&uid_hash_table[*pos]));
  152. return &uid_hash_table[*pos];
  153. }
  154. static void uid_seq_stop(struct seq_file *seq, void *v) { }
  155. static int uid_time_in_state_seq_show(struct seq_file *m, void *v)
  156. {
  157. struct uid_entry *uid_entry;
  158. struct cpu_freqs *freqs, *last_freqs = NULL;
  159. int i, cpu;
  160. if (v == uid_hash_table) {
  161. seq_puts(m, "uid:");
  162. for_each_possible_cpu(cpu) {
  163. freqs = all_freqs[cpu];
  164. if (!freqs || freqs == last_freqs)
  165. continue;
  166. last_freqs = freqs;
  167. for (i = 0; i < freqs->max_state; i++) {
  168. seq_put_decimal_ull(m, " ",
  169. freqs->freq_table[i]);
  170. }
  171. }
  172. seq_putc(m, '\n');
  173. }
  174. rcu_read_lock();
  175. hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) {
  176. if (uid_entry->max_state) {
  177. seq_put_decimal_ull(m, "", uid_entry->uid);
  178. seq_putc(m, ':');
  179. }
  180. for (i = 0; i < uid_entry->max_state; ++i) {
  181. u64 time = nsec_to_clock_t(uid_entry->time_in_state[i]);
  182. seq_put_decimal_ull(m, " ", time);
  183. }
  184. if (uid_entry->max_state)
  185. seq_putc(m, '\n');
  186. }
  187. rcu_read_unlock();
  188. return 0;
  189. }
  190. static int concurrent_time_seq_show(struct seq_file *m, void *v,
  191. atomic64_t *(*get_times)(struct concurrent_times *))
  192. {
  193. struct uid_entry *uid_entry;
  194. int i, num_possible_cpus = num_possible_cpus();
  195. rcu_read_lock();
  196. hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) {
  197. atomic64_t *times = get_times(uid_entry->concurrent_times);
  198. seq_put_decimal_ull(m, "", (u64)uid_entry->uid);
  199. seq_putc(m, ':');
  200. for (i = 0; i < num_possible_cpus; ++i) {
  201. u64 time = nsec_to_clock_t(atomic64_read(&times[i]));
  202. seq_put_decimal_ull(m, " ", time);
  203. }
  204. seq_putc(m, '\n');
  205. }
  206. rcu_read_unlock();
  207. return 0;
  208. }
  209. static inline atomic64_t *get_active_times(struct concurrent_times *times)
  210. {
  211. return times->active;
  212. }
  213. static int concurrent_active_time_seq_show(struct seq_file *m, void *v)
  214. {
  215. if (v == uid_hash_table) {
  216. seq_put_decimal_ull(m, "cpus: ", num_possible_cpus());
  217. seq_putc(m, '\n');
  218. }
  219. return concurrent_time_seq_show(m, v, get_active_times);
  220. }
  221. static inline atomic64_t *get_policy_times(struct concurrent_times *times)
  222. {
  223. return times->policy;
  224. }
  225. static int concurrent_policy_time_seq_show(struct seq_file *m, void *v)
  226. {
  227. int i;
  228. struct cpu_freqs *freqs, *last_freqs = NULL;
  229. if (v == uid_hash_table) {
  230. int cnt = 0;
  231. for_each_possible_cpu(i) {
  232. freqs = all_freqs[i];
  233. if (!freqs)
  234. continue;
  235. if (freqs != last_freqs) {
  236. if (last_freqs) {
  237. seq_put_decimal_ull(m, ": ", cnt);
  238. seq_putc(m, ' ');
  239. cnt = 0;
  240. }
  241. seq_put_decimal_ull(m, "policy", i);
  242. last_freqs = freqs;
  243. }
  244. cnt++;
  245. }
  246. if (last_freqs) {
  247. seq_put_decimal_ull(m, ": ", cnt);
  248. seq_putc(m, '\n');
  249. }
  250. }
  251. return concurrent_time_seq_show(m, v, get_policy_times);
  252. }
  253. void cpufreq_task_times_init(struct task_struct *p)
  254. {
  255. void *temp;
  256. unsigned long flags;
  257. unsigned int max_state = READ_ONCE(next_offset);
  258. /* We use one array to avoid multiple allocs per task */
  259. temp = kcalloc(max_state, sizeof(p->time_in_state[0]), GFP_ATOMIC);
  260. if (!temp)
  261. return;
  262. spin_lock_irqsave(&task_time_in_state_lock, flags);
  263. p->time_in_state = temp;
  264. spin_unlock_irqrestore(&task_time_in_state_lock, flags);
  265. p->max_state = max_state;
  266. }
  267. /* Caller must hold task_time_in_state_lock */
  268. static int cpufreq_task_times_realloc_locked(struct task_struct *p)
  269. {
  270. void *temp;
  271. unsigned int max_state = READ_ONCE(next_offset);
  272. temp = krealloc(p->time_in_state, max_state * sizeof(u64), GFP_ATOMIC);
  273. if (!temp)
  274. return -ENOMEM;
  275. p->time_in_state = temp;
  276. memset(p->time_in_state + p->max_state, 0,
  277. (max_state - p->max_state) * sizeof(u64));
  278. p->max_state = max_state;
  279. return 0;
  280. }
  281. void cpufreq_task_times_exit(struct task_struct *p)
  282. {
  283. unsigned long flags;
  284. void *temp;
  285. if (!p->time_in_state)
  286. return;
  287. spin_lock_irqsave(&task_time_in_state_lock, flags);
  288. temp = p->time_in_state;
  289. p->time_in_state = NULL;
  290. spin_unlock_irqrestore(&task_time_in_state_lock, flags);
  291. kfree(temp);
  292. }
  293. int proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
  294. struct pid *pid, struct task_struct *p)
  295. {
  296. unsigned int cpu, i;
  297. u64 cputime;
  298. unsigned long flags;
  299. struct cpu_freqs *freqs;
  300. struct cpu_freqs *last_freqs = NULL;
  301. spin_lock_irqsave(&task_time_in_state_lock, flags);
  302. for_each_possible_cpu(cpu) {
  303. freqs = all_freqs[cpu];
  304. if (!freqs || freqs == last_freqs)
  305. continue;
  306. last_freqs = freqs;
  307. seq_printf(m, "cpu%u\n", cpu);
  308. for (i = 0; i < freqs->max_state; i++) {
  309. cputime = 0;
  310. if (freqs->offset + i < p->max_state &&
  311. p->time_in_state)
  312. cputime = p->time_in_state[freqs->offset + i];
  313. seq_printf(m, "%u %lu\n", freqs->freq_table[i],
  314. (unsigned long)nsec_to_clock_t(cputime));
  315. }
  316. }
  317. spin_unlock_irqrestore(&task_time_in_state_lock, flags);
  318. return 0;
  319. }
  320. void cpufreq_acct_update_power(struct task_struct *p, u64 cputime)
  321. {
  322. unsigned long flags;
  323. unsigned int state;
  324. unsigned int active_cpu_cnt = 0;
  325. unsigned int policy_cpu_cnt = 0;
  326. unsigned int policy_first_cpu;
  327. struct uid_entry *uid_entry;
  328. struct cpu_freqs *freqs = all_freqs[task_cpu(p)];
  329. struct cpufreq_policy *policy;
  330. uid_t uid = from_kuid_munged(current_user_ns(), task_uid(p));
  331. int cpu = 0;
  332. if (!freqs || is_idle_task(p) || p->flags & PF_EXITING)
  333. return;
  334. state = freqs->offset + READ_ONCE(freqs->last_index);
  335. spin_lock_irqsave(&task_time_in_state_lock, flags);
  336. if ((state < p->max_state || !cpufreq_task_times_realloc_locked(p)) &&
  337. p->time_in_state)
  338. p->time_in_state[state] += cputime;
  339. spin_unlock_irqrestore(&task_time_in_state_lock, flags);
  340. spin_lock_irqsave(&uid_lock, flags);
  341. uid_entry = find_or_register_uid_locked(uid);
  342. if (uid_entry && state < uid_entry->max_state)
  343. uid_entry->time_in_state[state] += cputime;
  344. spin_unlock_irqrestore(&uid_lock, flags);
  345. rcu_read_lock();
  346. uid_entry = find_uid_entry_rcu(uid);
  347. if (!uid_entry) {
  348. rcu_read_unlock();
  349. return;
  350. }
  351. for_each_possible_cpu(cpu)
  352. if (!idle_cpu(cpu))
  353. ++active_cpu_cnt;
  354. atomic64_add(cputime,
  355. &uid_entry->concurrent_times->active[active_cpu_cnt - 1]);
  356. policy = cpufreq_cpu_get(task_cpu(p));
  357. if (!policy) {
  358. /*
  359. * This CPU may have just come up and not have a cpufreq policy
  360. * yet.
  361. */
  362. rcu_read_unlock();
  363. return;
  364. }
  365. for_each_cpu(cpu, policy->related_cpus)
  366. if (!idle_cpu(cpu))
  367. ++policy_cpu_cnt;
  368. policy_first_cpu = cpumask_first(policy->related_cpus);
  369. cpufreq_cpu_put(policy);
  370. atomic64_add(cputime,
  371. &uid_entry->concurrent_times->policy[policy_first_cpu +
  372. policy_cpu_cnt - 1]);
  373. rcu_read_unlock();
  374. }
  375. static int cpufreq_times_get_index(struct cpu_freqs *freqs, unsigned int freq)
  376. {
  377. int index;
  378. for (index = 0; index < freqs->max_state; ++index) {
  379. if (freqs->freq_table[index] == freq)
  380. return index;
  381. }
  382. return -1;
  383. }
  384. void cpufreq_times_create_policy(struct cpufreq_policy *policy)
  385. {
  386. int cpu, index = 0;
  387. unsigned int count = 0;
  388. struct cpufreq_frequency_table *pos, *table;
  389. struct cpu_freqs *freqs;
  390. void *tmp;
  391. if (all_freqs[policy->cpu])
  392. return;
  393. table = policy->freq_table;
  394. if (!table)
  395. return;
  396. cpufreq_for_each_valid_entry(pos, table)
  397. count++;
  398. tmp = kzalloc(sizeof(*freqs) + sizeof(freqs->freq_table[0]) * count,
  399. GFP_KERNEL);
  400. if (!tmp)
  401. return;
  402. freqs = tmp;
  403. freqs->max_state = count;
  404. cpufreq_for_each_valid_entry(pos, table)
  405. freqs->freq_table[index++] = pos->frequency;
  406. index = cpufreq_times_get_index(freqs, policy->cur);
  407. if (index >= 0)
  408. WRITE_ONCE(freqs->last_index, index);
  409. freqs->offset = next_offset;
  410. WRITE_ONCE(next_offset, freqs->offset + count);
  411. for_each_cpu(cpu, policy->related_cpus)
  412. all_freqs[cpu] = freqs;
  413. }
  414. static void uid_entry_reclaim(struct rcu_head *rcu)
  415. {
  416. struct uid_entry *uid_entry = container_of(rcu, struct uid_entry, rcu);
  417. kfree(uid_entry->concurrent_times);
  418. kfree(uid_entry);
  419. }
  420. void cpufreq_task_times_remove_uids(uid_t uid_start, uid_t uid_end)
  421. {
  422. struct uid_entry *uid_entry;
  423. struct hlist_node *tmp;
  424. unsigned long flags;
  425. spin_lock_irqsave(&uid_lock, flags);
  426. for (; uid_start <= uid_end; uid_start++) {
  427. hash_for_each_possible_safe(uid_hash_table, uid_entry, tmp,
  428. hash, uid_start) {
  429. if (uid_start == uid_entry->uid) {
  430. hash_del_rcu(&uid_entry->hash);
  431. call_rcu(&uid_entry->rcu, uid_entry_reclaim);
  432. }
  433. }
  434. }
  435. spin_unlock_irqrestore(&uid_lock, flags);
  436. }
  437. void cpufreq_times_record_transition(struct cpufreq_policy *policy,
  438. unsigned int new_freq)
  439. {
  440. int index;
  441. struct cpu_freqs *freqs = all_freqs[policy->cpu];
  442. if (!freqs)
  443. return;
  444. index = cpufreq_times_get_index(freqs, new_freq);
  445. if (index >= 0)
  446. WRITE_ONCE(freqs->last_index, index);
  447. }
  448. static const struct seq_operations uid_time_in_state_seq_ops = {
  449. .start = uid_seq_start,
  450. .next = uid_seq_next,
  451. .stop = uid_seq_stop,
  452. .show = uid_time_in_state_seq_show,
  453. };
  454. static int uid_time_in_state_open(struct inode *inode, struct file *file)
  455. {
  456. return seq_open(file, &uid_time_in_state_seq_ops);
  457. }
  458. int single_uid_time_in_state_open(struct inode *inode, struct file *file)
  459. {
  460. return single_open(file, single_uid_time_in_state_show,
  461. &(inode->i_uid));
  462. }
  463. static const struct file_operations uid_time_in_state_fops = {
  464. .open = uid_time_in_state_open,
  465. .read = seq_read,
  466. .llseek = seq_lseek,
  467. .release = seq_release,
  468. };
  469. static const struct seq_operations concurrent_active_time_seq_ops = {
  470. .start = uid_seq_start,
  471. .next = uid_seq_next,
  472. .stop = uid_seq_stop,
  473. .show = concurrent_active_time_seq_show,
  474. };
  475. static int concurrent_active_time_open(struct inode *inode, struct file *file)
  476. {
  477. return seq_open(file, &concurrent_active_time_seq_ops);
  478. }
  479. static const struct file_operations concurrent_active_time_fops = {
  480. .open = concurrent_active_time_open,
  481. .read = seq_read,
  482. .llseek = seq_lseek,
  483. .release = seq_release,
  484. };
  485. static const struct seq_operations concurrent_policy_time_seq_ops = {
  486. .start = uid_seq_start,
  487. .next = uid_seq_next,
  488. .stop = uid_seq_stop,
  489. .show = concurrent_policy_time_seq_show,
  490. };
  491. static int concurrent_policy_time_open(struct inode *inode, struct file *file)
  492. {
  493. return seq_open(file, &concurrent_policy_time_seq_ops);
  494. }
  495. static const struct file_operations concurrent_policy_time_fops = {
  496. .open = concurrent_policy_time_open,
  497. .read = seq_read,
  498. .llseek = seq_lseek,
  499. .release = seq_release,
  500. };
  501. static int __init cpufreq_times_init(void)
  502. {
  503. proc_create_data("uid_time_in_state", 0444, NULL,
  504. &uid_time_in_state_fops, NULL);
  505. proc_create_data("uid_concurrent_active_time", 0444, NULL,
  506. &concurrent_active_time_fops, NULL);
  507. proc_create_data("uid_concurrent_policy_time", 0444, NULL,
  508. &concurrent_policy_time_fops, NULL);
  509. return 0;
  510. }
  511. early_initcall(cpufreq_times_init);