@@ -91,6 +91,12 @@ class Lscpu(Tool):
9191 r"(?P<l1_data_cache>\d+):(?P<l1_instruction_cache>\d+):"
9292 r"(?P<l2_cache>\d+):(?P<l3_cache>\d+)$"
9393 )
94+ # On some VMs (e.g. confidential VMs), cache topology is not exposed
95+ # and lscpu outputs "-" instead of cache IDs:
96+ # 0 0 0 -
97+ _core_numa_no_cache = re .compile (
98+ r"\s*(?P<cpu>\d+)\s+(?P<numa_node>\d+)\s+(?P<socket>\d+)\s+-$"
99+ )
94100 # Model name: Intel(R) Xeon(R) Platinum 8168 CPU @ 2.70GHz
95101 # Model name: AMD EPYC 7763 64-Core Processor
96102 # Model name: AMD EPYC 7763 64-Core Processor
@@ -267,6 +273,10 @@ def get_cpu_info(self) -> List[CPUInfo]:
267273 # CPU NODE SOCKET L1d:L1i:L2:L3
268274 # 0 0 0 0:0:0:0
269275 # 1 0 0 0:0:0:0
276+ #
277+ # On some VMs (e.g. confidential VMs), cache topology is not exposed:
278+ # CPU NODE SOCKET CACHE
279+ # 0 0 0 -
270280 result = self .run (
271281 "--extended=cpu,node,socket,cache" , expected_exit_code = 0
272282 ).stdout
@@ -278,22 +288,36 @@ def get_cpu_info(self) -> List[CPUInfo]:
278288 output : List [CPUInfo ] = []
279289 for item in mappings :
280290 match_result = self ._core_numa_mappings .fullmatch (item )
281- assert (
282- match_result
283- ), f"lscpu NUMA node mapping is not in expected format: { item } "
284- output .append (
285- CPUInfo (
286- cpu = int (match_result .group ("cpu" )),
287- numa_node = int (match_result .group ("numa_node" )),
288- socket = int (match_result .group ("socket" )),
289- l1_data_cache = int (match_result .group ("l1_data_cache" )),
290- l1_instruction_cache = int (
291- match_result .group ("l1_instruction_cache" )
292- ),
293- l2_cache = int (match_result .group ("l2_cache" )),
294- l3_cache = int (match_result .group ("l3_cache" )),
291+ if match_result :
292+ output .append (
293+ CPUInfo (
294+ cpu = int (match_result .group ("cpu" )),
295+ numa_node = int (match_result .group ("numa_node" )),
296+ socket = int (match_result .group ("socket" )),
297+ l1_data_cache = int (match_result .group ("l1_data_cache" )),
298+ l1_instruction_cache = int (
299+ match_result .group ("l1_instruction_cache" )
300+ ),
301+ l2_cache = int (match_result .group ("l2_cache" )),
302+ l3_cache = int (match_result .group ("l3_cache" )),
303+ )
295304 )
296- )
305+ continue
306+ no_cache_match = self ._core_numa_no_cache .fullmatch (item )
307+ if no_cache_match :
308+ output .append (
309+ CPUInfo (
310+ cpu = int (no_cache_match .group ("cpu" )),
311+ numa_node = int (no_cache_match .group ("numa_node" )),
312+ socket = int (no_cache_match .group ("socket" )),
313+ l1_data_cache = - 1 ,
314+ l1_instruction_cache = - 1 ,
315+ l2_cache = - 1 ,
316+ l3_cache = - 1 ,
317+ )
318+ )
319+ continue
320+ assert False , f"lscpu NUMA node mapping is not in expected format: { item } "
297321 return output
298322
299323 def get_numa_node_count (self ) -> int :
0 commit comments