2013-03-27 22:37:30

by Jacob Shin

[permalink] [raw]
Subject: [PATCH 0/2] cpufreq: ondemand: add AMD specific powersave bias

This patchset adds AMD specific powersave bias function to the ondemand
governor; which can be used to help ondemand governor make more power conscious
frequency change decisions based on feedback from hardware (availble on AMD
Family 16h and above).

Hardware feedback tells software how "sensitive" to frequency changes the
workloads are. CPU-bound workloads will be more sensitive -- they will
perform better as frequency increases. Memory/IO-bound workloads will be less
sensitive -- they will not necessarily perform better as frequnecy increases.

This patchset was compared against ondemand governor without powersave bias
and did not show any performance degradation on CPU-bound workloads such as
kernbench and unixbench. While saving power on Memory-bound workloads such as
stream.

This applies to linux-pm's linux-next branch, on top of Viresh's 'Implement
per policy instance of governor' V4 patchset:

https://lkml.org/lkml/2013/3/27/348

Jacob Shin (2):
cpufreq: ondemand: allow custom od_ops to be registered
cpufreq: AMD "frequency sensitivity feedback" powersave bias for
ondemand governor

arch/x86/include/uapi/asm/msr-index.h | 1 +
drivers/cpufreq/Kconfig.x86 | 10 ++++++++++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/cpufreq_governor.h | 2 ++
drivers/cpufreq/cpufreq_ondemand.c | 32 +++++++++++++++++++++++++++-----
5 files changed, 41 insertions(+), 5 deletions(-)

--
1.7.9.5


2013-03-27 22:37:33

by Jacob Shin

[permalink] [raw]
Subject: [PATCH 1/2] cpufreq: ondemand: allow custom od_ops to be registered

This allows for another [arch specific] driver to hook into existing
powersave bias function of the ondemand governor. i.e. This allows AMD
specific powersave bias function (in a separate AMD specific driver)
to aid ondemand governor's frequency transition deicisions.

Signed-off-by: Jacob Shin <[email protected]>
---
drivers/cpufreq/cpufreq_governor.h | 2 ++
drivers/cpufreq/cpufreq_ondemand.c | 32 +++++++++++++++++++++++++++-----
2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
index c83cabf..d1f7b23 100644
--- a/drivers/cpufreq/cpufreq_governor.h
+++ b/drivers/cpufreq/cpufreq_governor.h
@@ -262,4 +262,6 @@ bool need_load_eval(struct cpu_dbs_common_info *cdbs,
unsigned int sampling_rate);
int cpufreq_governor_dbs(struct cpufreq_policy *policy,
struct common_dbs_data *cdata, unsigned int event);
+void od_register_ops(struct od_ops *ops);
+void od_unregister_ops(struct od_ops *ops);
#endif /* _CPUFREQ_GOVERNER_H */
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 15e80ee..0a101eb 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -40,6 +40,8 @@

static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info);

+static struct od_ops od_ops;
+
#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
static struct cpufreq_governor cpufreq_gov_ondemand;
#endif
@@ -135,7 +137,7 @@ static void ondemand_powersave_bias_init(void)
{
int i;
for_each_online_cpu(i) {
- ondemand_powersave_bias_init_cpu(i);
+ od_ops.powersave_bias_init_cpu(i);
}
}

@@ -145,7 +147,8 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq)
struct od_dbs_tuners *od_tuners = dbs_data->tuners;

if (od_tuners->powersave_bias)
- freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H);
+ freq = od_ops.powersave_bias_target(p, freq,
+ CPUFREQ_RELATION_H);
else if (p->cur == p->max)
return;

@@ -177,7 +180,7 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
if (policy->cur < policy->max)
dbs_info->rate_mult =
od_tuners->sampling_down_factor;
- dbs_freq_increase(policy, policy->max);
+ od_ops.freq_increase(policy, policy->max);
return;
}

@@ -206,8 +209,8 @@ static void od_check_cpu(int cpu, unsigned int load_freq)
__cpufreq_driver_target(policy, freq_next,
CPUFREQ_RELATION_L);
} else {
- int freq = powersave_bias_target(policy, freq_next,
- CPUFREQ_RELATION_L);
+ int freq = od_ops.powersave_bias_target(policy,
+ freq_next, CPUFREQ_RELATION_L);
__cpufreq_driver_target(policy, freq,
CPUFREQ_RELATION_L);
}
@@ -565,6 +568,25 @@ static struct common_dbs_data od_dbs_cdata = {
.exit = od_exit,
};

+void od_register_ops(struct od_ops *ops)
+{
+ if (ops->powersave_bias_init_cpu)
+ od_ops.powersave_bias_init_cpu = ops->powersave_bias_init_cpu;
+ if (ops->powersave_bias_target)
+ od_ops.powersave_bias_target = ops->powersave_bias_target;
+ if (ops->freq_increase)
+ od_ops.freq_increase = ops->freq_increase;
+}
+EXPORT_SYMBOL_GPL(od_register_ops);
+
+void od_unregister_ops(struct od_ops *ops)
+{
+ od_ops.powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu;
+ od_ops.powersave_bias_target = powersave_bias_target;
+ od_ops.freq_increase = dbs_freq_increase;
+}
+EXPORT_SYMBOL_GPL(od_unregister_ops);
+
static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy,
unsigned int event)
{
--
1.7.9.5

2013-03-27 22:37:32

by Jacob Shin

[permalink] [raw]
Subject: [PATCH 2/2] cpufreq: AMD "frequency sensitivity feedback" powersave bias for ondemand governor

Future AMD processors, starting with Family 16h, can provide software
with feedback on how the workload may respond to frequency change --
memory-bound workloads will not benefit from higher frequency, where
as compute-bound workloads will. This patch enables this "frequency
sensitivity feedback" to aid the ondemand governor to make better
frequency change decisions by hooking into the powersave bias.

Signed-off-by: Jacob Shin <[email protected]>
---
arch/x86/include/uapi/asm/msr-index.h | 1 +
drivers/cpufreq/Kconfig.x86 | 10 ++++++++++
drivers/cpufreq/Makefile | 1 +
3 files changed, 12 insertions(+)

diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h
index 7a060f4..b2e6c49 100644
--- a/arch/x86/include/uapi/asm/msr-index.h
+++ b/arch/x86/include/uapi/asm/msr-index.h
@@ -173,6 +173,7 @@
#define MSR_AMD64_TSC_RATIO 0xc0000104
#define MSR_AMD64_NB_CFG 0xc001001f
#define MSR_AMD64_PATCH_LOADER 0xc0010020
+#define MSR_AMD64_FREQ_SENSITIVITY 0xc0010080
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
#define MSR_AMD64_OSVW_STATUS 0xc0010141
#define MSR_AMD64_DC_CFG 0xc0011022
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index d7dc0ed..6c714b0 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -129,6 +129,16 @@ config X86_POWERNOW_K8

For details, take a look at <file:Documentation/cpu-freq/>.

+config X86_AMD_FREQ_SENSITIVITY
+ tristate "AMD 'frequency sensitivity feedback' powersave bias"
+ depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ
+ help
+ This adds support for 'frequency sensitivity feedback' feature on
+ supported AMD processors, which hooks into the ondemand governor's
+ powersave bias to influence frequency change decisions.
+
+ If in doubt, say N.
+
config X86_GX_SUSPMOD
tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
depends on X86_32 && PCI
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 863fd18..01dfdaf 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o
+obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o

##################################################################################
# ARM SoC drivers
--
1.7.9.5

2013-03-27 22:41:37

by Jacob Shin

[permalink] [raw]
Subject: Re: [PATCH 2/2] cpufreq: AMD "frequency sensitivity feedback" powersave bias for ondemand governor

On Wed, Mar 27, 2013 at 05:37:21PM -0500, Jacob Shin wrote:
> Future AMD processors, starting with Family 16h, can provide software
> with feedback on how the workload may respond to frequency change --
> memory-bound workloads will not benefit from higher frequency, where
> as compute-bound workloads will. This patch enables this "frequency
> sensitivity feedback" to aid the ondemand governor to make better
> frequency change decisions by hooking into the powersave bias.
>
> Signed-off-by: Jacob Shin <[email protected]>
> ---
> arch/x86/include/uapi/asm/msr-index.h | 1 +
> drivers/cpufreq/Kconfig.x86 | 10 ++++++++++
> drivers/cpufreq/Makefile | 1 +
> 3 files changed, 12 insertions(+)
>
> diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h
> index 7a060f4..b2e6c49 100644
> --- a/arch/x86/include/uapi/asm/msr-index.h
> +++ b/arch/x86/include/uapi/asm/msr-index.h
> @@ -173,6 +173,7 @@
> #define MSR_AMD64_TSC_RATIO 0xc0000104
> #define MSR_AMD64_NB_CFG 0xc001001f
> #define MSR_AMD64_PATCH_LOADER 0xc0010020
> +#define MSR_AMD64_FREQ_SENSITIVITY 0xc0010080
> #define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
> #define MSR_AMD64_OSVW_STATUS 0xc0010141
> #define MSR_AMD64_DC_CFG 0xc0011022
> diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
> index d7dc0ed..6c714b0 100644
> --- a/drivers/cpufreq/Kconfig.x86
> +++ b/drivers/cpufreq/Kconfig.x86
> @@ -129,6 +129,16 @@ config X86_POWERNOW_K8
>
> For details, take a look at <file:Documentation/cpu-freq/>.
>
> +config X86_AMD_FREQ_SENSITIVITY
> + tristate "AMD 'frequency sensitivity feedback' powersave bias"
> + depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ
> + help
> + This adds support for 'frequency sensitivity feedback' feature on
> + supported AMD processors, which hooks into the ondemand governor's
> + powersave bias to influence frequency change decisions.
> +
> + If in doubt, say N.
> +
> config X86_GX_SUSPMOD
> tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
> depends on X86_32 && PCI
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 863fd18..01dfdaf 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -41,6 +41,7 @@ obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
> obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
> obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
> obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o
> +obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o

So sorry .. this file did not get git add'ed. Will resend in a bit

>
> ##################################################################################
> # ARM SoC drivers
> --
> 1.7.9.5
>

2013-03-27 22:47:06

by Jacob Shin

[permalink] [raw]
Subject: Re: [PATCH 2/2] cpufreq: AMD "frequency sensitivity feedback" powersave bias for ondemand governor

On Wed, Mar 27, 2013 at 05:41:22PM -0500, Jacob Shin wrote:
> On Wed, Mar 27, 2013 at 05:37:21PM -0500, Jacob Shin wrote:

> So sorry .. this file did not get git add'ed. Will resend in a bit

Here is the correct patch 2/2:

Thanks!

---

>From 9b79ef03c72f613dcc0cdd3624a6154cb3e76244 Mon Sep 17 00:00:00 2001
From: Jacob Shin <[email protected]>
Date: Fri, 22 Mar 2013 10:32:08 -0500
Subject: [PATCH 2/2] cpufreq: AMD "frequency sensitivity feedback" powersave
bias for ondemand governor

Future AMD processors, starting with Family 16h, can provide software
with feedback on how the workload may respond to frequency change --
memory-bound workloads will not benefit from higher frequency, where
as compute-bound workloads will. This patch enables this "frequency
sensitivity feedback" to aid the ondemand governor to make better
frequency change decisions by hooking into the powersave bias.

Signed-off-by: Jacob Shin <[email protected]>
---
arch/x86/include/uapi/asm/msr-index.h | 1 +
drivers/cpufreq/Kconfig.x86 | 10 +++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/amd_freq_sensitivity.c | 149 ++++++++++++++++++++++++++++++++
4 files changed, 161 insertions(+)
create mode 100644 drivers/cpufreq/amd_freq_sensitivity.c

diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h
index 7a060f4..b2e6c49 100644
--- a/arch/x86/include/uapi/asm/msr-index.h
+++ b/arch/x86/include/uapi/asm/msr-index.h
@@ -173,6 +173,7 @@
#define MSR_AMD64_TSC_RATIO 0xc0000104
#define MSR_AMD64_NB_CFG 0xc001001f
#define MSR_AMD64_PATCH_LOADER 0xc0010020
+#define MSR_AMD64_FREQ_SENSITIVITY 0xc0010080
#define MSR_AMD64_OSVW_ID_LENGTH 0xc0010140
#define MSR_AMD64_OSVW_STATUS 0xc0010141
#define MSR_AMD64_DC_CFG 0xc0011022
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index d7dc0ed..6c714b0 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -129,6 +129,16 @@ config X86_POWERNOW_K8

For details, take a look at <file:Documentation/cpu-freq/>.

+config X86_AMD_FREQ_SENSITIVITY
+ tristate "AMD 'frequency sensitivity feedback' powersave bias"
+ depends on CPU_FREQ_GOV_ONDEMAND && X86_ACPI_CPUFREQ
+ help
+ This adds support for 'frequency sensitivity feedback' feature on
+ supported AMD processors, which hooks into the ondemand governor's
+ powersave bias to influence frequency change decisions.
+
+ If in doubt, say N.
+
config X86_GX_SUSPMOD
tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
depends on X86_32 && PCI
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 863fd18..01dfdaf 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o
+obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o

##################################################################################
# ARM SoC drivers
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
new file mode 100644
index 0000000..80669ae
--- /dev/null
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -0,0 +1,149 @@
+/*
+ * amd_freq_sensitivity.c: AMD "frequency sensitivity feedback" powersave bias
+ * for ondemand governor.
+ *
+ * Copyright (C) 2013 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+
+#include "cpufreq_governor.h"
+
+#define PROC_FEEDBACK_INTERFACE_SHIFT 11
+#define CLASS_CODE_SHIFT 56
+#define CLASS_CODE_MASK 0xff
+#define CLASS_CODE_CORE_FREQUENCY_SENSITIVITY 0x01
+
+static u32 msr_addr;
+
+struct cpu_data_t {
+ u64 actual;
+ u64 reference;
+ unsigned int freq_prev;
+};
+
+static DEFINE_PER_CPU(struct cpu_data_t, cpu_data);
+
+static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,
+ unsigned int freq_next, unsigned int relation)
+{
+ int sensitivity;
+ long d_actual, d_reference;
+ struct msr actual, reference;
+ struct cpu_data_t *data = &per_cpu(cpu_data, policy->cpu);
+ struct dbs_data *od_data = policy->governor_data;
+ struct od_dbs_tuners *od_tuners = od_data->tuners;
+ struct od_cpu_dbs_info_s *od_info =
+ od_data->cdata->get_cpu_dbs_info_s(policy->cpu);
+
+ rdmsr_on_cpu(policy->cpu, msr_addr, &actual.l, &actual.h);
+ rdmsr_on_cpu(policy->cpu, msr_addr + 1, &reference.l, &reference.h);
+ actual.h &= 0x00ffffff;
+ reference.h &= 0x00ffffff;
+
+ if (!od_info->freq_table)
+ goto out;
+
+ /* counter wrapped around, so push until next check */
+ if (actual.q < data->actual || reference.q < data->reference) {
+ freq_next = policy->cur;
+ goto out;
+ }
+
+ d_actual = actual.q - data->actual;
+ d_reference = reference.q - data->reference;
+
+ /* divide by 0, so push as well */
+ if (d_reference == 0) {
+ freq_next = policy->cur;
+ goto out;
+ }
+
+ sensitivity = 1000 - (1000 * (d_reference - d_actual) / d_reference);
+
+ if (sensitivity > 1000)
+ sensitivity = 1000;
+ else if (sensitivity < 0)
+ sensitivity = 0;
+
+ /* this workload is not CPU bound, so choose a lower freq */
+ if (sensitivity < od_tuners->powersave_bias) {
+ if (data->freq_prev == policy->cur)
+ freq_next = policy->cur;
+
+ if (freq_next > policy->cur)
+ freq_next = policy->cur;
+ else if (freq_next < policy->cur)
+ freq_next = policy->min;
+ else {
+ unsigned int index = 0;
+
+ cpufreq_frequency_table_target(policy,
+ od_info->freq_table, policy->cur - 1,
+ CPUFREQ_RELATION_H, &index);
+ freq_next = od_info->freq_table[index].frequency;
+ }
+
+ data->freq_prev = freq_next;
+ } else
+ data->freq_prev = 0;
+
+out:
+ data->actual = actual.q;
+ data->reference = reference.q;
+ return freq_next;
+}
+
+static struct od_ops od_ops = {
+ .powersave_bias_target = amd_powersave_bias_target,
+};
+
+static int __init amd_freq_sensitivity_init(void)
+{
+ int i;
+ u32 eax, edx, dummy;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return -ENODEV;
+
+ cpuid(0x80000007, &eax, &dummy, &dummy, &edx);
+
+ if (!(edx & (1 << PROC_FEEDBACK_INTERFACE_SHIFT)))
+ return -ENODEV;
+
+ for (i = 0; i < (eax & 0xf); i++) {
+ u64 val;
+ u32 addr = MSR_AMD64_FREQ_SENSITIVITY + (i * 2);
+
+ rdmsrl(addr, val);
+
+ if (((val >> CLASS_CODE_SHIFT) & CLASS_CODE_MASK)
+ == CLASS_CODE_CORE_FREQUENCY_SENSITIVITY) {
+ msr_addr = addr;
+ break;
+ }
+ }
+
+ if (!msr_addr)
+ return -ENODEV;
+
+ od_register_ops(&od_ops);
+ return 0;
+}
+
+static void __exit amd_freq_sensitivity_exit(void)
+{
+ od_unregister_ops(&od_ops);
+}
+
+MODULE_AUTHOR("Jacob Shin <[email protected]>");
+MODULE_DESCRIPTION("AMD 'frequency sensitivity feedback' powersave bias for "
+ "the ondemand governor.");
+MODULE_LICENSE("GPL");
+
+module_init(amd_freq_sensitivity_init);
+module_exit(amd_freq_sensitivity_exit);
--
1.7.9.5

2013-03-28 07:36:42

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH 1/2] cpufreq: ondemand: allow custom od_ops to be registered

On 28 March 2013 04:07, Jacob Shin <[email protected]> wrote:
> diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
> +void od_register_ops(struct od_ops *ops)
> +{
> + if (ops->powersave_bias_init_cpu)
> + od_ops.powersave_bias_init_cpu = ops->powersave_bias_init_cpu;
> + if (ops->powersave_bias_target)
> + od_ops.powersave_bias_target = ops->powersave_bias_target;
> + if (ops->freq_increase)
> + od_ops.freq_increase = ops->freq_increase;
> +}

We don't need to support all the three. First and last ones strictly belong
to ondemand governor.

2013-03-28 07:41:28

by Viresh Kumar

[permalink] [raw]
Subject: Re: [PATCH 2/2] cpufreq: AMD "frequency sensitivity feedback" powersave bias for ondemand governor

On 28 March 2013 04:16, Jacob Shin <[email protected]> wrote:
> diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
> +#include <linux/module.h>
> +
> +#include "cpufreq_governor.h"

These two are enough for you?

> +#define PROC_FEEDBACK_INTERFACE_SHIFT 11
> +#define CLASS_CODE_SHIFT 56
> +#define CLASS_CODE_MASK 0xff
> +#define CLASS_CODE_CORE_FREQUENCY_SENSITIVITY 0x01
> +
> +static u32 msr_addr;
> +
> +struct cpu_data_t {
> + u64 actual;
> + u64 reference;

types.h

> + unsigned int freq_prev;
> +};
> +
> +static DEFINE_PER_CPU(struct cpu_data_t, cpu_data);

include/linux/percpu.h

> +static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,
> + unsigned int freq_next, unsigned int relation)
> +{
> + int sensitivity;
> + long d_actual, d_reference;
> + struct msr actual, reference;
> + struct cpu_data_t *data = &per_cpu(cpu_data, policy->cpu);
> + struct dbs_data *od_data = policy->governor_data;
> + struct od_dbs_tuners *od_tuners = od_data->tuners;
> + struct od_cpu_dbs_info_s *od_info =
> + od_data->cdata->get_cpu_dbs_info_s(policy->cpu);
> +
> + rdmsr_on_cpu(policy->cpu, msr_addr, &actual.l, &actual.h);
> + rdmsr_on_cpu(policy->cpu, msr_addr + 1, &reference.l, &reference.h);
> + actual.h &= 0x00ffffff;
> + reference.h &= 0x00ffffff;
> +
> + if (!od_info->freq_table)
> + goto out;
> +
> + /* counter wrapped around, so push until next check */
> + if (actual.q < data->actual || reference.q < data->reference) {
> + freq_next = policy->cur;
> + goto out;
> + }
> +
> + d_actual = actual.q - data->actual;
> + d_reference = reference.q - data->reference;
> +
> + /* divide by 0, so push as well */
> + if (d_reference == 0) {
> + freq_next = policy->cur;
> + goto out;
> + }
> +
> + sensitivity = 1000 - (1000 * (d_reference - d_actual) / d_reference);
> +
> + if (sensitivity > 1000)
> + sensitivity = 1000;
> + else if (sensitivity < 0)
> + sensitivity = 0;
> +
> + /* this workload is not CPU bound, so choose a lower freq */
> + if (sensitivity < od_tuners->powersave_bias) {
> + if (data->freq_prev == policy->cur)
> + freq_next = policy->cur;
> +
> + if (freq_next > policy->cur)
> + freq_next = policy->cur;
> + else if (freq_next < policy->cur)
> + freq_next = policy->min;
> + else {
> + unsigned int index = 0;
> +
> + cpufreq_frequency_table_target(policy,
> + od_info->freq_table, policy->cur - 1,
> + CPUFREQ_RELATION_H, &index);
> + freq_next = od_info->freq_table[index].frequency;
> + }
> +
> + data->freq_prev = freq_next;
> + } else
> + data->freq_prev = 0;
> +
> +out:
> + data->actual = actual.q;
> + data->reference = reference.q;
> + return freq_next;
> +}
> +
> +static struct od_ops od_ops = {
> + .powersave_bias_target = amd_powersave_bias_target,
> +};
> +
> +static int __init amd_freq_sensitivity_init(void)

include/linux/init.h

> +{
> + int i;
> + u32 eax, edx, dummy;
> +
> + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
> + return -ENODEV;
> +
> + cpuid(0x80000007, &eax, &dummy, &dummy, &edx);
> +
> + if (!(edx & (1 << PROC_FEEDBACK_INTERFACE_SHIFT)))
> + return -ENODEV;
> +
> + for (i = 0; i < (eax & 0xf); i++) {
> + u64 val;
> + u32 addr = MSR_AMD64_FREQ_SENSITIVITY + (i * 2);
> +
> + rdmsrl(addr, val);
> +
> + if (((val >> CLASS_CODE_SHIFT) & CLASS_CODE_MASK)
> + == CLASS_CODE_CORE_FREQUENCY_SENSITIVITY) {
> + msr_addr = addr;
> + break;
> + }
> + }
> +
> + if (!msr_addr)
> + return -ENODEV;
> +
> + od_register_ops(&od_ops);
> + return 0;
> +}
> +
> +static void __exit amd_freq_sensitivity_exit(void)
> +{
> + od_unregister_ops(&od_ops);
> +}
> +
> +MODULE_AUTHOR("Jacob Shin <[email protected]>");
> +MODULE_DESCRIPTION("AMD 'frequency sensitivity feedback' powersave bias for "
> + "the ondemand governor.");
> +MODULE_LICENSE("GPL");
> +
> +module_init(amd_freq_sensitivity_init);
> +module_exit(amd_freq_sensitivity_exit);

Add them directly below their respective routines without a blank line
inbetween.