From 086aa750ab8f1698a6c6eaafe1458279776ce66d Mon Sep 17 00:00:00 2001 From: tb Date: Wed, 11 Aug 2021 18:15:50 +0000 Subject: [PATCH] Make hw.setperf percentages proportional to the enhanced speed step frequencies on intel processors. This way, the default hw.setperf=99 corresponds to the maximum ordinary speed while setting it to 100 enables turbo mode. Tested in snaps for a week, positive feedback from several. --- sys/arch/amd64/amd64/est.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/sys/arch/amd64/amd64/est.c b/sys/arch/amd64/amd64/est.c index 547ae088e11..9565de6d12e 100644 --- a/sys/arch/amd64/amd64/est.c +++ b/sys/arch/amd64/amd64/est.c @@ -1,4 +1,4 @@ -/* $OpenBSD: est.c,v 1.39 2016/03/06 22:41:24 naddy Exp $ */ +/* $OpenBSD: est.c,v 1.40 2021/08/11 18:15:50 tb Exp $ */ /* * Copyright (c) 2003 Michael Eriksson. * All rights reserved. @@ -83,6 +83,7 @@ struct est_op { uint16_t ctrl; uint16_t mhz; + uint16_t pct; }; struct fqlist { @@ -229,10 +230,16 @@ est_acpi_init(void) struct acpicpu_pss *pss; struct fqlist *acpilist; int nstates, i; + int high, low; if ((nstates = acpicpu_fetch_pss(&pss)) == 0) goto nolist; + high = pss[0].pss_core_freq; + low = pss[nstates - 1].pss_core_freq; + if (high - low <= 0) + goto nolist; + if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT)) == NULL) goto nolist; @@ -246,6 +253,8 @@ est_acpi_init(void) for (i = 0; i < nstates; i++) { acpilist->table[i].mhz = pss[i].pss_core_freq; acpilist->table[i].ctrl = pss[i].pss_ctrl; + acpilist->table[i].pct = + (pss[i].pss_core_freq - low) * 100 / (high - low); } acpicpu_set_notify(est_acpi_pss_changed); @@ -264,12 +273,21 @@ est_acpi_pss_changed(struct acpicpu_pss *pss, int npss) { struct fqlist *acpilist; int needtran = 1, i; + int high, low; u_int64_t msr; u_int16_t cur; msr = rdmsr(MSR_PERF_STATUS); cur = msr & 0xffff; + high = pss[0].pss_core_freq; + low = pss[npss - 1].pss_core_freq; + if (high - low <= 0) { + printf("est_acpi_pss_changed: new est state has no " + "speed step\n"); + return; + } + if ((acpilist = malloc(sizeof(struct fqlist), M_DEVBUF, M_NOWAIT)) == NULL) { printf("est_acpi_pss_changed: cannot allocate memory for new " @@ -288,6 +306,8 @@ est_acpi_pss_changed(struct acpicpu_pss *pss, int npss) for (i = 0; i < npss; i++) { acpilist->table[i].mhz = pss[i].pss_core_freq; acpilist->table[i].ctrl = pss[i].pss_ctrl; + acpilist->table[i].pct = + (pss[i].pss_core_freq - low) * 100 / (high - low); if (pss[i].pss_ctrl == cur) needtran = 0; } @@ -392,18 +412,25 @@ est_init(struct cpu_info *ci) printf("%s: using only highest and lowest power " "states\n", cpu_device); + fake_table[0].pct = 51; + fake_table[1].ctrl = idlo; fake_table[1].mhz = MSR2MHZ(idlo, bus_clock); + fake_table[1].pct = 0; fake_fqlist->n = 2; } else { printf("%s: using only highest, current and lowest " "power states\n", cpu_device); + fake_table[0].pct = 67; + fake_table[1].ctrl = cur; fake_table[1].mhz = MSR2MHZ(cur, bus_clock); + fake_table[1].pct = 34; fake_table[2].ctrl = idlo; fake_table[2].mhz = MSR2MHZ(idlo, bus_clock); + fake_table[2].pct = 0; fake_fqlist->n = 3; } @@ -454,10 +481,10 @@ est_setperf(int level) if (est_fqlist == NULL) return; - i = ((level * est_fqlist->n) + 1) / 101; - if (i >= est_fqlist->n) - i = est_fqlist->n - 1; - i = est_fqlist->n - 1 - i; + for (i = 0; i < est_fqlist->n; i++) { + if (level >= est_fqlist->table[i].pct) + break; + } msr = rdmsr(MSR_PERF_CTL); msr &= ~0xffffULL; -- 2.20.1