ANDROID: cpufreq: stats: add uid removal for uid_time_in_state
authorAndres Oportus <andresoportus@google.com>
Mon, 5 Jun 2017 19:46:44 +0000 (12:46 -0700)
committerDanny Wood <danwood76@gmail.com>
Sun, 31 Mar 2019 08:48:12 +0000 (09:48 +0100)
Bug: 62295304
Bug: 34133340
Test: Boot and test uid removal by writing to remove_uid_range

Signed-off-by: Andres Oportus <andresoportus@google.com>
Change-Id: Ic51fc9480716a8aad88fb55549c2b69021038a11

Conflicts:
drivers/cpufreq/cpufreq_stats.c
include/linux/cpufreq.h
Signed-off-by: Francisco Franco <franciscofranco.1990@gmail.com>
drivers/cpufreq/cpufreq_stats.c
drivers/misc/uid_sys_stats.c
include/linux/cpufreq.h

index 68ea9aeac77080eb2a921e96d2543556a8c4e9b3..bbecdcee412c820087b8cb893d72600d71c53db9 100644 (file)
@@ -865,6 +865,27 @@ static void cpufreq_allstats_create(unsigned int cpu,
        spin_unlock(&cpufreq_stats_lock);
 }
 
+void cpufreq_task_stats_remove_uids(uid_t uid_start, uid_t uid_end)
+{
+       struct uid_entry *uid_entry;
+       struct hlist_node *tmp;
+
+       rt_mutex_lock(&uid_lock);
+
+       for (; uid_start <= uid_end; uid_start++) {
+               hash_for_each_possible_safe(uid_hash_table, uid_entry, tmp,
+                       hash, uid_start) {
+                       if (uid_start == uid_entry->uid) {
+                               hash_del(&uid_entry->hash);
+                               kfree(uid_entry->dead_time_in_state);
+                               kfree(uid_entry);
+                       }
+               }
+       }
+
+       rt_mutex_unlock(&uid_lock);
+}
+
 static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
                unsigned long val, void *data)
 {
index d677b37e4804ab8ab74ebd94c4781cdc1ae92dbd..412f3200ada1d921e794dadd2c0cf147a0d07dba 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/rtmutex.h>
+#include <linux/cpufreq.h>
 
 #define UID_HASH_BITS  10
 DECLARE_HASHTABLE(hash_table, UID_HASH_BITS);
@@ -173,7 +174,8 @@ static ssize_t uid_remove_write(struct file *file,
        struct hlist_node *tmp;
        char uids[128];
        char *start_uid, *end_uid = NULL;
-       long int uid_start = 0, uid_end = 0;
+       long int start = 0, end = 0;
+       uid_t uid_start, uid_end;
 
        if (count >= sizeof(uids))
                count = sizeof(uids) - 1;
@@ -188,15 +190,32 @@ static ssize_t uid_remove_write(struct file *file,
        if (!start_uid || !end_uid)
                return -EINVAL;
 
-       if (kstrtol(start_uid, 10, &uid_start) != 0 ||
-               kstrtol(end_uid, 10, &uid_end) != 0) {
+       if (kstrtol(start_uid, 10, &start) != 0 ||
+               kstrtol(end_uid, 10, &end) != 0) {
                return -EINVAL;
        }
+
+#define UID_T_MAX (((uid_t)~0U)-1)
+       if ((start < 0) || (end < 0) ||
+               (start > UID_T_MAX) || (end > UID_T_MAX)) {
+               return -EINVAL;
+       }
+
+       uid_start = start;
+       uid_end = end;
+
+       /* TODO need to unify uid_sys_stats interface with uid_time_in_state.
+        * Here we are reusing remove_uid_range to reduce the number of
+        * sys calls made by userspace clients, remove_uid_range removes uids
+        * from both here as well as from cpufreq uid_time_in_state
+        */
+       cpufreq_task_stats_remove_uids(uid_start, uid_end);
+
        rt_mutex_lock(&uid_lock);
 
        for (; uid_start <= uid_end; uid_start++) {
                hash_for_each_possible_safe(hash_table, uid_entry, tmp,
-                                                       hash, (uid_t)uid_start) {
+                                                       hash, uid_start) {
                        if (uid_start == uid_entry->uid) {
                                hash_del(&uid_entry->hash);
                                kfree(uid_entry);
@@ -205,6 +224,7 @@ static ssize_t uid_remove_write(struct file *file,
        }
 
        rt_mutex_unlock(&uid_lock);
+
        return count;
 }
 
index 574db4e70aedde20fb0847530138dd8269a7e75b..e4b33a7b165cb29f0bdfcb7cca55ae1682fa6e5d 100644 (file)
@@ -480,12 +480,15 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu);
 void acct_update_power(struct task_struct *p, cputime_t cputime);
 void cpufreq_task_stats_init(struct task_struct *p);
 void cpufreq_task_stats_exit(struct task_struct *p);
+void cpufreq_task_stats_remove_uids(uid_t uid_start, uid_t uid_end);
 int  proc_time_in_state_show(struct seq_file *m, struct pid_namespace *ns,
-                            struct pid *pid, struct task_struct *p);
+       struct pid *pid, struct task_struct *p);
 #else
 static inline void acct_update_power(struct task_struct *p, cputime_t cputime) {}
 static inline void cpufreq_task_stats_init(struct task_struct *p) {}
 static inline void cpufreq_task_stats_exit(struct task_struct *p) {}
+static inline void cpufreq_task_stats_remove_uids(uid_t uid_start,
+       uid_t uid_end) {}
 #endif
 
 #endif /* _LINUX_CPUFREQ_H */