uid_sys_stats.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /* drivers/misc/uid_sys_stats.c
  2. *
  3. * Copyright (C) 2014 - 2015 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/atomic.h>
  16. #include <linux/err.h>
  17. #include <linux/hashtable.h>
  18. #include <linux/init.h>
  19. #include <linux/kernel.h>
  20. #include <linux/list.h>
  21. #include <linux/llist.h>
  22. #include <linux/mm.h>
  23. #include <linux/proc_fs.h>
  24. #include <linux/profile.h>
  25. #include <linux/sched/cputime.h>
  26. #include <linux/seq_file.h>
  27. #include <linux/slab.h>
  28. #include <linux/uaccess.h>
  29. #include <linux/spinlock_types.h>
  30. #define UID_HASH_BITS 10
  31. #define UID_HASH_NUMS (1 << UID_HASH_BITS)
  32. DECLARE_HASHTABLE(hash_table, UID_HASH_BITS);
  33. /*
  34. * uid_lock[bkt] ensure consistency of hash_table[bkt]
  35. */
  36. spinlock_t uid_lock[UID_HASH_NUMS];
  37. static struct proc_dir_entry *cpu_parent;
  38. static struct proc_dir_entry *io_parent;
  39. static struct proc_dir_entry *proc_parent;
  40. struct io_stats {
  41. u64 read_bytes;
  42. u64 write_bytes;
  43. u64 rchar;
  44. u64 wchar;
  45. u64 fsync;
  46. };
  47. #define UID_STATE_FOREGROUND 0
  48. #define UID_STATE_BACKGROUND 1
  49. #define UID_STATE_TOTAL_LAST 2
  50. #define UID_STATE_DEAD_TASKS 3
  51. #define UID_STATE_SIZE 4
  52. #define MAX_TASK_COMM_LEN 256
  53. struct task_entry {
  54. char comm[MAX_TASK_COMM_LEN];
  55. pid_t pid;
  56. struct io_stats io[UID_STATE_SIZE];
  57. struct hlist_node hash;
  58. };
  59. struct uid_entry {
  60. uid_t uid;
  61. u64 utime;
  62. u64 stime;
  63. int state;
  64. struct io_stats io[UID_STATE_SIZE];
  65. struct hlist_node hash;
  66. };
  67. static inline int trylock_uid(uid_t uid)
  68. {
  69. return spin_trylock(
  70. &uid_lock[hash_min(uid, HASH_BITS(hash_table))]);
  71. }
  72. static inline void lock_uid(uid_t uid)
  73. {
  74. spin_lock(&uid_lock[hash_min(uid, HASH_BITS(hash_table))]);
  75. }
  76. static inline void unlock_uid(uid_t uid)
  77. {
  78. spin_unlock(&uid_lock[hash_min(uid, HASH_BITS(hash_table))]);
  79. }
  80. static inline void lock_uid_by_bkt(u32 bkt)
  81. {
  82. spin_lock(&uid_lock[bkt]);
  83. }
  84. static inline void unlock_uid_by_bkt(u32 bkt)
  85. {
  86. spin_unlock(&uid_lock[bkt]);
  87. }
  88. static u64 compute_write_bytes(struct task_io_accounting *ioac)
  89. {
  90. if (ioac->write_bytes <= ioac->cancelled_write_bytes)
  91. return 0;
  92. return ioac->write_bytes - ioac->cancelled_write_bytes;
  93. }
  94. static void compute_io_bucket_stats(struct io_stats *io_bucket,
  95. struct io_stats *io_curr,
  96. struct io_stats *io_last,
  97. struct io_stats *io_dead)
  98. {
  99. /* tasks could switch to another uid group, but its io_last in the
  100. * previous uid group could still be positive.
  101. * therefore before each update, do an overflow check first
  102. */
  103. int64_t delta;
  104. delta = io_curr->read_bytes + io_dead->read_bytes -
  105. io_last->read_bytes;
  106. io_bucket->read_bytes += delta > 0 ? delta : 0;
  107. delta = io_curr->write_bytes + io_dead->write_bytes -
  108. io_last->write_bytes;
  109. io_bucket->write_bytes += delta > 0 ? delta : 0;
  110. delta = io_curr->rchar + io_dead->rchar - io_last->rchar;
  111. io_bucket->rchar += delta > 0 ? delta : 0;
  112. delta = io_curr->wchar + io_dead->wchar - io_last->wchar;
  113. io_bucket->wchar += delta > 0 ? delta : 0;
  114. delta = io_curr->fsync + io_dead->fsync - io_last->fsync;
  115. io_bucket->fsync += delta > 0 ? delta : 0;
  116. io_last->read_bytes = io_curr->read_bytes;
  117. io_last->write_bytes = io_curr->write_bytes;
  118. io_last->rchar = io_curr->rchar;
  119. io_last->wchar = io_curr->wchar;
  120. io_last->fsync = io_curr->fsync;
  121. memset(io_dead, 0, sizeof(struct io_stats));
  122. }
  123. static struct uid_entry *find_uid_entry(uid_t uid)
  124. {
  125. struct uid_entry *uid_entry;
  126. hash_for_each_possible(hash_table, uid_entry, hash, uid) {
  127. if (uid_entry->uid == uid)
  128. return uid_entry;
  129. }
  130. return NULL;
  131. }
  132. static struct uid_entry *find_or_register_uid(uid_t uid)
  133. {
  134. struct uid_entry *uid_entry;
  135. uid_entry = find_uid_entry(uid);
  136. if (uid_entry)
  137. return uid_entry;
  138. uid_entry = kzalloc(sizeof(struct uid_entry), GFP_ATOMIC);
  139. if (!uid_entry)
  140. return NULL;
  141. uid_entry->uid = uid;
  142. hash_add(hash_table, &uid_entry->hash, uid);
  143. return uid_entry;
  144. }
  145. static void calc_uid_cputime(struct uid_entry *uid_entry,
  146. u64 *total_utime, u64 *total_stime)
  147. {
  148. struct user_namespace *user_ns = current_user_ns();
  149. struct task_struct *p, *t;
  150. u64 utime, stime;
  151. uid_t uid;
  152. rcu_read_lock();
  153. for_each_process(p) {
  154. uid = from_kuid_munged(user_ns, task_uid(p));
  155. if (uid != uid_entry->uid)
  156. continue;
  157. for_each_thread(p, t) {
  158. /* avoid double accounting of dying threads */
  159. if (!(t->flags & PF_EXITING)) {
  160. task_cputime_adjusted(t, &utime, &stime);
  161. *total_utime += utime;
  162. *total_stime += stime;
  163. }
  164. }
  165. }
  166. rcu_read_unlock();
  167. }
  168. static int uid_cputime_show(struct seq_file *m, void *v)
  169. {
  170. struct uid_entry *uid_entry = NULL;
  171. u32 bkt;
  172. for (bkt = 0, uid_entry = NULL; uid_entry == NULL &&
  173. bkt < HASH_SIZE(hash_table); bkt++) {
  174. lock_uid_by_bkt(bkt);
  175. hlist_for_each_entry(uid_entry, &hash_table[bkt], hash) {
  176. u64 total_utime = uid_entry->utime;
  177. u64 total_stime = uid_entry->stime;
  178. calc_uid_cputime(uid_entry, &total_utime, &total_stime);
  179. seq_printf(m, "%d: %llu %llu\n", uid_entry->uid,
  180. ktime_to_us(total_utime), ktime_to_us(total_stime));
  181. }
  182. unlock_uid_by_bkt(bkt);
  183. }
  184. return 0;
  185. }
  186. static int uid_cputime_open(struct inode *inode, struct file *file)
  187. {
  188. return single_open(file, uid_cputime_show, pde_data(inode));
  189. }
  190. static const struct proc_ops uid_cputime_fops = {
  191. .proc_open = uid_cputime_open,
  192. .proc_read = seq_read,
  193. .proc_lseek = seq_lseek,
  194. .proc_release = single_release,
  195. };
  196. static int uid_remove_open(struct inode *inode, struct file *file)
  197. {
  198. return single_open(file, NULL, NULL);
  199. }
  200. static ssize_t uid_remove_write(struct file *file,
  201. const char __user *buffer, size_t count, loff_t *ppos)
  202. {
  203. struct uid_entry *uid_entry;
  204. struct hlist_node *tmp;
  205. char uids[128];
  206. char *start_uid, *end_uid = NULL;
  207. long int uid_start = 0, uid_end = 0;
  208. if (count >= sizeof(uids))
  209. count = sizeof(uids) - 1;
  210. if (copy_from_user(uids, buffer, count))
  211. return -EFAULT;
  212. uids[count] = '\0';
  213. end_uid = uids;
  214. start_uid = strsep(&end_uid, "-");
  215. if (!start_uid || !end_uid)
  216. return -EINVAL;
  217. if (kstrtol(start_uid, 10, &uid_start) != 0 ||
  218. kstrtol(end_uid, 10, &uid_end) != 0) {
  219. return -EINVAL;
  220. }
  221. for (; uid_start <= uid_end; uid_start++) {
  222. lock_uid(uid_start);
  223. hash_for_each_possible_safe(hash_table, uid_entry, tmp,
  224. hash, (uid_t)uid_start) {
  225. if (uid_start == uid_entry->uid) {
  226. hash_del(&uid_entry->hash);
  227. kfree(uid_entry);
  228. }
  229. }
  230. unlock_uid(uid_start);
  231. }
  232. return count;
  233. }
  234. static const struct proc_ops uid_remove_fops = {
  235. .proc_open = uid_remove_open,
  236. .proc_release = single_release,
  237. .proc_write = uid_remove_write,
  238. };
  239. static void __add_uid_io_stats(struct uid_entry *uid_entry,
  240. struct task_io_accounting *ioac, int slot)
  241. {
  242. struct io_stats *io_slot = &uid_entry->io[slot];
  243. io_slot->read_bytes += ioac->read_bytes;
  244. io_slot->write_bytes += compute_write_bytes(ioac);
  245. io_slot->rchar += ioac->rchar;
  246. io_slot->wchar += ioac->wchar;
  247. io_slot->fsync += ioac->syscfs;
  248. }
  249. static void add_uid_io_stats(struct uid_entry *uid_entry,
  250. struct task_struct *task, int slot)
  251. {
  252. struct task_entry *task_entry __maybe_unused;
  253. /* avoid double accounting of dying threads */
  254. if (slot != UID_STATE_DEAD_TASKS && (task->flags & PF_EXITING))
  255. return;
  256. __add_uid_io_stats(uid_entry, &task->ioac, slot);
  257. }
  258. static void update_io_stats_uid(struct uid_entry *uid_entry)
  259. {
  260. struct user_namespace *user_ns = current_user_ns();
  261. struct task_struct *p, *t;
  262. struct io_stats io;
  263. memset(&io, 0, sizeof(struct io_stats));
  264. rcu_read_lock();
  265. for_each_process(p) {
  266. uid_t uid = from_kuid_munged(user_ns, task_uid(p));
  267. if (uid != uid_entry->uid)
  268. continue;
  269. for_each_thread(p, t) {
  270. /* avoid double accounting of dying threads */
  271. if (!(t->flags & PF_EXITING)) {
  272. io.read_bytes += t->ioac.read_bytes;
  273. io.write_bytes += compute_write_bytes(&t->ioac);
  274. io.rchar += t->ioac.rchar;
  275. io.wchar += t->ioac.wchar;
  276. io.fsync += t->ioac.syscfs;
  277. }
  278. }
  279. }
  280. rcu_read_unlock();
  281. compute_io_bucket_stats(&uid_entry->io[uid_entry->state], &io,
  282. &uid_entry->io[UID_STATE_TOTAL_LAST],
  283. &uid_entry->io[UID_STATE_DEAD_TASKS]);
  284. }
  285. static int uid_io_show(struct seq_file *m, void *v)
  286. {
  287. struct uid_entry *uid_entry = NULL;
  288. u32 bkt;
  289. for (bkt = 0, uid_entry = NULL; uid_entry == NULL && bkt < HASH_SIZE(hash_table);
  290. bkt++) {
  291. lock_uid_by_bkt(bkt);
  292. hlist_for_each_entry(uid_entry, &hash_table[bkt], hash) {
  293. update_io_stats_uid(uid_entry);
  294. seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
  295. uid_entry->uid,
  296. uid_entry->io[UID_STATE_FOREGROUND].rchar,
  297. uid_entry->io[UID_STATE_FOREGROUND].wchar,
  298. uid_entry->io[UID_STATE_FOREGROUND].read_bytes,
  299. uid_entry->io[UID_STATE_FOREGROUND].write_bytes,
  300. uid_entry->io[UID_STATE_BACKGROUND].rchar,
  301. uid_entry->io[UID_STATE_BACKGROUND].wchar,
  302. uid_entry->io[UID_STATE_BACKGROUND].read_bytes,
  303. uid_entry->io[UID_STATE_BACKGROUND].write_bytes,
  304. uid_entry->io[UID_STATE_FOREGROUND].fsync,
  305. uid_entry->io[UID_STATE_BACKGROUND].fsync);
  306. }
  307. unlock_uid_by_bkt(bkt);
  308. }
  309. return 0;
  310. }
  311. static int uid_io_open(struct inode *inode, struct file *file)
  312. {
  313. return single_open(file, uid_io_show, pde_data(inode));
  314. }
  315. static const struct proc_ops uid_io_fops = {
  316. .proc_open = uid_io_open,
  317. .proc_read = seq_read,
  318. .proc_lseek = seq_lseek,
  319. .proc_release = single_release,
  320. };
  321. static int uid_procstat_open(struct inode *inode, struct file *file)
  322. {
  323. return single_open(file, NULL, NULL);
  324. }
  325. static ssize_t uid_procstat_write(struct file *file,
  326. const char __user *buffer, size_t count, loff_t *ppos)
  327. {
  328. struct uid_entry *uid_entry;
  329. uid_t uid;
  330. int argc, state;
  331. char input[128];
  332. if (count >= sizeof(input))
  333. return -EINVAL;
  334. if (copy_from_user(input, buffer, count))
  335. return -EFAULT;
  336. input[count] = '\0';
  337. argc = sscanf(input, "%u %d", &uid, &state);
  338. if (argc != 2)
  339. return -EINVAL;
  340. if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND)
  341. return -EINVAL;
  342. lock_uid(uid);
  343. uid_entry = find_or_register_uid(uid);
  344. if (!uid_entry) {
  345. unlock_uid(uid);
  346. return -EINVAL;
  347. }
  348. if (uid_entry->state == state) {
  349. unlock_uid(uid);
  350. return count;
  351. }
  352. update_io_stats_uid(uid_entry);
  353. uid_entry->state = state;
  354. unlock_uid(uid);
  355. return count;
  356. }
  357. static const struct proc_ops uid_procstat_fops = {
  358. .proc_open = uid_procstat_open,
  359. .proc_release = single_release,
  360. .proc_write = uid_procstat_write,
  361. };
  362. struct update_stats_work {
  363. uid_t uid;
  364. struct task_io_accounting ioac;
  365. u64 utime;
  366. u64 stime;
  367. struct llist_node node;
  368. };
  369. static LLIST_HEAD(work_usw);
  370. static void update_stats_workfn(struct work_struct *work)
  371. {
  372. struct update_stats_work *usw, *t;
  373. struct uid_entry *uid_entry;
  374. struct task_entry *task_entry __maybe_unused;
  375. struct llist_node *node;
  376. node = llist_del_all(&work_usw);
  377. llist_for_each_entry_safe(usw, t, node, node) {
  378. lock_uid(usw->uid);
  379. uid_entry = find_uid_entry(usw->uid);
  380. if (!uid_entry)
  381. goto next;
  382. uid_entry->utime += usw->utime;
  383. uid_entry->stime += usw->stime;
  384. __add_uid_io_stats(uid_entry, &usw->ioac, UID_STATE_DEAD_TASKS);
  385. next:
  386. unlock_uid(usw->uid);
  387. kfree(usw);
  388. }
  389. }
  390. static DECLARE_WORK(update_stats_work, update_stats_workfn);
  391. static int process_notifier(struct notifier_block *self,
  392. unsigned long cmd, void *v)
  393. {
  394. struct task_struct *task = v;
  395. struct uid_entry *uid_entry;
  396. u64 utime, stime;
  397. uid_t uid;
  398. if (!task)
  399. return NOTIFY_OK;
  400. uid = from_kuid_munged(current_user_ns(), task_uid(task));
  401. if (!trylock_uid(uid)) {
  402. struct update_stats_work *usw;
  403. usw = kmalloc(sizeof(struct update_stats_work), GFP_KERNEL);
  404. if (usw) {
  405. usw->uid = uid;
  406. /*
  407. * Copy task->ioac since task might be destroyed before
  408. * the work is later performed.
  409. */
  410. usw->ioac = task->ioac;
  411. task_cputime_adjusted(task, &usw->utime, &usw->stime);
  412. llist_add(&usw->node, &work_usw);
  413. schedule_work(&update_stats_work);
  414. }
  415. return NOTIFY_OK;
  416. }
  417. uid_entry = find_or_register_uid(uid);
  418. if (!uid_entry) {
  419. pr_err("%s: failed to find uid %d\n", __func__, uid);
  420. goto exit;
  421. }
  422. task_cputime_adjusted(task, &utime, &stime);
  423. uid_entry->utime += utime;
  424. uid_entry->stime += stime;
  425. add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS);
  426. exit:
  427. unlock_uid(uid);
  428. return NOTIFY_OK;
  429. }
  430. static struct notifier_block process_notifier_block = {
  431. .notifier_call = process_notifier,
  432. };
  433. static void init_hash_table_and_lock(void)
  434. {
  435. int i;
  436. hash_init(hash_table);
  437. for (i = 0; i < UID_HASH_NUMS; i++)
  438. spin_lock_init(&uid_lock[i]);
  439. }
  440. static int __init proc_uid_sys_stats_init(void)
  441. {
  442. init_hash_table_and_lock();
  443. cpu_parent = proc_mkdir("uid_cputime", NULL);
  444. if (!cpu_parent) {
  445. pr_err("%s: failed to create uid_cputime proc entry\n",
  446. __func__);
  447. goto err;
  448. }
  449. proc_create_data("remove_uid_range", 0222, cpu_parent,
  450. &uid_remove_fops, NULL);
  451. proc_create_data("show_uid_stat", 0444, cpu_parent,
  452. &uid_cputime_fops, NULL);
  453. io_parent = proc_mkdir("uid_io", NULL);
  454. if (!io_parent) {
  455. pr_err("%s: failed to create uid_io proc entry\n",
  456. __func__);
  457. goto err;
  458. }
  459. proc_create_data("stats", 0444, io_parent,
  460. &uid_io_fops, NULL);
  461. proc_parent = proc_mkdir("uid_procstat", NULL);
  462. if (!proc_parent) {
  463. pr_err("%s: failed to create uid_procstat proc entry\n",
  464. __func__);
  465. goto err;
  466. }
  467. proc_create_data("set", 0222, proc_parent,
  468. &uid_procstat_fops, NULL);
  469. profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block);
  470. return 0;
  471. err:
  472. remove_proc_subtree("uid_cputime", NULL);
  473. remove_proc_subtree("uid_io", NULL);
  474. remove_proc_subtree("uid_procstat", NULL);
  475. return -ENOMEM;
  476. }
  477. early_initcall(proc_uid_sys_stats_init);