linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC 0/3] Per-process power consumption measurement facility
@ 2013-07-04 15:17 Konstantin Krivyakin
  2013-07-04 15:17 ` [PATCH RFC 1/3] Add interface to receive current cpu power Konstantin Krivyakin
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Konstantin Krivyakin @ 2013-07-04 15:17 UTC (permalink / raw)
  To: k.krivyakin, i.zhbanov, e.voevodin, kyungmin.park, linux-kernel

This patchset adds per-process power consumption measurement facility.
Power consumption is very important on mobile platforms. This code
allows to measure consumed power in Watts*Hours. The consumed power
for process is updated on scheduler switch and depends on current
CPU voltage and frequency.

The formula for computation is: P = C * V^2 * f, where C is a constant
that reflects capacity of the system, V is the current voltage and
f is the current frequency.
(Taken from: http://en.wikipedia.org/wiki/CPU_power_dissipation).

In this patchset was added implementation for Exynos platform
to demonstrate how it works.

To minimize scheduler impact for each CPU P-state the value of (V^2 *f)
was precomputed at the time of platform initialization.

And to reduce performance impact furthermore, the C constant is multiplied
in userspace.

Konstantin Krivyakin (3):
  Add interface to receive current cpu power
  Add power consumption counter in task_struct.
  Update current cpu power when cpu freq change for exynos.

 drivers/cpufreq/cpufreq.c            |   17 +++++++++++++++++
 drivers/cpufreq/exynos-cpufreq.c     |    2 ++
 drivers/cpufreq/exynos-cpufreq.h     |    1 +
 drivers/cpufreq/exynos4x12-cpufreq.c |   19 ++++++++++++++++++-
 include/linux/cpufreq.h              |    6 ++++++
 include/linux/sched.h                |    2 ++
 include/uapi/linux/taskstats.h       |    2 ++
 kernel/fork.c                        |    1 +
 kernel/sched/core.c                  |    8 ++++++++
 kernel/sched/cputime.c               |   11 +++++++++++
 kernel/tsacct.c                      |    3 +++
 11 files changed, 71 insertions(+), 1 deletion(-)

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH RFC 1/3] Add interface to receive current cpu power
  2013-07-04 15:17 [PATCH RFC 0/3] Per-process power consumption measurement facility Konstantin Krivyakin
@ 2013-07-04 15:17 ` Konstantin Krivyakin
  2013-07-05  0:49   ` Kyungmin Park
  2013-07-04 15:17 ` [PATCH RFC 2/3] Add power consumption counter in task_struct Konstantin Krivyakin
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Konstantin Krivyakin @ 2013-07-04 15:17 UTC (permalink / raw)
  To: k.krivyakin, i.zhbanov, e.voevodin, kyungmin.park, linux-kernel

Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
---
 drivers/cpufreq/cpufreq.c |   17 +++++++++++++++++
 include/linux/cpufreq.h   |    6 ++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 6a015ad..4180e89 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1538,6 +1538,23 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
 }
 EXPORT_SYMBOL(cpufreq_unregister_notifier);
 
+/**
+ * cpu_power_get - get current CPU power
+ * @cpu: CPU number
+ */
+u64 cpu_power_get(int cpu)
+{
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	u64 ret_power = 0;
+
+	if (policy) {
+		ret_power = policy->current_power;
+		cpufreq_cpu_put(policy);
+	}
+
+	return ret_power;
+}
+EXPORT_SYMBOL(cpu_power_get);
 
 /*********************************************************************
  *                              GOVERNORS                            *
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 4d7390b..67323af 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -107,6 +107,7 @@ struct cpufreq_policy {
 	unsigned int		max;    /* in kHz */
 	unsigned int		cur;    /* in kHz, only needed if cpufreq
 					 * governors are used */
+	u64			current_power;
 	unsigned int		policy; /* see above */
 	struct cpufreq_governor	*governor; /* see below */
 	void			*governor_data;
@@ -365,6 +366,7 @@ static inline unsigned int cpufreq_get(unsigned int cpu)
 #ifdef CONFIG_CPU_FREQ
 unsigned int cpufreq_quick_get(unsigned int cpu);
 unsigned int cpufreq_quick_get_max(unsigned int cpu);
+u64 cpu_power_get(int cpu);
 #else
 static inline unsigned int cpufreq_quick_get(unsigned int cpu)
 {
@@ -374,6 +376,10 @@ static inline unsigned int cpufreq_quick_get_max(unsigned int cpu)
 {
 	return 0;
 }
+static inline u64 cpu_power_get(unsigned int cpu)
+{
+	return 0;
+}
 #endif
 
 /*********************************************************************
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 2/3] Add power consumption counter in task_struct.
  2013-07-04 15:17 [PATCH RFC 0/3] Per-process power consumption measurement facility Konstantin Krivyakin
  2013-07-04 15:17 ` [PATCH RFC 1/3] Add interface to receive current cpu power Konstantin Krivyakin
@ 2013-07-04 15:17 ` Konstantin Krivyakin
  2013-07-05  0:50   ` Kyungmin Park
  2013-07-04 15:17 ` [PATCH RFC 3/3] Update current cpu power when cpu freq change for exynos Konstantin Krivyakin
  2013-07-05  0:48 ` [PATCH RFC 0/3] Per-process power consumption measurement facility Kyungmin Park
  3 siblings, 1 reply; 9+ messages in thread
From: Konstantin Krivyakin @ 2013-07-04 15:17 UTC (permalink / raw)
  To: k.krivyakin, i.zhbanov, e.voevodin, kyungmin.park, linux-kernel

Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
---
 include/linux/sched.h          |    2 ++
 include/uapi/linux/taskstats.h |    2 ++
 kernel/fork.c                  |    1 +
 kernel/sched/core.c            |    8 ++++++++
 kernel/sched/cputime.c         |   11 +++++++++++
 kernel/tsacct.c                |    3 +++
 6 files changed, 27 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index cdd5407..f074718 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1157,6 +1157,8 @@ struct task_struct {
 	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
 
 	cputime_t utime, stime, utimescaled, stimescaled;
+	u64 utime_power_cons;
+	u64 stime_power_cons;
 	cputime_t gtime;
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 	struct cputime prev_cputime;
diff --git a/include/uapi/linux/taskstats.h b/include/uapi/linux/taskstats.h
index 2466e55..02ac708 100644
--- a/include/uapi/linux/taskstats.h
+++ b/include/uapi/linux/taskstats.h
@@ -116,6 +116,8 @@ struct taskstats {
 					/* Elapsed time [usec] */
 	__u64	ac_utime;		/* User CPU time [usec] */
 	__u64	ac_stime;		/* SYstem CPU time [usec] */
+	__u64   ac_utime_power_cons;	/* User CPU time power consumption */
+	__u64   ac_stime_power_cons;	/* System CPU time power consumption */
 	__u64	ac_minflt;		/* Minor Page Fault Count */
 	__u64	ac_majflt;		/* Major Page Fault Count */
 	/* Basic Accounting Fields end */
diff --git a/kernel/fork.c b/kernel/fork.c
index 6e6a1c1..a021d5b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1240,6 +1240,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
 	p->utime = p->stime = p->gtime = 0;
 	p->utimescaled = p->stimescaled = 0;
+	p->utime_power_cons = p->stime_power_cons = 0;
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 	p->prev_cputime.utime = p->prev_cputime.stime = 0;
 #endif
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 9b1f2e5..cac73d7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -73,6 +73,7 @@
 #include <linux/init_task.h>
 #include <linux/binfmts.h>
 #include <linux/context_tracking.h>
+#include <linux/cpufreq.h>
 
 #include <asm/switch_to.h>
 #include <asm/tlb.h>
@@ -297,6 +298,13 @@ __read_mostly int scheduler_running;
 int sysctl_sched_rt_runtime = 950000;
 
 
+static u64 cpu_power_cons(cputime_t cputime)
+{
+	struct thread_info *ti = current_thread_info();
+
+	return cpu_power_get(ti->cpu) * cputime;
+}
+
 
 /*
  * __task_rq_lock - lock the rq @p resides on.
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index a7959e0..512727d 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -4,6 +4,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/static_key.h>
 #include <linux/context_tracking.h>
+#include <linux/cpufreq.h>
 #include "sched.h"
 
 
@@ -126,6 +127,13 @@ static inline void task_group_account_field(struct task_struct *p, int index,
 	cpuacct_account_field(p, index, tmp);
 }
 
+static u64 cpu_power_cons(cputime_t cputime)
+{
+	struct thread_info *ti = current_thread_info();
+
+	return cpu_power_get(ti->cpu) * cputime;
+}
+
 /*
  * Account user cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -138,6 +146,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
 	int index;
 
 	/* Add user time to process. */
+	p->utime_power_cons += cpu_power_cons(cputime);
 	p->utime += cputime;
 	p->utimescaled += cputime_scaled;
 	account_group_user_time(p, cputime);
@@ -163,6 +172,7 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
 	u64 *cpustat = kcpustat_this_cpu->cpustat;
 
 	/* Add guest time to process. */
+	p->utime_power_cons += cpu_power_cons(cputime);
 	p->utime += cputime;
 	p->utimescaled += cputime_scaled;
 	account_group_user_time(p, cputime);
@@ -190,6 +200,7 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
 			cputime_t cputime_scaled, int index)
 {
 	/* Add system time to process. */
+	p->stime_power_cons += cpu_power_cons(cputime);
 	p->stime += cputime;
 	p->stimescaled += cputime_scaled;
 	account_group_system_time(p, cputime);
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index a1dd9a1..cea4a9c 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -75,6 +75,9 @@ void bacct_add_tsk(struct user_namespace *user_ns,
 	stats->ac_utimescaled = cputime_to_usecs(utimescaled);
 	stats->ac_stimescaled = cputime_to_usecs(stimescaled);
 
+	stats->ac_utime_power_cons = tsk->utime_power_cons;
+	stats->ac_stime_power_cons = tsk->stime_power_cons;
+
 	stats->ac_minflt = tsk->min_flt;
 	stats->ac_majflt = tsk->maj_flt;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH RFC 3/3] Update current cpu power when cpu freq change for exynos.
  2013-07-04 15:17 [PATCH RFC 0/3] Per-process power consumption measurement facility Konstantin Krivyakin
  2013-07-04 15:17 ` [PATCH RFC 1/3] Add interface to receive current cpu power Konstantin Krivyakin
  2013-07-04 15:17 ` [PATCH RFC 2/3] Add power consumption counter in task_struct Konstantin Krivyakin
@ 2013-07-04 15:17 ` Konstantin Krivyakin
  2013-07-05  0:51   ` Kyungmin Park
  2013-07-05  0:48 ` [PATCH RFC 0/3] Per-process power consumption measurement facility Kyungmin Park
  3 siblings, 1 reply; 9+ messages in thread
From: Konstantin Krivyakin @ 2013-07-04 15:17 UTC (permalink / raw)
  To: k.krivyakin, i.zhbanov, e.voevodin, kyungmin.park, linux-kernel

Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
---
 drivers/cpufreq/exynos-cpufreq.c     |    2 ++
 drivers/cpufreq/exynos-cpufreq.h     |    1 +
 drivers/cpufreq/exynos4x12-cpufreq.c |   19 ++++++++++++++++++-
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index 0d32f02..02f17bc 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -178,6 +178,8 @@ static int exynos_target(struct cpufreq_policy *policy,
 	}
 
 	new_freq = freq_table[index].frequency;
+	if (exynos_info->power_table)
+		policy->current_power = exynos_info->power_table[index];
 
 	ret = exynos_cpufreq_scale(new_freq);
 
diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
index 92b852e..64f964f 100644
--- a/drivers/cpufreq/exynos-cpufreq.h
+++ b/drivers/cpufreq/exynos-cpufreq.h
@@ -38,6 +38,7 @@ struct exynos_dvfs_info {
 	unsigned int	pll_safe_idx;
 	struct clk	*cpu_clk;
 	unsigned int	*volt_table;
+	u64		*power_table;
 	struct cpufreq_frequency_table	*freq_table;
 	void (*set_freq)(unsigned int, unsigned int);
 	bool (*need_apll_change)(unsigned int, unsigned int);
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
index 08b7477..8905f9b 100644
--- a/drivers/cpufreq/exynos4x12-cpufreq.c
+++ b/drivers/cpufreq/exynos4x12-cpufreq.c
@@ -219,6 +219,7 @@ static void exynos4x12_set_frequency(unsigned int old_index,
 int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
 {
 	unsigned long rate;
+	int freq_count;
 
 	cpu_clk = clk_get(NULL, "armclk");
 	if (IS_ERR(cpu_clk))
@@ -252,8 +253,24 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
 	info->set_freq = exynos4x12_set_frequency;
 	info->need_apll_change = exynos4x12_pms_change;
 
-	return 0;
+	freq_count = sizeof(exynos4x12_freq_table) /
+		sizeof(struct cpufreq_frequency_table);
+	info->power_table = kzalloc(sizeof(u64) * freq_count, GFP_KERNEL);
+	if (!info->power_table)
+		goto err_power_table;
+
+	for (i = 0; i <= freq_count; ++i) {
+		u64 freq = info->freq_table[i].frequency;
+		u64 volt = info->volt_table[i];
 
+		do_div(freq, 1000);
+		do_div(volt, 1000);
+		info->power_table[i] = freq * volt * volt;
+	}
+
+	return 0;
+err_power_table:
+	clk_put(mout_appl);
 err_mout_apll:
 	clk_put(mout_mpll);
 err_mout_mpll:
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH RFC 0/3] Per-process power consumption measurement facility
  2013-07-04 15:17 [PATCH RFC 0/3] Per-process power consumption measurement facility Konstantin Krivyakin
                   ` (2 preceding siblings ...)
  2013-07-04 15:17 ` [PATCH RFC 3/3] Update current cpu power when cpu freq change for exynos Konstantin Krivyakin
@ 2013-07-05  0:48 ` Kyungmin Park
  3 siblings, 0 replies; 9+ messages in thread
From: Kyungmin Park @ 2013-07-05  0:48 UTC (permalink / raw)
  To: Konstantin Krivyakin, Rafael J. Wysocki, viresh.kumar, mingo,
	Peter Zijlstra
  Cc: i.zhbanov, e.voevodin, linux-kernel

Hi Krivyakin,

Please use "./scripts/get_maintainer.pl" and send proper maintainers.

I added them.

Thank you,
Kyungmin Park

On Fri, Jul 5, 2013 at 12:17 AM, Konstantin Krivyakin
<k.krivyakin@samsung.com> wrote:
> This patchset adds per-process power consumption measurement facility.
> Power consumption is very important on mobile platforms. This code
> allows to measure consumed power in Watts*Hours. The consumed power
> for process is updated on scheduler switch and depends on current
> CPU voltage and frequency.
>
> The formula for computation is: P = C * V^2 * f, where C is a constant
> that reflects capacity of the system, V is the current voltage and
> f is the current frequency.
> (Taken from: http://en.wikipedia.org/wiki/CPU_power_dissipation).
>
> In this patchset was added implementation for Exynos platform
> to demonstrate how it works.
>
> To minimize scheduler impact for each CPU P-state the value of (V^2 *f)
> was precomputed at the time of platform initialization.
>
> And to reduce performance impact furthermore, the C constant is multiplied
> in userspace.
>
> Konstantin Krivyakin (3):
>   Add interface to receive current cpu power
>   Add power consumption counter in task_struct.
>   Update current cpu power when cpu freq change for exynos.
>
>  drivers/cpufreq/cpufreq.c            |   17 +++++++++++++++++
>  drivers/cpufreq/exynos-cpufreq.c     |    2 ++
>  drivers/cpufreq/exynos-cpufreq.h     |    1 +
>  drivers/cpufreq/exynos4x12-cpufreq.c |   19 ++++++++++++++++++-
>  include/linux/cpufreq.h              |    6 ++++++
>  include/linux/sched.h                |    2 ++
>  include/uapi/linux/taskstats.h       |    2 ++
>  kernel/fork.c                        |    1 +
>  kernel/sched/core.c                  |    8 ++++++++
>  kernel/sched/cputime.c               |   11 +++++++++++
>  kernel/tsacct.c                      |    3 +++
>  11 files changed, 71 insertions(+), 1 deletion(-)
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RFC 1/3] Add interface to receive current cpu power
  2013-07-04 15:17 ` [PATCH RFC 1/3] Add interface to receive current cpu power Konstantin Krivyakin
@ 2013-07-05  0:49   ` Kyungmin Park
  0 siblings, 0 replies; 9+ messages in thread
From: Kyungmin Park @ 2013-07-05  0:49 UTC (permalink / raw)
  To: Konstantin Krivyakin, Rafael J. Wysocki, viresh.kumar, mingo,
	Peter Zijlstra
  Cc: i.zhbanov, e.voevodin, linux-kernel

+ cpufreq maintainers

On Fri, Jul 5, 2013 at 12:17 AM, Konstantin Krivyakin
<k.krivyakin@samsung.com> wrote:
> Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
> ---
>  drivers/cpufreq/cpufreq.c |   17 +++++++++++++++++
>  include/linux/cpufreq.h   |    6 ++++++
>  2 files changed, 23 insertions(+)
>
> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
> index 6a015ad..4180e89 100644
> --- a/drivers/cpufreq/cpufreq.c
> +++ b/drivers/cpufreq/cpufreq.c
> @@ -1538,6 +1538,23 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
>  }
>  EXPORT_SYMBOL(cpufreq_unregister_notifier);
>
> +/**
> + * cpu_power_get - get current CPU power
> + * @cpu: CPU number
> + */
> +u64 cpu_power_get(int cpu)
> +{
> +       struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
> +       u64 ret_power = 0;
> +
> +       if (policy) {
> +               ret_power = policy->current_power;
> +               cpufreq_cpu_put(policy);
> +       }
> +
> +       return ret_power;
> +}
> +EXPORT_SYMBOL(cpu_power_get);
>
>  /*********************************************************************
>   *                              GOVERNORS                            *
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 4d7390b..67323af 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -107,6 +107,7 @@ struct cpufreq_policy {
>         unsigned int            max;    /* in kHz */
>         unsigned int            cur;    /* in kHz, only needed if cpufreq
>                                          * governors are used */
> +       u64                     current_power;
>         unsigned int            policy; /* see above */
>         struct cpufreq_governor *governor; /* see below */
>         void                    *governor_data;
> @@ -365,6 +366,7 @@ static inline unsigned int cpufreq_get(unsigned int cpu)
>  #ifdef CONFIG_CPU_FREQ
>  unsigned int cpufreq_quick_get(unsigned int cpu);
>  unsigned int cpufreq_quick_get_max(unsigned int cpu);
> +u64 cpu_power_get(int cpu);
>  #else
>  static inline unsigned int cpufreq_quick_get(unsigned int cpu)
>  {
> @@ -374,6 +376,10 @@ static inline unsigned int cpufreq_quick_get_max(unsigned int cpu)
>  {
>         return 0;
>  }
> +static inline u64 cpu_power_get(unsigned int cpu)
> +{
> +       return 0;
> +}
>  #endif
>
>  /*********************************************************************
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RFC 2/3] Add power consumption counter in task_struct.
  2013-07-04 15:17 ` [PATCH RFC 2/3] Add power consumption counter in task_struct Konstantin Krivyakin
@ 2013-07-05  0:50   ` Kyungmin Park
  0 siblings, 0 replies; 9+ messages in thread
From: Kyungmin Park @ 2013-07-05  0:50 UTC (permalink / raw)
  To: Konstantin Krivyakin, Rafael J. Wysocki, viresh.kumar, mingo,
	Peter Zijlstra
  Cc: i.zhbanov, e.voevodin, linux-kernel

+ scheduler maintainers

On Fri, Jul 5, 2013 at 12:17 AM, Konstantin Krivyakin
<k.krivyakin@samsung.com> wrote:
> Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
> ---
>  include/linux/sched.h          |    2 ++
>  include/uapi/linux/taskstats.h |    2 ++
>  kernel/fork.c                  |    1 +
>  kernel/sched/core.c            |    8 ++++++++
>  kernel/sched/cputime.c         |   11 +++++++++++
>  kernel/tsacct.c                |    3 +++
>  6 files changed, 27 insertions(+)
>
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index cdd5407..f074718 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1157,6 +1157,8 @@ struct task_struct {
>         int __user *clear_child_tid;            /* CLONE_CHILD_CLEARTID */
>
>         cputime_t utime, stime, utimescaled, stimescaled;
> +       u64 utime_power_cons;
> +       u64 stime_power_cons;
>         cputime_t gtime;
>  #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
>         struct cputime prev_cputime;
> diff --git a/include/uapi/linux/taskstats.h b/include/uapi/linux/taskstats.h
> index 2466e55..02ac708 100644
> --- a/include/uapi/linux/taskstats.h
> +++ b/include/uapi/linux/taskstats.h
> @@ -116,6 +116,8 @@ struct taskstats {
>                                         /* Elapsed time [usec] */
>         __u64   ac_utime;               /* User CPU time [usec] */
>         __u64   ac_stime;               /* SYstem CPU time [usec] */
> +       __u64   ac_utime_power_cons;    /* User CPU time power consumption */
> +       __u64   ac_stime_power_cons;    /* System CPU time power consumption */
>         __u64   ac_minflt;              /* Minor Page Fault Count */
>         __u64   ac_majflt;              /* Major Page Fault Count */
>         /* Basic Accounting Fields end */
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 6e6a1c1..a021d5b 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1240,6 +1240,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
>
>         p->utime = p->stime = p->gtime = 0;
>         p->utimescaled = p->stimescaled = 0;
> +       p->utime_power_cons = p->stime_power_cons = 0;
>  #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
>         p->prev_cputime.utime = p->prev_cputime.stime = 0;
>  #endif
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 9b1f2e5..cac73d7 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -73,6 +73,7 @@
>  #include <linux/init_task.h>
>  #include <linux/binfmts.h>
>  #include <linux/context_tracking.h>
> +#include <linux/cpufreq.h>
>
>  #include <asm/switch_to.h>
>  #include <asm/tlb.h>
> @@ -297,6 +298,13 @@ __read_mostly int scheduler_running;
>  int sysctl_sched_rt_runtime = 950000;
>
>
> +static u64 cpu_power_cons(cputime_t cputime)
> +{
> +       struct thread_info *ti = current_thread_info();
> +
> +       return cpu_power_get(ti->cpu) * cputime;
> +}
> +
>
>  /*
>   * __task_rq_lock - lock the rq @p resides on.
> diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
> index a7959e0..512727d 100644
> --- a/kernel/sched/cputime.c
> +++ b/kernel/sched/cputime.c
> @@ -4,6 +4,7 @@
>  #include <linux/kernel_stat.h>
>  #include <linux/static_key.h>
>  #include <linux/context_tracking.h>
> +#include <linux/cpufreq.h>
>  #include "sched.h"
>
>
> @@ -126,6 +127,13 @@ static inline void task_group_account_field(struct task_struct *p, int index,
>         cpuacct_account_field(p, index, tmp);
>  }
>
> +static u64 cpu_power_cons(cputime_t cputime)
> +{
> +       struct thread_info *ti = current_thread_info();
> +
> +       return cpu_power_get(ti->cpu) * cputime;
> +}
> +
>  /*
>   * Account user cpu time to a process.
>   * @p: the process that the cpu time gets accounted to
> @@ -138,6 +146,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
>         int index;
>
>         /* Add user time to process. */
> +       p->utime_power_cons += cpu_power_cons(cputime);
>         p->utime += cputime;
>         p->utimescaled += cputime_scaled;
>         account_group_user_time(p, cputime);
> @@ -163,6 +172,7 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
>         u64 *cpustat = kcpustat_this_cpu->cpustat;
>
>         /* Add guest time to process. */
> +       p->utime_power_cons += cpu_power_cons(cputime);
>         p->utime += cputime;
>         p->utimescaled += cputime_scaled;
>         account_group_user_time(p, cputime);
> @@ -190,6 +200,7 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
>                         cputime_t cputime_scaled, int index)
>  {
>         /* Add system time to process. */
> +       p->stime_power_cons += cpu_power_cons(cputime);
>         p->stime += cputime;
>         p->stimescaled += cputime_scaled;
>         account_group_system_time(p, cputime);
> diff --git a/kernel/tsacct.c b/kernel/tsacct.c
> index a1dd9a1..cea4a9c 100644
> --- a/kernel/tsacct.c
> +++ b/kernel/tsacct.c
> @@ -75,6 +75,9 @@ void bacct_add_tsk(struct user_namespace *user_ns,
>         stats->ac_utimescaled = cputime_to_usecs(utimescaled);
>         stats->ac_stimescaled = cputime_to_usecs(stimescaled);
>
> +       stats->ac_utime_power_cons = tsk->utime_power_cons;
> +       stats->ac_stime_power_cons = tsk->stime_power_cons;
> +
>         stats->ac_minflt = tsk->min_flt;
>         stats->ac_majflt = tsk->maj_flt;
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RFC 3/3] Update current cpu power when cpu freq change for exynos.
  2013-07-04 15:17 ` [PATCH RFC 3/3] Update current cpu power when cpu freq change for exynos Konstantin Krivyakin
@ 2013-07-05  0:51   ` Kyungmin Park
  0 siblings, 0 replies; 9+ messages in thread
From: Kyungmin Park @ 2013-07-05  0:51 UTC (permalink / raw)
  To: Konstantin Krivyakin, Rafael J. Wysocki, viresh.kumar, mingo,
	Peter Zijlstra
  Cc: i.zhbanov, e.voevodin, linux-kernel

+ cpufreq maintainers

On Fri, Jul 5, 2013 at 12:17 AM, Konstantin Krivyakin
<k.krivyakin@samsung.com> wrote:
> Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
> ---
>  drivers/cpufreq/exynos-cpufreq.c     |    2 ++
>  drivers/cpufreq/exynos-cpufreq.h     |    1 +
>  drivers/cpufreq/exynos4x12-cpufreq.c |   19 ++++++++++++++++++-
>  3 files changed, 21 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
> index 0d32f02..02f17bc 100644
> --- a/drivers/cpufreq/exynos-cpufreq.c
> +++ b/drivers/cpufreq/exynos-cpufreq.c
> @@ -178,6 +178,8 @@ static int exynos_target(struct cpufreq_policy *policy,
>         }
>
>         new_freq = freq_table[index].frequency;
> +       if (exynos_info->power_table)
> +               policy->current_power = exynos_info->power_table[index];
>
>         ret = exynos_cpufreq_scale(new_freq);
>
> diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
> index 92b852e..64f964f 100644
> --- a/drivers/cpufreq/exynos-cpufreq.h
> +++ b/drivers/cpufreq/exynos-cpufreq.h
> @@ -38,6 +38,7 @@ struct exynos_dvfs_info {
>         unsigned int    pll_safe_idx;
>         struct clk      *cpu_clk;
>         unsigned int    *volt_table;
> +       u64             *power_table;
>         struct cpufreq_frequency_table  *freq_table;
>         void (*set_freq)(unsigned int, unsigned int);
>         bool (*need_apll_change)(unsigned int, unsigned int);
> diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
> index 08b7477..8905f9b 100644
> --- a/drivers/cpufreq/exynos4x12-cpufreq.c
> +++ b/drivers/cpufreq/exynos4x12-cpufreq.c
> @@ -219,6 +219,7 @@ static void exynos4x12_set_frequency(unsigned int old_index,
>  int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
>  {
>         unsigned long rate;
> +       int freq_count;
>
>         cpu_clk = clk_get(NULL, "armclk");
>         if (IS_ERR(cpu_clk))
> @@ -252,8 +253,24 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
>         info->set_freq = exynos4x12_set_frequency;
>         info->need_apll_change = exynos4x12_pms_change;
>
> -       return 0;
> +       freq_count = sizeof(exynos4x12_freq_table) /
> +               sizeof(struct cpufreq_frequency_table);
> +       info->power_table = kzalloc(sizeof(u64) * freq_count, GFP_KERNEL);
> +       if (!info->power_table)
> +               goto err_power_table;
> +
> +       for (i = 0; i <= freq_count; ++i) {
> +               u64 freq = info->freq_table[i].frequency;
> +               u64 volt = info->volt_table[i];
>
> +               do_div(freq, 1000);
> +               do_div(volt, 1000);
> +               info->power_table[i] = freq * volt * volt;
> +       }
> +
> +       return 0;
> +err_power_table:
> +       clk_put(mout_appl);
>  err_mout_apll:
>         clk_put(mout_mpll);
>  err_mout_mpll:
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH RFC 2/3] Add power consumption counter in task_struct.
  2013-07-30  8:17 Konstantin Krivyakin
@ 2013-07-30  8:17 ` Konstantin Krivyakin
  0 siblings, 0 replies; 9+ messages in thread
From: Konstantin Krivyakin @ 2013-07-30  8:17 UTC (permalink / raw)
  To: linux-kernel, rjw, viresh.kumar, mingo, peterz, kgene.kim, linux-pm
  Cc: k.krivyakin, i.zhbanov, e.voevodin, kyungmin.park, akpm

Signed-off-by: Konstantin Krivyakin <k.krivyakin@samsung.com>
---
 include/linux/sched.h          |    2 ++
 include/uapi/linux/taskstats.h |    2 ++
 kernel/fork.c                  |    1 +
 kernel/sched/core.c            |    8 ++++++++
 kernel/sched/cputime.c         |   11 +++++++++++
 kernel/tsacct.c                |    3 +++
 6 files changed, 27 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index cdd5407..f074718 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1157,6 +1157,8 @@ struct task_struct {
 	int __user *clear_child_tid;		/* CLONE_CHILD_CLEARTID */
 
 	cputime_t utime, stime, utimescaled, stimescaled;
+	u64 utime_power_cons;
+	u64 stime_power_cons;
 	cputime_t gtime;
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 	struct cputime prev_cputime;
diff --git a/include/uapi/linux/taskstats.h b/include/uapi/linux/taskstats.h
index 2466e55..02ac708 100644
--- a/include/uapi/linux/taskstats.h
+++ b/include/uapi/linux/taskstats.h
@@ -116,6 +116,8 @@ struct taskstats {
 					/* Elapsed time [usec] */
 	__u64	ac_utime;		/* User CPU time [usec] */
 	__u64	ac_stime;		/* SYstem CPU time [usec] */
+	__u64   ac_utime_power_cons;	/* User CPU time power consumption */
+	__u64   ac_stime_power_cons;	/* System CPU time power consumption */
 	__u64	ac_minflt;		/* Minor Page Fault Count */
 	__u64	ac_majflt;		/* Major Page Fault Count */
 	/* Basic Accounting Fields end */
diff --git a/kernel/fork.c b/kernel/fork.c
index 6e6a1c1..a021d5b 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1240,6 +1240,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 
 	p->utime = p->stime = p->gtime = 0;
 	p->utimescaled = p->stimescaled = 0;
+	p->utime_power_cons = p->stime_power_cons = 0;
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 	p->prev_cputime.utime = p->prev_cputime.stime = 0;
 #endif
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 9b1f2e5..cac73d7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -73,6 +73,7 @@
 #include <linux/init_task.h>
 #include <linux/binfmts.h>
 #include <linux/context_tracking.h>
+#include <linux/cpufreq.h>
 
 #include <asm/switch_to.h>
 #include <asm/tlb.h>
@@ -297,6 +298,13 @@ __read_mostly int scheduler_running;
 int sysctl_sched_rt_runtime = 950000;
 
 
+static u64 cpu_power_cons(cputime_t cputime)
+{
+	struct thread_info *ti = current_thread_info();
+
+	return cpu_power_get(ti->cpu) * cputime;
+}
+
 
 /*
  * __task_rq_lock - lock the rq @p resides on.
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index a7959e0..512727d 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -4,6 +4,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/static_key.h>
 #include <linux/context_tracking.h>
+#include <linux/cpufreq.h>
 #include "sched.h"
 
 
@@ -126,6 +127,13 @@ static inline void task_group_account_field(struct task_struct *p, int index,
 	cpuacct_account_field(p, index, tmp);
 }
 
+static u64 cpu_power_cons(cputime_t cputime)
+{
+	struct thread_info *ti = current_thread_info();
+
+	return cpu_power_get(ti->cpu) * cputime;
+}
+
 /*
  * Account user cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -138,6 +146,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
 	int index;
 
 	/* Add user time to process. */
+	p->utime_power_cons += cpu_power_cons(cputime);
 	p->utime += cputime;
 	p->utimescaled += cputime_scaled;
 	account_group_user_time(p, cputime);
@@ -163,6 +172,7 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime,
 	u64 *cpustat = kcpustat_this_cpu->cpustat;
 
 	/* Add guest time to process. */
+	p->utime_power_cons += cpu_power_cons(cputime);
 	p->utime += cputime;
 	p->utimescaled += cputime_scaled;
 	account_group_user_time(p, cputime);
@@ -190,6 +200,7 @@ void __account_system_time(struct task_struct *p, cputime_t cputime,
 			cputime_t cputime_scaled, int index)
 {
 	/* Add system time to process. */
+	p->stime_power_cons += cpu_power_cons(cputime);
 	p->stime += cputime;
 	p->stimescaled += cputime_scaled;
 	account_group_system_time(p, cputime);
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index a1dd9a1..cea4a9c 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -75,6 +75,9 @@ void bacct_add_tsk(struct user_namespace *user_ns,
 	stats->ac_utimescaled = cputime_to_usecs(utimescaled);
 	stats->ac_stimescaled = cputime_to_usecs(stimescaled);
 
+	stats->ac_utime_power_cons = tsk->utime_power_cons;
+	stats->ac_stime_power_cons = tsk->stime_power_cons;
+
 	stats->ac_minflt = tsk->min_flt;
 	stats->ac_majflt = tsk->maj_flt;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-07-30  8:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-04 15:17 [PATCH RFC 0/3] Per-process power consumption measurement facility Konstantin Krivyakin
2013-07-04 15:17 ` [PATCH RFC 1/3] Add interface to receive current cpu power Konstantin Krivyakin
2013-07-05  0:49   ` Kyungmin Park
2013-07-04 15:17 ` [PATCH RFC 2/3] Add power consumption counter in task_struct Konstantin Krivyakin
2013-07-05  0:50   ` Kyungmin Park
2013-07-04 15:17 ` [PATCH RFC 3/3] Update current cpu power when cpu freq change for exynos Konstantin Krivyakin
2013-07-05  0:51   ` Kyungmin Park
2013-07-05  0:48 ` [PATCH RFC 0/3] Per-process power consumption measurement facility Kyungmin Park
2013-07-30  8:17 Konstantin Krivyakin
2013-07-30  8:17 ` [PATCH RFC 2/3] Add power consumption counter in task_struct Konstantin Krivyakin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).