aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuchi Kandoi <kandoiruchi@google.com>2015-04-17 16:33:29 -0700
committerRuchi Kandoi <kandoiruchi@google.com>2015-06-02 11:14:50 -0700
commite91d3fbfa83b2ab32ffef6fdfd9a244c20e27ffa (patch)
treeb142868583b61d1ccf61a398ca33220435d44ac5
parent0866f4e30c337714f86bff4638e418ad8c60b11c (diff)
sched: cpufreq: Adds a field cpu_power in the task_struct
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>
-rw-r--r--drivers/cpufreq/cpufreq_stats.c19
-rw-r--r--include/linux/cpufreq.h8
-rw-r--r--include/linux/sched.h1
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/sched/cputime.c7
5 files changed, 36 insertions, 0 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 7f8e5a1b930c..3811168bf28d 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/sort.h>
#include <linux/of.h>
+#include <linux/sched.h>
#include <asm/cputime.h>
static spinlock_t cpufreq_stats_lock;
@@ -125,6 +126,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)
{
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index b0d360c87602..a15944d5a06f 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -17,6 +17,8 @@
#include <linux/kobject.h>
#include <linux/notifier.h>
#include <linux/sysfs.h>
+#include <asm/cputime.h>
+
/*********************************************************************
* CPUFREQ INTERFACE *
@@ -509,4 +511,10 @@ static inline int cpufreq_generic_exit(struct cpufreq_policy *policy)
return 0;
}
+/*********************************************************************
+ * CPUFREQ STATS *
+ *********************************************************************/
+
+void acct_update_power(struct task_struct *p, cputime_t cputime);
+
#endif /* _LINUX_CPUFREQ_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 37658d063909..6aef9c64c73d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1290,6 +1290,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
diff --git a/kernel/fork.c b/kernel/fork.c
index 02f89e3d75cd..42f05920e642 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1296,6 +1296,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
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 99947919e30b..582806c52752 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -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);
}
/*