From f4e30b66d92fd7cb5c700e68c80a221b8953e685 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakivskyy Date: Tue, 17 Mar 2026 03:10:49 +0200 Subject: [PATCH] source/cpu: Expose CPU cores information Signed-off-by: Oleg Zhurakivskyy --- docs/usage/features.md | 3 +++ source/cpu/cpu.go | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/usage/features.md b/docs/usage/features.md index e1e73aada9..1aa65e1e7b 100644 --- a/docs/usage/features.md +++ b/docs/usage/features.md @@ -65,6 +65,9 @@ feature.node.kubernetes.io/ = | **`cpu-model.vendor_id`** | string | Comparable CPU vendor ID. | | **`cpu-model.family`** | int | CPU family. | | **`cpu-model.id`** | int | CPU model number. | +| **`cpu-cores.physical `** | int | Number of CPU physical cores. | +| **`cpu-cores.threads_per_core`** | int | Number of threads per CPU core. | +| **`cpu-cores.logical`** | int | Number of CPU physical cores. | The CPU label source is configurable, see [worker configuration](nfd-worker.md#worker-configuration) and diff --git a/source/cpu/cpu.go b/source/cpu/cpu.go index f0d77edb93..e15c614d80 100644 --- a/source/cpu/cpu.go +++ b/source/cpu/cpu.go @@ -40,6 +40,7 @@ const Name = "cpu" const ( CpuidFeature = "cpuid" + Cpucores = "cpu_cores" Cpumodel = "model" CstateFeature = "cstate" PstateFeature = "pstate" @@ -161,6 +162,11 @@ func (s *cpuSource) GetLabels() (source.FeatureLabels, error) { labels["model."+k] = v } + // CPU cores + for k, v := range features.Attributes[Cpucores].Elements { + labels["cores."+k] = v + } + // Cstate for k, v := range features.Attributes[CstateFeature].Elements { labels["cstate."+k] = v @@ -226,6 +232,9 @@ func (s *cpuSource) Discover() error { // Detect CPU model s.features.Attributes[Cpumodel] = nfdv1alpha1.NewAttributeFeatures(getCPUModel()) + // Detect CPU cores + s.features.Attributes[Cpucores] = nfdv1alpha1.NewAttributeFeatures(getCPUCores()) + // Detect cstate configuration cstate, err := detectCstate() if err != nil { @@ -299,6 +308,15 @@ func getCPUModel() map[string]string { return cpuModelInfo } +func getCPUCores() map[string]string { + cpuCoresInfo := make(map[string]string) + cpuCoresInfo["physical"] = strconv.Itoa(cpuid.CPU.PhysicalCores) + cpuCoresInfo["threads_per_core"] = strconv.Itoa(cpuid.CPU.ThreadsPerCore) + cpuCoresInfo["logical"] = strconv.Itoa(cpuid.CPU.LogicalCores) + + return cpuCoresInfo +} + // getHypervisor detects the hypervisor on s390x by reading /proc/sysinfo // and on x86_64/arm64 using the cpuid library. // Returns normalized hypervisor string, "unknown" for unknown vendor, or "none" for bare metal.