2016-04-01 15:50:05

by Andy Lutomirski

[permalink] [raw]
Subject: [PATCH] x86: Add a turbo mode sysctl

Sadly, hardware turbo mode buttons are few and far between in these
degenerate times. Add a software control at /proc/sys/turbo_mode.

Unfortunately, Linux graphical environments have become very
heavy-weight and are essentially unusable on non-Turbo systems. The
VT console works very well, though.

Due to KVM limitations, turbo mode is permanently on in a KVM guest.

Signed-off-by: Andy Lutomirski <[email protected]>
---
arch/x86/mm/pat.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index faec01e7a17d..f703d8b1ed20 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -69,6 +69,8 @@ static int __init pat_debug_setup(char *str)
}
__setup("debugpat", pat_debug_setup);

+static int turbo_mode = 1;
+
#ifdef CONFIG_X86_PAT
/*
* X86 PAT uses page flags arch_1 and uncached together to keep track of
@@ -176,6 +178,62 @@ static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg)

#undef CM

+#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
+
+static void update_local_turbo_mode(void *dummy)
+{
+ unsigned long cr0 = read_cr0();
+
+ /*
+ * KVM doesn't properly handle CD.
+ *
+ * XXX: this may interact poorly with CPU hotplug.
+ */
+
+ if (turbo_mode)
+ write_cr0(cr0 & ~X86_CR0_CD);
+ else
+ write_cr0(cr0 | X86_CR0_CD);
+}
+
+static void update_turbo_mode(void)
+{
+ on_each_cpu(update_local_turbo_mode, NULL, 1);
+
+ if (!turbo_mode)
+ wbinvd();
+}
+
+static int turbo_mode_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ int error;
+
+ error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+ if (error)
+ return error;
+
+ if (write)
+ update_turbo_mode();
+
+ return 0;
+}
+
+static int zero, one = 1;
+static struct ctl_table turbo_mode_table[] = {
+ {
+ .procname = "turbo_mode",
+ .data = &turbo_mode,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = turbo_mode_handler,
+ .extra1 = &zero,
+ .extra2 = &one,
+ },
+ {}
+};
+
/*
* Update the cache mode to pgprot translation tables according to PAT
* configuration.
@@ -196,8 +254,6 @@ void pat_init_cache_modes(u64 pat)
pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg);
}

-#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
-
static void pat_bsp_init(u64 pat)
{
u64 tmp_pat;
@@ -1096,6 +1152,9 @@ static int __init pat_memtype_list_init(void)
debugfs_create_file("pat_memtype_list", S_IRUSR,
arch_debugfs_dir, NULL, &memtype_fops);
}
+
+ register_sysctl_table(turbo_mode_table);
+
return 0;
}

--
2.5.5


2016-04-01 16:06:04

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl

On Fri, Apr 01, 2016 at 08:49:53AM -0700, Andy Lutomirski wrote:
> Sadly, hardware turbo mode buttons are few and far between in these
> degenerate times. Add a software control at /proc/sys/turbo_mode.
>
> Unfortunately, Linux graphical environments have become very
> heavy-weight and are essentially unusable on non-Turbo systems. The
> VT console works very well, though.
>
> Due to KVM limitations, turbo mode is permanently on in a KVM guest.
>
> Signed-off-by: Andy Lutomirski <[email protected]>
> ---
> arch/x86/mm/pat.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 61 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
> index faec01e7a17d..f703d8b1ed20 100644
> --- a/arch/x86/mm/pat.c
> +++ b/arch/x86/mm/pat.c
> @@ -69,6 +69,8 @@ static int __init pat_debug_setup(char *str)
> }
> __setup("debugpat", pat_debug_setup);
>
> +static int turbo_mode = 1;
> +
> #ifdef CONFIG_X86_PAT
> /*
> * X86 PAT uses page flags arch_1 and uncached together to keep track of
> @@ -176,6 +178,62 @@ static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg)
>
> #undef CM
>
> +#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
> +
> +static void update_local_turbo_mode(void *dummy)
> +{
> + unsigned long cr0 = read_cr0();
> +
> + /*
> + * KVM doesn't properly handle CD.
> + *
> + * XXX: this may interact poorly with CPU hotplug.
> + */
> +
> + if (turbo_mode)
> + write_cr0(cr0 & ~X86_CR0_CD);
> + else
> + write_cr0(cr0 | X86_CR0_CD);

Good!

> +}
> +
> +static void update_turbo_mode(void)
> +{
> + on_each_cpu(update_local_turbo_mode, NULL, 1);
> +
> + if (!turbo_mode)
> + wbinvd();
> +}
> +
> +static int turbo_mode_handler(struct ctl_table *table, int write,
> + void __user *buffer, size_t *lenp,
> + loff_t *ppos)
> +{
> + int error;
> +
> + error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
> + if (error)
> + return error;
> +
> + if (write)
> + update_turbo_mode();
> +
> + return 0;
> +}
> +
> +static int zero, one = 1;
> +static struct ctl_table turbo_mode_table[] = {
> + {
> + .procname = "turbo_mode",

I'd call that "make_shit_faster". Other than that, ACK!

> + .data = &turbo_mode,
> + .maxlen = sizeof(int),
> + .mode = 0644,
> + .proc_handler = turbo_mode_handler,
> + .extra1 = &zero,
> + .extra2 = &one,
> + },
> + {}
> +};
> +
> /*
> * Update the cache mode to pgprot translation tables according to PAT
> * configuration.
> @@ -196,8 +254,6 @@ void pat_init_cache_modes(u64 pat)
> pr_info("x86/PAT: Configuration [0-7]: %s\n", pat_msg);
> }
>
> -#define PAT(x, y) ((u64)PAT_ ## y << ((x)*8))
> -
> static void pat_bsp_init(u64 pat)
> {
> u64 tmp_pat;
> @@ -1096,6 +1152,9 @@ static int __init pat_memtype_list_init(void)
> debugfs_create_file("pat_memtype_list", S_IRUSR,
> arch_debugfs_dir, NULL, &memtype_fops);
> }
> +
> + register_sysctl_table(turbo_mode_table);
> +
> return 0;
> }
>
> --
> 2.5.5
>
>

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.

2016-04-01 16:09:18

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl

Hi Andy,

[auto build test WARNING on tip/x86/core]
[also build test WARNING on v4.6-rc1 next-20160401]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url: https://github.com/0day-ci/linux/commits/Andy-Lutomirski/x86-Add-a-turbo-mode-sysctl/20160401-235300
config: i386-randconfig-s1-201613 (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=i386

All warnings (new ones prefixed by >>):

>> arch/x86/mm/pat.c:224:25: warning: 'turbo_mode_table' defined but not used [-Wunused-variable]
static struct ctl_table turbo_mode_table[] = {
^

vim +/turbo_mode_table +224 arch/x86/mm/pat.c

208 void __user *buffer, size_t *lenp,
209 loff_t *ppos)
210 {
211 int error;
212
213 error = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
214 if (error)
215 return error;
216
217 if (write)
218 update_turbo_mode();
219
220 return 0;
221 }
222
223 static int zero, one = 1;
> 224 static struct ctl_table turbo_mode_table[] = {
225 {
226 .procname = "turbo_mode",
227 .data = &turbo_mode,
228 .maxlen = sizeof(int),
229 .mode = 0644,
230 .proc_handler = turbo_mode_handler,
231 .extra1 = &zero,
232 .extra2 = &one,

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (1.55 kB)
.config.gz (26.48 kB)
Download all attachments

2016-04-01 16:11:41

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl

On Fri, 1 Apr 2016, Andy Lutomirski wrote:
> +static void update_local_turbo_mode(void *dummy)
> +{
> + unsigned long cr0 = read_cr0();
> +
> + /*
> + * KVM doesn't properly handle CD.
> + *
> + * XXX: this may interact poorly with CPU hotplug.

Please cc these crazy folks who cleanup the hotplug mess so they can put it on
their todo list.

> + */
> +
> + if (turbo_mode)
> + write_cr0(cr0 & ~X86_CR0_CD);
> + else
> + write_cr0(cr0 | X86_CR0_CD);

I think proper turbo mode disable requires ~(X86_CR0_CD | X86_CR0_NW)

> +static void update_turbo_mode(void)
> +{
> + on_each_cpu(update_local_turbo_mode, NULL, 1);
> +
> + if (!turbo_mode)
> + wbinvd();

You really want to do wbinvd() on each cpu to make sure that each cpu gets out
of that turbo thing.

Thanks,

tglx

2016-04-02 20:22:04

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl

On Fri, Apr 1, 2016 at 9:10 AM, Thomas Gleixner <[email protected]> wrote:
> On Fri, 1 Apr 2016, Andy Lutomirski wrote:
>> +static void update_local_turbo_mode(void *dummy)
>> +{
>> + unsigned long cr0 = read_cr0();
>> +
>> + /*
>> + * KVM doesn't properly handle CD.
>> + *
>> + * XXX: this may interact poorly with CPU hotplug.
>
> Please cc these crazy folks who cleanup the hotplug mess so they can put it on
> their todo list.
>
>> + */
>> +
>> + if (turbo_mode)
>> + write_cr0(cr0 & ~X86_CR0_CD);
>> + else
>> + write_cr0(cr0 | X86_CR0_CD);
>
> I think proper turbo mode disable requires ~(X86_CR0_CD | X86_CR0_NW)

I thought that made no difference on family 6 and P4 and was actively
dangerous (disabled coherency) before. At least, that's what the
table of caching modes and the footnote seems to say.

>
>> +static void update_turbo_mode(void)
>> +{
>> + on_each_cpu(update_local_turbo_mode, NULL, 1);
>> +
>> + if (!turbo_mode)
>> + wbinvd();
>
> You really want to do wbinvd() on each cpu to make sure that each cpu gets out
> of that turbo thing.

Nah, this is an explicit optimization to de-turboize as quickly as possible:

"The instruction then issues a special-function bus cycle that directs
external caches to also write
back modified data and another bus cycle to indicate that the external
caches should be invalidated."

I think we should merge this patch and add a special-case so that
calling unlink on turbo_mode sets it to zero. Then people who rm -rf
/ will brick their systems more slowly :)

--Andy

2016-04-03 09:57:14

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl

On Sat, 2 Apr 2016, Andy Lutomirski wrote:
> On Fri, Apr 1, 2016 at 9:10 AM, Thomas Gleixner <[email protected]> wrote:
> >> + if (turbo_mode)
> >> + write_cr0(cr0 & ~X86_CR0_CD);
> >> + else
> >> + write_cr0(cr0 | X86_CR0_CD);
> >
> > I think proper turbo mode disable requires ~(X86_CR0_CD | X86_CR0_NW)
>
> I thought that made no difference on family 6 and P4 and was actively
> dangerous (disabled coherency) before. At least, that's what the
> table of caching modes and the footnote seems to say.

CD=0 and NW=1 result in #GP, which might be your intent as that is definitely
the slowest mode you can achieve. But you should add a comment at least.

> I think we should merge this patch and add a special-case so that
> calling unlink on turbo_mode sets it to zero. Then people who rm -rf
> / will brick their systems more slowly :)

While at it can you please make a turbo = 0 call when we hit a WARN/BUG/Panic
so the messages spill slower over the screen?

Thanks,

tglx

2016-04-03 10:12:14

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl

On Sun, Apr 03, 2016 at 11:55:34AM +0200, Thomas Gleixner wrote:
> While at it can you please make a turbo = 0 call when we hit a WARN/BUG/Panic
> so the messages spill slower over the screen?

Good idea!

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.

2016-04-04 06:48:29

by Angel Shtilianov

[permalink] [raw]
Subject: Re: [PATCH] x86: Add a turbo mode sysctl



On 04/01/2016 06:49 PM, Andy Lutomirski wrote:
> Sadly, hardware turbo mode buttons are few and far between in these
> degenerate times. Add a software control at /proc/sys/turbo_mode.
>
> Unfortunately, Linux graphical environments have become very
> heavy-weight and are essentially unusable on non-Turbo systems. The
> VT console works very well, though.
>
> Due to KVM limitations, turbo mode is permanently on in a KVM guest.
>
> Signed-off-by: Andy Lutomirski <[email protected]>
> ---
> arch/x86/mm/pat.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 61 insertions(+), 2 deletions(-)


The name of the sysctl really sucks, it just control whether caching is
enabled/disabled. Now, having said that I realize there are multiple
sysctl that contain "cache" in their names. But can you come up with a
more descriptive name, directly relating to what the sysctl does and now
what its actual effects are :)? Also, aren't caches enabled by the
kernel when the system is booting, according to SDM1/section 9.3 caches
are disabled after reset and I assume the kernel does enable them when
it's booting?