jaypipes / ghw

Go HardWare discovery/inspection library
Apache License 2.0
1.63k stars 177 forks source link

Check if hyperthreading enabled on not in a system #231

Open swatisehgal opened 3 years ago

swatisehgal commented 3 years ago

Currently there is no API to check if hyperthreading is enabled or disabled on a system. There are ways of figuring out if hyperthreading is enabled on a system or not by something like the following:

func isHyperthreadingEnabled(snapShotOptions *option.Option) (bool, error) {
    cpuInfo, err := ghw.CPU(ghwHandler.snapShotOptions)
    if err != nil {
        return false, fmt.Errorf("Error obtaining CPU Info from GHW snapshot: %v", err)
    }
    threadsPerCore := cpuInfo.TotalThreads / cpuInfo.TotalCores
    if threadsPerCore == 1 {
        //Hyperthreading disabled
        return false, nil
    }
    //Hyperthreading is enabled
    return true, nil
}

OR

func (ghwHandler GHWHandler) isHyperthreadingEnabled(snapShotOptions *option.Option) (bool, error) {
    cpuInfo, err := ghw.CPU(ghwHandler.snapShotOptions)
    if err != nil {
        return false, fmt.Errorf("Error obtaining CPU Info from GHW snapshot: %v", err)
    }
    return contains(cpuInfo.Processors[0].Capabilities, "ht"), nil
}

// contains checks if a string is present in a slice
func contains(s []string, str string) bool {
    for _, v := range s {
        if v == str {
            return true
        }
    }

    return false
}

Would be nice if there was an API to obtain this information directly from a ghw snapshot.

ffromani commented 3 years ago

Sharing some thoughts as ghw contributor.

Since 2018 the linux kernel exposes a pseudofile (https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu) which reports if smt (aka ht) is enabled globally. OTOH, ghw exposes the ht flag per-processor.

I think this is the key decision here: is (or we should model as) smt a per-processor or per-system setting? IOW, can we have SMT enabled only on some cpu complexes and not in other?

At best of my knowledge, if smt is disabled via BIOS or kernel settings, then the processor will NOT report the "ht" flag, thus the two methods yield equivalent results.

ffromani commented 3 years ago

I did a bit of extra research and what we have so far is: we also need to distinguish between firmware settings (aka HT enabled/disabled in BIOS or UEFI) and kernel settings.

  1. the HT flag, if present, is telling us that the HW is ht capable. This is what ghw reports today, reading from /proc/cpuinfo.
  2. the "nosmt" kernel parameters seems (didn't dive deep enough yet) to do something very close to just offline the hyperthread sibilings. While this is of course relevant, is also always possible to offline cores manually, so we need to dive deeper to understand the difference here.

So in practice:

  1. if the BIOS and the kernel aligns, checking for the presence of HT flags tells us if the system is running with SMT enabled - or not.
  2. if the BIOS and the kernel DO NOT align, things get interesting. The only meaningful case is: HT enabled in firmware, nosmt given. In this case, this function wrongly reports the HT state. For userspace, HT is enabled only if ALL hardware, firmware and kernel allow + enable SMT. So in this case the computation will be wrong.