• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <linux/atomic.h>
17 #include <linux/err.h>
18 #include <linux/hashtable.h>
19 #include <linux/init.h>
20 #include <linux/kernel.h>
21 #include <linux/list.h>
22 #include <linux/llist.h>
23 #include <linux/mm.h>
24 #include <linux/proc_fs.h>
25 #include <linux/profile.h>
26 #include <linux/sched/cputime.h>
27 #include <linux/seq_file.h>
28 #include <linux/slab.h>
29 #include <linux/uaccess.h>
30 #include <linux/spinlock_types.h>
31 #include <linux/pm_qos.h>
32 #include <trace/hooks/power.h>
33 
34 #define UID_HASH_BITS	10
35 #define UID_HASH_NUMS	(1 << UID_HASH_BITS)
36 DECLARE_HASHTABLE(hash_table, UID_HASH_BITS);
37 /* uid_lock[bkt] ensure consistency of hash_table[bkt] */
38 spinlock_t uid_lock[UID_HASH_NUMS];
39 
40 #define for_each_bkt(bkt) \
41 	for (bkt = 0; bkt < HASH_SIZE(hash_table); bkt++)
42 
43 /* iterate over all uid_entrys hashing to the same bkt */
44 #define for_each_uid_entry(uid_entry, bkt) \
45 	hlist_for_each_entry(uid_entry, &hash_table[bkt], hash)
46 
47 #define for_each_uid_entry_safe(uid_entry, tmp, bkt) \
48 	hlist_for_each_entry_safe(uid_entry, tmp,\
49 			&hash_table[bkt], hash)
50 
51 #define UPDATE_ANDROID_OEM_DATA(target, source, task, type) \
52 	trace_android_vh_update_uid_stats(target, source, task, type)
53 
54 #ifdef CONFIG_ANDROID_VENDOR_OEM_DATA
55 #define OEM_DATA(x) ((x)->android_oem_data1)
56 #define OEM_DATA_PTR(x) (&(x)->android_oem_data1)
57 #else
oem_data_ptr(void * x)58 static inline u64 *oem_data_ptr(void *x) { return NULL; }
59 #define OEM_DATA(x) 0
60 #define OEM_DATA_PTR(x) oem_data_ptr(x)
61 #endif
62 
63 static struct proc_dir_entry *cpu_parent;
64 static struct proc_dir_entry *io_parent;
65 static struct proc_dir_entry *proc_parent;
66 
67 struct io_stats {
68 	u64 read_bytes;
69 	u64 write_bytes;
70 	u64 rchar;
71 	u64 wchar;
72 	u64 fsync;
73 };
74 
75 #define UID_STATE_FOREGROUND	0
76 #define UID_STATE_BACKGROUND	1
77 #define UID_STATE_TOTAL_LAST	2
78 #define UID_STATE_DEAD_TASKS	3
79 #define UID_STATE_SIZE		4
80 
81 #define MAX_TASK_COMM_LEN 256
82 
83 struct task_entry {
84 	char comm[MAX_TASK_COMM_LEN];
85 	pid_t pid;
86 	struct io_stats io[UID_STATE_SIZE];
87 	struct hlist_node hash;
88 };
89 
90 struct uid_entry {
91 	uid_t uid;
92 	u64 utime;
93 	u64 stime;
94 	int state;
95 	struct io_stats io[UID_STATE_SIZE];
96 	struct hlist_node hash;
97 
98 	ANDROID_OEM_DATA(1);
99 };
100 
init_hash_table_and_lock(void)101 static void init_hash_table_and_lock(void)
102 {
103 	int i;
104 
105 	hash_init(hash_table);
106 	for (i = 0; i < UID_HASH_NUMS; i++)
107 		spin_lock_init(&uid_lock[i]);
108 }
109 
uid_to_bkt(uid_t uid)110 static inline int uid_to_bkt(uid_t uid)
111 {
112 	return hash_min(uid, HASH_BITS(hash_table));
113 }
114 
trylock_uid(uid_t uid)115 static inline int trylock_uid(uid_t uid)
116 {
117 	return spin_trylock(&uid_lock[uid_to_bkt(uid)]);
118 }
119 
lock_uid(uid_t uid)120 static inline void lock_uid(uid_t uid)
121 {
122 	spin_lock(&uid_lock[uid_to_bkt(uid)]);
123 }
124 
unlock_uid(uid_t uid)125 static inline void unlock_uid(uid_t uid)
126 {
127 	spin_unlock(&uid_lock[uid_to_bkt(uid)]);
128 }
129 
lock_uid_by_bkt(u32 bkt)130 static inline void lock_uid_by_bkt(u32 bkt)
131 {
132 	spin_lock(&uid_lock[bkt]);
133 }
134 
unlock_uid_by_bkt(u32 bkt)135 static inline void unlock_uid_by_bkt(u32 bkt)
136 {
137 	spin_unlock(&uid_lock[bkt]);
138 }
139 
compute_write_bytes(struct task_io_accounting * ioac)140 static u64 compute_write_bytes(struct task_io_accounting *ioac)
141 {
142 	if (ioac->write_bytes <= ioac->cancelled_write_bytes)
143 		return 0;
144 
145 	return ioac->write_bytes - ioac->cancelled_write_bytes;
146 }
147 
compute_io_bucket_stats(struct io_stats * io_bucket,struct io_stats * io_curr,struct io_stats * io_last,struct io_stats * io_dead)148 static void compute_io_bucket_stats(struct io_stats *io_bucket,
149 					struct io_stats *io_curr,
150 					struct io_stats *io_last,
151 					struct io_stats *io_dead)
152 {
153 	/* tasks could switch to another uid group, but its io_last in the
154 	 * previous uid group could still be positive.
155 	 * therefore before each update, do an overflow check first
156 	 */
157 	int64_t delta;
158 
159 	delta = io_curr->read_bytes + io_dead->read_bytes -
160 		io_last->read_bytes;
161 	io_bucket->read_bytes += delta > 0 ? delta : 0;
162 	delta = io_curr->write_bytes + io_dead->write_bytes -
163 		io_last->write_bytes;
164 	io_bucket->write_bytes += delta > 0 ? delta : 0;
165 	delta = io_curr->rchar + io_dead->rchar - io_last->rchar;
166 	io_bucket->rchar += delta > 0 ? delta : 0;
167 	delta = io_curr->wchar + io_dead->wchar - io_last->wchar;
168 	io_bucket->wchar += delta > 0 ? delta : 0;
169 	delta = io_curr->fsync + io_dead->fsync - io_last->fsync;
170 	io_bucket->fsync += delta > 0 ? delta : 0;
171 
172 	io_last->read_bytes = io_curr->read_bytes;
173 	io_last->write_bytes = io_curr->write_bytes;
174 	io_last->rchar = io_curr->rchar;
175 	io_last->wchar = io_curr->wchar;
176 	io_last->fsync = io_curr->fsync;
177 
178 	memset(io_dead, 0, sizeof(struct io_stats));
179 }
180 
find_uid_entry(uid_t uid)181 static struct uid_entry *find_uid_entry(uid_t uid)
182 {
183 	struct uid_entry *uid_entry;
184 	u32 bkt = uid_to_bkt(uid);
185 
186 	for_each_uid_entry(uid_entry, bkt) {
187 		if (uid_entry->uid == uid)
188 			return uid_entry;
189 	}
190 	return NULL;
191 }
192 
find_or_register_uid(uid_t uid)193 static struct uid_entry *find_or_register_uid(uid_t uid)
194 {
195 	struct uid_entry *uid_entry;
196 
197 	uid_entry = find_uid_entry(uid);
198 	if (uid_entry)
199 		return uid_entry;
200 
201 	uid_entry = kzalloc(sizeof(struct uid_entry), GFP_ATOMIC);
202 	if (!uid_entry)
203 		return NULL;
204 
205 	uid_entry->uid = uid;
206 	hash_add(hash_table, &uid_entry->hash, uid);
207 
208 	return uid_entry;
209 }
210 
calc_uid_cputime(struct uid_entry * uid_entry,u64 * total_utime,u64 * total_stime,u64 * android_oem_data)211 static void calc_uid_cputime(struct uid_entry *uid_entry,
212 			u64 *total_utime, u64 *total_stime, u64 *android_oem_data)
213 {
214 	struct user_namespace *user_ns = current_user_ns();
215 	struct task_struct *p, *t;
216 	u64 utime, stime;
217 	uid_t uid;
218 
219 	rcu_read_lock();
220 	for_each_process(p) {
221 		uid = from_kuid_munged(user_ns, task_uid(p));
222 
223 		if (uid != uid_entry->uid)
224 			continue;
225 
226 		for_each_thread(p, t) {
227 			/* avoid double accounting of dying threads */
228 			if (!(t->flags & PF_EXITING)) {
229 				UPDATE_ANDROID_OEM_DATA(android_oem_data, NULL, t, 3);
230 				task_cputime_adjusted(t, &utime, &stime);
231 				*total_utime += utime;
232 				*total_stime += stime;
233 			}
234 		}
235 	}
236 	rcu_read_unlock();
237 }
238 
uid_cputime_show(struct seq_file * m,void * v)239 static int uid_cputime_show(struct seq_file *m, void *v)
240 {
241 	struct uid_entry *uid_entry = NULL;
242 	u32 bkt;
243 
244 	for_each_bkt(bkt) {
245 		lock_uid_by_bkt(bkt);
246 		for_each_uid_entry(uid_entry, bkt) {
247 			u64 total_utime = uid_entry->utime;
248 			u64 total_stime = uid_entry->stime;
249 			u64 android_oem_data = OEM_DATA(uid_entry);
250 
251 			calc_uid_cputime(uid_entry, &total_utime,
252 				&total_stime, &android_oem_data);
253 			seq_printf(m, "%d: %llu %llu\n", uid_entry->uid,
254 				ktime_to_us(total_utime), ktime_to_us(total_stime));
255 			trace_android_vh_append_total_power(m, uid_entry->uid,
256 				total_utime, total_stime, android_oem_data);
257 		}
258 		unlock_uid_by_bkt(bkt);
259 	}
260 
261 	return 0;
262 }
263 
uid_cputime_open(struct inode * inode,struct file * file)264 static int uid_cputime_open(struct inode *inode, struct file *file)
265 {
266 	return single_open(file, uid_cputime_show, pde_data(inode));
267 }
268 
269 static const struct proc_ops uid_cputime_fops = {
270 	.proc_open	= uid_cputime_open,
271 	.proc_read	= seq_read,
272 	.proc_lseek	= seq_lseek,
273 	.proc_release	= single_release,
274 };
275 
uid_remove_open(struct inode * inode,struct file * file)276 static int uid_remove_open(struct inode *inode, struct file *file)
277 {
278 	return single_open(file, NULL, NULL);
279 }
280 
uid_remove_write(struct file * file,const char __user * buffer,size_t count,loff_t * ppos)281 static ssize_t uid_remove_write(struct file *file,
282 			const char __user *buffer, size_t count, loff_t *ppos)
283 {
284 	char uids[128];
285 	char *start_uid, *end_uid = NULL;
286 	long int uid_start = 0, uid_end = 0;
287 
288 	if (count >= sizeof(uids))
289 		count = sizeof(uids) - 1;
290 
291 	if (copy_from_user(uids, buffer, count))
292 		return -EFAULT;
293 
294 	uids[count] = '\0';
295 	end_uid = uids;
296 	start_uid = strsep(&end_uid, "-");
297 
298 	if (!start_uid || !end_uid)
299 		return -EINVAL;
300 
301 	if (kstrtol(start_uid, 10, &uid_start) != 0 ||
302 		kstrtol(end_uid, 10, &uid_end) != 0) {
303 		return -EINVAL;
304 	}
305 
306 	for (; uid_start <= uid_end; uid_start++) {
307 		struct uid_entry *uid_entry;
308 		struct hlist_node *tmp;
309 		u32 bkt = uid_to_bkt((uid_t)uid_start);
310 
311 		lock_uid(uid_start);
312 		for_each_uid_entry_safe(uid_entry, tmp, bkt) {
313 			if (uid_start == uid_entry->uid) {
314 				hash_del(&uid_entry->hash);
315 				kfree(uid_entry);
316 			}
317 		}
318 		unlock_uid(uid_start);
319 	}
320 
321 	return count;
322 }
323 
324 static const struct proc_ops uid_remove_fops = {
325 	.proc_open	= uid_remove_open,
326 	.proc_release	= single_release,
327 	.proc_write	= uid_remove_write,
328 };
329 
__add_uid_io_stats(struct uid_entry * uid_entry,struct task_io_accounting * ioac,int slot)330 static void __add_uid_io_stats(struct uid_entry *uid_entry,
331 			struct task_io_accounting *ioac, int slot)
332 {
333 	struct io_stats *io_slot = &uid_entry->io[slot];
334 
335 	io_slot->read_bytes += ioac->read_bytes;
336 	io_slot->write_bytes += compute_write_bytes(ioac);
337 	io_slot->rchar += ioac->rchar;
338 	io_slot->wchar += ioac->wchar;
339 	io_slot->fsync += ioac->syscfs;
340 }
341 
add_uid_io_stats(struct uid_entry * uid_entry,struct task_struct * task,int slot)342 static void add_uid_io_stats(struct uid_entry *uid_entry,
343 			struct task_struct *task, int slot)
344 {
345 	struct task_entry *task_entry __maybe_unused;
346 
347 	/* avoid double accounting of dying threads */
348 	if (slot != UID_STATE_DEAD_TASKS && (task->flags & PF_EXITING))
349 		return;
350 
351 	__add_uid_io_stats(uid_entry, &task->ioac, slot);
352 }
353 
update_io_stats_uid(struct uid_entry * uid_entry)354 static void update_io_stats_uid(struct uid_entry *uid_entry)
355 {
356 	struct user_namespace *user_ns = current_user_ns();
357 	struct task_struct *p, *t;
358 	struct io_stats io;
359 
360 	memset(&io, 0, sizeof(struct io_stats));
361 
362 	rcu_read_lock();
363 	for_each_process(p) {
364 		uid_t uid = from_kuid_munged(user_ns, task_uid(p));
365 
366 		if (uid != uid_entry->uid)
367 			continue;
368 
369 		for_each_thread(p, t) {
370 			/* avoid double accounting of dying threads */
371 			if (!(t->flags & PF_EXITING)) {
372 				io.read_bytes += t->ioac.read_bytes;
373 				io.write_bytes += compute_write_bytes(&t->ioac);
374 				io.rchar += t->ioac.rchar;
375 				io.wchar += t->ioac.wchar;
376 				io.fsync += t->ioac.syscfs;
377 			}
378 		}
379 	}
380 	rcu_read_unlock();
381 
382 	compute_io_bucket_stats(&uid_entry->io[uid_entry->state], &io,
383 					&uid_entry->io[UID_STATE_TOTAL_LAST],
384 					&uid_entry->io[UID_STATE_DEAD_TASKS]);
385 }
386 
uid_io_show(struct seq_file * m,void * v)387 static int uid_io_show(struct seq_file *m, void *v)
388 {
389 
390 	struct uid_entry *uid_entry = NULL;
391 	u32 bkt;
392 
393 	for_each_bkt(bkt) {
394 		lock_uid_by_bkt(bkt);
395 		for_each_uid_entry(uid_entry, bkt) {
396 
397 			update_io_stats_uid(uid_entry);
398 
399 			seq_printf(m, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
400 				uid_entry->uid,
401 				uid_entry->io[UID_STATE_FOREGROUND].rchar,
402 				uid_entry->io[UID_STATE_FOREGROUND].wchar,
403 				uid_entry->io[UID_STATE_FOREGROUND].read_bytes,
404 				uid_entry->io[UID_STATE_FOREGROUND].write_bytes,
405 				uid_entry->io[UID_STATE_BACKGROUND].rchar,
406 				uid_entry->io[UID_STATE_BACKGROUND].wchar,
407 				uid_entry->io[UID_STATE_BACKGROUND].read_bytes,
408 				uid_entry->io[UID_STATE_BACKGROUND].write_bytes,
409 				uid_entry->io[UID_STATE_FOREGROUND].fsync,
410 				uid_entry->io[UID_STATE_BACKGROUND].fsync);
411 		}
412 		unlock_uid_by_bkt(bkt);
413 	}
414 
415 	return 0;
416 }
417 
uid_io_open(struct inode * inode,struct file * file)418 static int uid_io_open(struct inode *inode, struct file *file)
419 {
420 	return single_open(file, uid_io_show, pde_data(inode));
421 }
422 
423 static const struct proc_ops uid_io_fops = {
424 	.proc_open	= uid_io_open,
425 	.proc_read	= seq_read,
426 	.proc_lseek	= seq_lseek,
427 	.proc_release	= single_release,
428 };
429 
uid_procstat_open(struct inode * inode,struct file * file)430 static int uid_procstat_open(struct inode *inode, struct file *file)
431 {
432 	return single_open(file, NULL, NULL);
433 }
434 
uid_procstat_write(struct file * file,const char __user * buffer,size_t count,loff_t * ppos)435 static ssize_t uid_procstat_write(struct file *file,
436 			const char __user *buffer, size_t count, loff_t *ppos)
437 {
438 	struct uid_entry *uid_entry;
439 	uid_t uid;
440 	int argc, state;
441 	char input[128];
442 
443 	if (count >= sizeof(input))
444 		return -EINVAL;
445 
446 	if (copy_from_user(input, buffer, count))
447 		return -EFAULT;
448 
449 	input[count] = '\0';
450 
451 	argc = sscanf(input, "%u %d", &uid, &state);
452 	if (argc != 2)
453 		return -EINVAL;
454 
455 	if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND)
456 		return -EINVAL;
457 
458 	lock_uid(uid);
459 	uid_entry = find_or_register_uid(uid);
460 	if (!uid_entry) {
461 		unlock_uid(uid);
462 		return -EINVAL;
463 	}
464 
465 	if (uid_entry->state == state) {
466 		unlock_uid(uid);
467 		return count;
468 	}
469 
470 	update_io_stats_uid(uid_entry);
471 	uid_entry->state = state;
472 	unlock_uid(uid);
473 
474 	return count;
475 }
476 
477 static const struct proc_ops uid_procstat_fops = {
478 	.proc_open	= uid_procstat_open,
479 	.proc_release	= single_release,
480 	.proc_write	= uid_procstat_write,
481 };
482 
483 struct update_stats_work {
484 	uid_t uid;
485 	struct task_io_accounting ioac;
486 	u64 utime;
487 	u64 stime;
488 	struct llist_node node;
489 
490 	ANDROID_OEM_DATA(1);
491 };
492 
493 static LLIST_HEAD(work_usw);
494 
update_stats_workfn(struct work_struct * work)495 static void update_stats_workfn(struct work_struct *work)
496 {
497 	struct update_stats_work *usw, *t;
498 	struct uid_entry *uid_entry;
499 	struct task_entry *task_entry __maybe_unused;
500 	struct llist_node *node;
501 
502 	node = llist_del_all(&work_usw);
503 	llist_for_each_entry_safe(usw, t, node, node) {
504 		lock_uid(usw->uid);
505 		uid_entry = find_uid_entry(usw->uid);
506 		if (!uid_entry)
507 			goto next;
508 
509 		uid_entry->utime += usw->utime;
510 		uid_entry->stime += usw->stime;
511 		UPDATE_ANDROID_OEM_DATA(OEM_DATA_PTR(uid_entry),
512 					OEM_DATA_PTR(usw), NULL, 0);
513 
514 		__add_uid_io_stats(uid_entry, &usw->ioac, UID_STATE_DEAD_TASKS);
515 next:
516 		unlock_uid(usw->uid);
517 		kfree(usw);
518 	}
519 
520 }
521 static DECLARE_WORK(update_stats_work, update_stats_workfn);
522 
process_notifier(struct notifier_block * self,unsigned long cmd,void * v)523 static int process_notifier(struct notifier_block *self,
524 			unsigned long cmd, void *v)
525 {
526 	struct task_struct *task = v;
527 	struct uid_entry *uid_entry;
528 	u64 utime, stime;
529 	uid_t uid;
530 
531 	if (!task)
532 		return NOTIFY_OK;
533 
534 	uid = from_kuid_munged(current_user_ns(), task_uid(task));
535 	if (!trylock_uid(uid)) {
536 		struct update_stats_work *usw;
537 
538 		usw = kmalloc(sizeof(struct update_stats_work), GFP_KERNEL);
539 		if (usw) {
540 			usw->uid = uid;
541 			/*
542 			 * Copy task->ioac since task might be destroyed before
543 			 * the work is later performed.
544 			 */
545 			usw->ioac = task->ioac;
546 			task_cputime_adjusted(task, &usw->utime, &usw->stime);
547 #ifdef CONFIG_ANDROID_VENDOR_OEM_DATA
548 			usw->android_oem_data1 = 0;
549 #endif
550 			UPDATE_ANDROID_OEM_DATA(NULL, OEM_DATA_PTR(usw), task, 1);
551 			llist_add(&usw->node, &work_usw);
552 			schedule_work(&update_stats_work);
553 		}
554 		return NOTIFY_OK;
555 	}
556 
557 	uid_entry = find_or_register_uid(uid);
558 	if (!uid_entry) {
559 		pr_err("%s: failed to find uid %d\n", __func__, uid);
560 		goto exit;
561 	}
562 
563 	task_cputime_adjusted(task, &utime, &stime);
564 	uid_entry->utime += utime;
565 	uid_entry->stime += stime;
566 	UPDATE_ANDROID_OEM_DATA(OEM_DATA_PTR(uid_entry), NULL, task, 2);
567 
568 	add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS);
569 
570 exit:
571 	unlock_uid(uid);
572 	return NOTIFY_OK;
573 }
574 
575 static struct notifier_block process_notifier_block = {
576 	.notifier_call	= process_notifier,
577 };
578 
proc_uid_sys_stats_init(void)579 static int __init proc_uid_sys_stats_init(void)
580 {
581 	init_hash_table_and_lock();
582 
583 	cpu_parent = proc_mkdir("uid_cputime", NULL);
584 	if (!cpu_parent) {
585 		pr_err("%s: failed to create uid_cputime proc entry\n",
586 			__func__);
587 		goto err;
588 	}
589 
590 	proc_create_data("remove_uid_range", 0222, cpu_parent,
591 		&uid_remove_fops, NULL);
592 	proc_create_data("show_uid_stat", 0444, cpu_parent,
593 		&uid_cputime_fops, NULL);
594 
595 	io_parent = proc_mkdir("uid_io", NULL);
596 	if (!io_parent) {
597 		pr_err("%s: failed to create uid_io proc entry\n",
598 			__func__);
599 		goto err;
600 	}
601 
602 	proc_create_data("stats", 0444, io_parent,
603 		&uid_io_fops, NULL);
604 
605 	proc_parent = proc_mkdir("uid_procstat", NULL);
606 	if (!proc_parent) {
607 		pr_err("%s: failed to create uid_procstat proc entry\n",
608 			__func__);
609 		goto err;
610 	}
611 
612 	proc_create_data("set", 0222, proc_parent,
613 		&uid_procstat_fops, NULL);
614 
615 	profile_event_register(PROFILE_TASK_EXIT, &process_notifier_block);
616 
617 	return 0;
618 
619 err:
620 	remove_proc_subtree("uid_cputime", NULL);
621 	remove_proc_subtree("uid_io", NULL);
622 	remove_proc_subtree("uid_procstat", NULL);
623 	return -ENOMEM;
624 }
625 
626 early_initcall(proc_uid_sys_stats_init);
627