Merge ~adam-collard/maas:lxd-numa-memory-1878923 into maas:master

Proposed by Adam Collard
Status: Merged
Approved by: Adam Collard
Approved revision: 46dea51cc575a72e4d210606c04a50e6e845e42f
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~adam-collard/maas:lxd-numa-memory-1878923
Merge into: maas:master
Diff against target: 148 lines (+64/-10)
4 files modified
src/maasserver/models/numa.py (+3/-0)
src/metadataserver/builtin_scripts/hooks.py (+2/-5)
src/metadataserver/builtin_scripts/tests/test_hooks.py (+47/-0)
src/provisioningserver/utils/lxd.py (+12/-5)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Lee Trager (community) Approve
Review via email: mp+386396@code.launchpad.net

Commit message

Improve robustness of NUMA node identification

Fixes LP:1885157

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lxd-numa-memory-1878923 lp:~adam-collard/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/7820/console
COMMIT: 245d125f97afbe54d50fe792bf0412cb1f4f0214

review: Needs Fixing
Revision history for this message
Lee Trager (ltrager) wrote :

LGTM!

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b lxd-numa-memory-1878923 lp:~adam-collard/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 46dea51cc575a72e4d210606c04a50e6e845e42f

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/maasserver/models/numa.py b/src/maasserver/models/numa.py
index ee82464..f6e347c 100644
--- a/src/maasserver/models/numa.py
+++ b/src/maasserver/models/numa.py
@@ -19,6 +19,9 @@ class NUMANode(CleanSave, TimestampedModel):
19 class Meta:19 class Meta:
20 unique_together = [("node", "index")]20 unique_together = [("node", "index")]
2121
22 def __repr__(self):
23 return f"<NUMANode of {self.index} {self.node!r} cores: {self.cores!r} {self.memory}>"
24
2225
23def create_default_numanode(machine):26def create_default_numanode(machine):
24 """Create the default "0" NUMA node for a machine."""27 """Create the default "0" NUMA node for a machine."""
diff --git a/src/metadataserver/builtin_scripts/hooks.py b/src/metadataserver/builtin_scripts/hooks.py
index c7a3580..26c7e11 100644
--- a/src/metadataserver/builtin_scripts/hooks.py
+++ b/src/metadataserver/builtin_scripts/hooks.py
@@ -464,10 +464,7 @@ def _process_lxd_resources(node, data):
464 NUMANode.objects.update_or_create(464 NUMANode.objects.update_or_create(
465 node=node,465 node=node,
466 index=numa_index,466 index=numa_index,
467 defaults={467 defaults={"memory": numa_data.memory, "cores": numa_data.cores},
468 "memory": numa_data["memory"],
469 "cores": numa_data["cores"],
470 },
471 )[0]468 )[0]
472 for numa_index, numa_data in numa_nodes.items()469 for numa_index, numa_data in numa_nodes.items()
473 ]470 ]
@@ -494,7 +491,7 @@ def _parse_memory(memory, numa_nodes):
494 default_numa_node = {"numa_node": 0, "total": total_memory}491 default_numa_node = {"numa_node": 0, "total": total_memory}
495492
496 for memory_node in memory.get("nodes", [default_numa_node]):493 for memory_node in memory.get("nodes", [default_numa_node]):
497 numa_nodes[memory_node["numa_node"]]["memory"] = int(494 numa_nodes[memory_node["numa_node"]].memory = int(
498 memory_node.get("total", 0) / 1024 ** 2495 memory_node.get("total", 0) / 1024 ** 2
499 )496 )
500497
diff --git a/src/metadataserver/builtin_scripts/tests/test_hooks.py b/src/metadataserver/builtin_scripts/tests/test_hooks.py
index 872b5ae..be1a517 100644
--- a/src/metadataserver/builtin_scripts/tests/test_hooks.py
+++ b/src/metadataserver/builtin_scripts/tests/test_hooks.py
@@ -1486,6 +1486,53 @@ class TestProcessLXDResults(MAASServerTestCase):
1486 [32158, 0], [numa.memory for numa in node.numanode_set.all()]1486 [32158, 0], [numa.memory for numa in node.numanode_set.all()]
1487 )1487 )
14881488
1489 def test_updates_memory_no_corresponding_cpu_numa_node(self):
1490 # Regression test for LP:1885157
1491 node = factory.make_Node()
1492 self.patch(hooks_module, "update_node_network_information")
1493 data = make_lxd_output()
1494 data["resources"]["memory"] = {
1495 "nodes": [
1496 {
1497 "numa_node": 252,
1498 "hugepages_used": 0,
1499 "hugepages_total": 0,
1500 "used": 1314131968,
1501 "total": 33720463360,
1502 },
1503 {
1504 "numa_node": 253,
1505 "hugepages_used": 0,
1506 "hugepages_total": 0,
1507 "used": 0,
1508 "total": 0,
1509 },
1510 {
1511 "numa_node": 254,
1512 "hugepages_used": 0,
1513 "hugepages_total": 0,
1514 "used": 0,
1515 "total": 0,
1516 },
1517 {
1518 "numa_node": 255,
1519 "hugepages_used": 0,
1520 "hugepages_total": 0,
1521 "used": 0,
1522 "total": 0,
1523 },
1524 ],
1525 "hugepages_total": 0,
1526 "hugepages_used": 0,
1527 "hugepages_size": 2097152,
1528 "used": 602902528,
1529 "total": 33720463360,
1530 }
1531
1532 process_lxd_results(node, json.dumps(data).encode(), 0)
1533 numa_nodes = NUMANode.objects.filter(node=node).order_by("index")
1534 self.assertEqual(6, len(numa_nodes))
1535
1489 def test_updates_cpu_numa_nodes(self):1536 def test_updates_cpu_numa_nodes(self):
1490 node = factory.make_Node()1537 node = factory.make_Node()
1491 self.patch(hooks_module, "update_node_network_information")1538 self.patch(hooks_module, "update_node_network_information")
diff --git a/src/provisioningserver/utils/lxd.py b/src/provisioningserver/utils/lxd.py
index 0b29b64..f45ffd1 100644
--- a/src/provisioningserver/utils/lxd.py
+++ b/src/provisioningserver/utils/lxd.py
@@ -5,8 +5,11 @@
55
6__all__ = ["parse_lxd_cpuinfo"]6__all__ = ["parse_lxd_cpuinfo"]
77
8from collections import defaultdict
8import re9import re
910
11import attr
12
1013
11# This is needed on the rack controller in the LXDPodDriver to set14# This is needed on the rack controller in the LXDPodDriver to set
12# the cpu_speed for discovered machines as the lxd resources are15# the cpu_speed for discovered machines as the lxd resources are
@@ -16,6 +19,13 @@ def lxd_cpu_speed(data):
16 return cpu_speed19 return cpu_speed
1720
1821
22@attr.s
23class NUMANode:
24
25 memory: int = attr.ib(default=0)
26 cores: list = attr.ib(factory=list)
27
28
19def parse_lxd_cpuinfo(data):29def parse_lxd_cpuinfo(data):
20 cpu_speed = 030 cpu_speed = 0
21 cpu_model = None31 cpu_model = None
@@ -23,7 +33,7 @@ def parse_lxd_cpuinfo(data):
23 # Only update the cpu_model if all the socket names match.33 # Only update the cpu_model if all the socket names match.
24 sockets = data.get("cpu", {}).get("sockets", [])34 sockets = data.get("cpu", {}).get("sockets", [])
25 names = []35 names = []
26 numa_nodes = {}36 numa_nodes = defaultdict(NUMANode)
27 for socket in sockets:37 for socket in sockets:
28 name = socket.get("name")38 name = socket.get("name")
29 if name is not None:39 if name is not None:
@@ -32,10 +42,7 @@ def parse_lxd_cpuinfo(data):
32 for thread in core.get("threads", []):42 for thread in core.get("threads", []):
33 thread_id = thread["id"]43 thread_id = thread["id"]
34 numa_node = thread["numa_node"]44 numa_node = thread["numa_node"]
35 if numa_node in numa_nodes:45 numa_nodes[numa_node].cores.append(thread_id)
36 numa_nodes[numa_node]["cores"].append(thread_id)
37 else:
38 numa_nodes[numa_node] = {"cores": [thread_id]}
3946
40 if len(names) > 0 and all(name == names[0] for name in names):47 if len(names) > 0 and all(name == names[0] for name in names):
41 cpu = names[0]48 cpu = names[0]

Subscribers

People subscribed via source and target branches