sched: cpufreq: Adds a field cpu_power in the task_struct
authorRuchi Kandoi <kandoiruchi@google.com>
Fri, 17 Apr 2015 23:33:29 +0000 (16:33 -0700)
committerRuchi Kandoi <kandoiruchi@google.com>
Mon, 1 Jun 2015 17:14:48 +0000 (17:14 +0000)
cpu_power has been added to keep track of amount of power each task is
consuming. cpu_power is updated whenever stime and utime are updated for
a task. power is computed by taking into account the frequency at which
the current core was running and the current for cpu actively
running at hat frequency.

Change-Id: Ic535941e7b339aab5cae9081a34049daeb44b248
Signed-off-by: Ruchi Kandoi <kandoiruchi@google.com>
drivers/cpufreq/cpufreq_stats.c
include/linux/cpufreq.h
include/linux/sched.h
kernel/fork.c
kernel/sched/cputime.c

index 89889bff56151c9a80b1a30c7caa3e4f5a801b25..c441758e01a6c92b02e7ab96c633c07d70eb1e43 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/sort.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <linux/sched.h>
 #include <asm/cputime.h>
 
 static spinlock_t cpufreq_stats_lock;
@@ -133,6 +134,24 @@ static int get_index_all_cpufreq_stat(struct all_cpufreq_stats *all_stat,
        return -1;
 }
 
+void acct_update_power(struct task_struct *task, cputime_t cputime) {
+       struct cpufreq_power_stats *powerstats;
+       struct cpufreq_stats *stats;
+       unsigned int cpu_num, curr;
+
+       if (!task)
+               return;
+       cpu_num = task_cpu(task);
+       powerstats = per_cpu(cpufreq_power_stats, cpu_num);
+       stats = per_cpu(cpufreq_stats_table, cpu_num);
+       if (!powerstats || !stats)
+               return;
+
+       curr = powerstats->curr[stats->last_index];
+       task->cpu_power += curr * cputime_to_usecs(cputime);
+}
+EXPORT_SYMBOL_GPL(acct_update_power);
+
 static ssize_t show_current_in_state(struct kobject *kobj,
                struct kobj_attribute *attr, char *buf)
 {
index 400509e3a2c03b5919bff2541623064345763f90..063c234597c7da81d74cb3f02790c355feb9baf3 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/workqueue.h>
 #include <linux/cpumask.h>
 #include <asm/div64.h>
+#include <asm/cputime.h>
 
 #define CPUFREQ_NAME_LEN 16
 /* Print length for names. Extra 1 space for accomodating '\n' in prints */
@@ -436,4 +437,11 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
 void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy);
 
 void cpufreq_frequency_table_put_attr(unsigned int cpu);
+
+/*********************************************************************
+ *                         CPUFREQ STATS                             *
+ *********************************************************************/
+
+void acct_update_power(struct task_struct *p, cputime_t cputime);
+
 #endif /* _LINUX_CPUFREQ_H */
index da5fe76a069b19b64e201a1a8b44f7418f0847b6..0ae16dd330a2e185787bd9315dcb212ca53cd480 100644 (file)
@@ -1164,6 +1164,7 @@ struct task_struct {
 
        cputime_t utime, stime, utimescaled, stimescaled;
        cputime_t gtime;
+       unsigned long long cpu_power;
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
        struct cputime prev_cputime;
 #endif
index 0ff07d94e07cee2db2130c590ee827b8dedb3309..52bde0c3ed98589701a87c825aa1b43549da9405 100644 (file)
@@ -1297,6 +1297,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
        p->utime = p->stime = p->gtime = 0;
        p->utimescaled = p->stimescaled = 0;
+       p->cpu_power = 0;
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
        p->prev_cputime.utime = p->prev_cputime.stime = 0;
 #endif
index b5ccba22603b51a92c2aa1f0ef647a878dd4e2c3..cc211d01f77f7388e9afaf136601a0d9c7a14297 100644 (file)
@@ -1,3 +1,4 @@
+#include <linux/cpufreq.h>
 #include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/tsacct_kern.h>
@@ -149,6 +150,9 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
 
        /* Account for user time used */
        acct_account_cputime(p);
+
+       /* Account power usage for user time */
+       acct_update_power(p, cputime);
 }
 
 /*
@@ -199,6 +203,9 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
 
        /* Account for system time used */
        acct_account_cputime(p);
+
+       /* Account power usage for system time */
+       acct_update_power(p, cputime);
 }
 
 /*