forked from NG-SD-Plugins/PowerTools
Fix SMT behaviour paper cuts
This commit is contained in:
parent
13bf31611d
commit
fbb68e0d51
3 changed files with 41 additions and 19 deletions
|
@ -60,6 +60,8 @@ pub enum CpuMessage {
|
||||||
|
|
||||||
impl CpuMessage {
|
impl CpuMessage {
|
||||||
fn process(self, settings: &mut dyn TCpus) {
|
fn process(self, settings: &mut dyn TCpus) {
|
||||||
|
// NOTE: "cpu" refers to the Linux kernel definition of a CPU, which is actually a hardware thread
|
||||||
|
// not to be confused with a CPU chip, which usually has multiple hardware threads (cpu cores/threads) in the chip
|
||||||
match self {
|
match self {
|
||||||
Self::SetCpuOnline(index, status) => {settings.cpus().get_mut(index).map(|c| *c.online() = status);},
|
Self::SetCpuOnline(index, status) => {settings.cpus().get_mut(index).map(|c| *c.online() = status);},
|
||||||
Self::SetCpusOnline(cpus) => {
|
Self::SetCpusOnline(cpus) => {
|
||||||
|
@ -68,10 +70,38 @@ impl CpuMessage {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::SetSmt(status, cb) => {
|
Self::SetSmt(status, cb) => {
|
||||||
*settings.smt() = status;
|
if *settings.smt() == status {
|
||||||
|
// already set, do nothing
|
||||||
|
} else if status {
|
||||||
|
// set SMT on
|
||||||
|
*settings.smt() = true;
|
||||||
|
let mut should_be_online = false;
|
||||||
|
let cpu_count = settings.len();
|
||||||
|
for i in (0..cpu_count).rev() {
|
||||||
|
if *settings.cpus()[i].online() && !should_be_online {
|
||||||
|
should_be_online = true;
|
||||||
|
// enable the odd-numbered thread right before
|
||||||
|
// for 1c:2t configs (i.e. anything with SMT2), the highest cpu core is always odd
|
||||||
|
// (e.g. 4c8t has CPUs 0-7, inclusive)
|
||||||
|
// this enables the """fake""" (i.e. odd) cpu which is disabled when SMT is set off
|
||||||
|
if i % 2 == 0 && i+1 != cpu_count {
|
||||||
|
*(settings.cpus()[i+1].online()) = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*settings.cpus()[i].online() = should_be_online;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// set SMT off
|
||||||
|
*settings.smt() = false;
|
||||||
|
for i in 0..settings.len() {
|
||||||
|
// this disables the """fake""" (odd) cpu for appearances' sake
|
||||||
|
// the kernel will automatically disable that same cpu when SMT is changed
|
||||||
|
*settings.cpus()[i].online() = *settings.cpus()[i].online() && (status || i % 2 == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut result = Vec::with_capacity(settings.len());
|
let mut result = Vec::with_capacity(settings.len());
|
||||||
for i in 0..settings.len() {
|
for i in 0..settings.len() {
|
||||||
*settings.cpus()[i].online() = *settings.cpus()[i].online() && (status || i % 2 == 0);
|
|
||||||
result.push(*settings.cpus()[i].online());
|
result.push(*settings.cpus()[i].online());
|
||||||
}
|
}
|
||||||
cb(result);
|
cb(result);
|
||||||
|
|
|
@ -120,8 +120,8 @@ export async function unsetBatteryChargeMode(): Promise<any[]> {
|
||||||
|
|
||||||
// CPU
|
// CPU
|
||||||
|
|
||||||
export async function setCpuSmt(status: boolean): Promise<boolean> {
|
export async function setCpuSmt(status: boolean): Promise<boolean[]> {
|
||||||
return (await call_backend("CPU_set_smt", [status]))[0];
|
return await call_backend("CPU_set_smt", [status]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*export async function getCpuCount(): Promise<number> {
|
/*export async function getCpuCount(): Promise<number> {
|
||||||
|
|
|
@ -251,18 +251,10 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
||||||
description="Enables odd-numbered CPUs"
|
description="Enables odd-numbered CPUs"
|
||||||
onChange={(smt: boolean) => {
|
onChange={(smt: boolean) => {
|
||||||
backend.log(backend.LogLevel.Debug, "SMT is now " + smt.toString());
|
backend.log(backend.LogLevel.Debug, "SMT is now " + smt.toString());
|
||||||
const cpus = get_value(ONLINE_CPUS);
|
//const cpus = get_value(ONLINE_CPUS);
|
||||||
const smtNow = smt && smtAllowed;
|
const smtNow = smt && smtAllowed;
|
||||||
backend.resolve(backend.setCpuSmt(smtNow), (newVal: boolean) => {
|
backend.resolve(backend.setCpuSmt(smtNow), (statii: boolean[]) => {
|
||||||
set_value(SMT_CPU, newVal);
|
set_value(SMT_CPU, smtNow);
|
||||||
});
|
|
||||||
let onlines: boolean[] = [];
|
|
||||||
for (let i = 0; i < total_cpus; i++) {
|
|
||||||
const online = (smtNow? i < cpus : (i % 2 == 0) && (i < cpus * 2))
|
|
||||||
|| (!smtNow && cpus == 4);
|
|
||||||
onlines.push(online);
|
|
||||||
}
|
|
||||||
backend.resolve(backend.setCpuOnlines(onlines), (statii: boolean[]) => {
|
|
||||||
set_value(ONLINE_STATUS_CPUS, statii);
|
set_value(ONLINE_STATUS_CPUS, statii);
|
||||||
const count = countCpus(statii);
|
const count = countCpus(statii);
|
||||||
set_value(ONLINE_CPUS, count);
|
set_value(ONLINE_CPUS, count);
|
||||||
|
@ -276,7 +268,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
||||||
label="Threads"
|
label="Threads"
|
||||||
value={get_value(ONLINE_CPUS)}
|
value={get_value(ONLINE_CPUS)}
|
||||||
step={1}
|
step={1}
|
||||||
max={get_value(SMT_CPU) || !smtAllowed ? total_cpus : total_cpus/2}
|
max={(get_value(SMT_CPU) || !smtAllowed) ? total_cpus : total_cpus/2}
|
||||||
min={1}
|
min={1}
|
||||||
showValue={true}
|
showValue={true}
|
||||||
onChange={(cpus: number) => {
|
onChange={(cpus: number) => {
|
||||||
|
@ -411,9 +403,9 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
||||||
description="Allow the CPU thread to do work"
|
description="Allow the CPU thread to do work"
|
||||||
onChange={(status: boolean) => {
|
onChange={(status: boolean) => {
|
||||||
backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString());
|
backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString());
|
||||||
if (get_value(SMT_CPU)) {
|
if (!get_value(SMT_CPU)) {
|
||||||
backend.resolve(backend.setCpuSmt(false), (newVal: boolean) => {
|
backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => {
|
||||||
set_value(SMT_CPU, newVal);
|
set_value(SMT_CPU, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => {
|
backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => {
|
||||||
|
|
Loading…
Reference in a new issue