[lxc-devel] [lxd/master] Properly handle sockets with multiple dies (and cores per die)

stgraber on Github lxc-bot at linuxcontainers.org
Thu Apr 2 00:23:12 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200401/c007716a/attachment.bin>
-------------- next part --------------
From b2a78785e0957567f2e58f0d7d241fd0a7e7d7ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 1 Apr 2020 20:22:08 -0400
Subject: [PATCH 1/2] api: resources_cpu_core_die
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 doc/api-extensions.md  | 3 +++
 shared/api/resource.go | 3 +++
 shared/version/api.go  | 1 +
 3 files changed, 7 insertions(+)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index 5e853325ca..9274f246b4 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -1005,3 +1005,6 @@ This adds USB and PCI devices to the output of `/1.0/resources`.
 This indicates that the numa_node field is now recorded per-thread
 rather than per core as some hardware apparently puts threads in
 different NUMA domains.
+
+## resources\_cpu\_core\_die
+Exposes the die_id information on each core.
diff --git a/shared/api/resource.go b/shared/api/resource.go
index 13dc33ea33..8cd2fc0dc4 100644
--- a/shared/api/resource.go
+++ b/shared/api/resource.go
@@ -56,6 +56,9 @@ type ResourcesCPUCache struct {
 type ResourcesCPUCore struct {
 	Core uint64 `json:"core" yaml:"core"`
 
+	// API extension: resources_cpu_core_die
+	Die uint64 `json:"die" yaml:"die"`
+
 	Threads []ResourcesCPUThread `json:"threads" yaml:"threads"`
 
 	Frequency uint64 `json:"frequency,omitempty" yaml:"frequency,omitempty"`
diff --git a/shared/version/api.go b/shared/version/api.go
index de6cd7e6a6..04f131cc3a 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -203,6 +203,7 @@ var APIExtensions = []string{
 	"container_nic_ipvlan_gateway",
 	"resources_usb_pci",
 	"resources_cpu_threads_numa",
+	"resources_cpu_core_die",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From abd99d0df9c4211e3c379c72f592b37ca8b65bac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 1 Apr 2020 20:22:28 -0400
Subject: [PATCH 2/2] lxd/resources: Parse and report die_id
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/resources/cpu.go | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/lxd/resources/cpu.go b/lxd/resources/cpu.go
index f516e9a230..52c5975c0b 100644
--- a/lxd/resources/cpu.go
+++ b/lxd/resources/cpu.go
@@ -89,7 +89,7 @@ func GetCPU() (*api.ResourcesCPU, error) {
 
 	// Temporary storage
 	cpuSockets := map[uint64]*api.ResourcesCPUSocket{}
-	cpuCores := map[uint64]map[uint64]*api.ResourcesCPUCore{}
+	cpuCores := map[uint64]map[string]*api.ResourcesCPUCore{}
 
 	// Open cpuinfo
 	f, err := os.Open("/proc/cpuinfo")
@@ -118,15 +118,25 @@ func GetCPU() (*api.ResourcesCPU, error) {
 
 		// Get topology
 		cpuSocket, err := readUint(filepath.Join(entryPath, "topology", "physical_package_id"))
-		if err != nil {
+		if err != nil && !os.IsNotExist(err) {
 			return nil, errors.Wrapf(err, "Failed to read \"%s\"", filepath.Join(entryPath, "topology", "physical_package_id"))
 		}
 
 		cpuCore, err := readUint(filepath.Join(entryPath, "topology", "core_id"))
-		if err != nil {
+		if err != nil && !os.IsNotExist(err) {
 			return nil, errors.Wrapf(err, "Failed to read \"%s\"", filepath.Join(entryPath, "topology", "core_id"))
 		}
 
+		cpuDie, err := readInt(filepath.Join(entryPath, "topology", "die_id"))
+		if err != nil && !os.IsNotExist(err) {
+			return nil, errors.Wrapf(err, "Failed to read \"%s\"", filepath.Join(entryPath, "topology", "die_id"))
+		}
+
+		if cpuDie == -1 {
+			// Architectures without support for die_id report -1, make that die 0 instead.
+			cpuDie = 0
+		}
+
 		// Grab socket data if needed
 		resSocket, ok := cpuSockets[cpuSocket]
 		if !ok {
@@ -233,17 +243,21 @@ func GetCPU() (*api.ResourcesCPU, error) {
 
 			// Record the data
 			cpuSockets[cpuSocket] = resSocket
-			cpuCores[cpuSocket] = map[uint64]*api.ResourcesCPUCore{}
+			cpuCores[cpuSocket] = map[string]*api.ResourcesCPUCore{}
 		}
 
 		// Grab core data if needed
-		resCore, ok := cpuCores[cpuSocket][cpuCore]
+		coreIndex := fmt.Sprintf("%d_%d", cpuDie, cpuCore)
+		resCore, ok := cpuCores[cpuSocket][coreIndex]
 		if !ok {
 			resCore = &api.ResourcesCPUCore{}
 
 			// Core number
 			resCore.Core = cpuCore
 
+			// Die number
+			resCore.Die = uint64(cpuDie)
+
 			// Frequency
 			if sysfsExists(filepath.Join(entryPath, "cpufreq", "scaling_cur_freq")) {
 				freqCurrent, err := readUint(filepath.Join(entryPath, "cpufreq", "scaling_cur_freq"))
@@ -258,7 +272,7 @@ func GetCPU() (*api.ResourcesCPU, error) {
 			resCore.Threads = []api.ResourcesCPUThread{}
 
 			// Record the data
-			cpuCores[cpuSocket][cpuCore] = resCore
+			cpuCores[cpuSocket][coreIndex] = resCore
 		}
 
 		// Grab thread data


More information about the lxc-devel mailing list