From: Andres Oportus Date: Mon, 5 Jun 2017 19:46:44 +0000 (-0700) Subject: ANDROID: cpufreq: stats: add uid removal for uid_time_in_state X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=ccd8b1cc8a102ddcf2608f0149ceae662861e4c8;p=GitHub%2FLineageOS%2Fandroid_kernel_samsung_universal7580.git ANDROID: cpufreq: stats: add uid removal for uid_time_in_state Bug: 62295304 Bug: 34133340 Test: Boot and test uid removal by writing to remove_uid_range Signed-off-by: Andres Oportus Change-Id: Ic51fc9480716a8aad88fb55549c2b69021038a11 Conflicts: drivers/cpufreq/cpufreq_stats.c include/linux/cpufreq.h Signed-off-by: Francisco Franco --- diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 68ea9aeac77..bbecdcee412 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -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) { diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c index d677b37e480..412f3200ada 100644 --- a/drivers/misc/uid_sys_stats.c +++ b/drivers/misc/uid_sys_stats.c @@ -26,6 +26,7 @@ #include #include #include +#include #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; } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 574db4e70ae..e4b33a7b165 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -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 */