@@ -78,35 +78,73 @@ def _check_cache_topology_x86(
78
78
)
79
79
80
80
81
- def _check_cache_topology_arm (test_microvm , no_cpus ):
81
+ def _aarch64_parse_cache_info (test_microvm , no_cpus ):
82
+ def parse_cache_info (info : str ):
83
+ "One line looks like this: /sys/devices/system/cpu/cpuX/cache/{index}/{name}:{value}"
84
+ cache_info = []
85
+ for line in info .splitlines ():
86
+ parts = line .split ("/" )
87
+
88
+ index = int (parts [- 2 ][- 1 ])
89
+
90
+ name , value = parts [- 1 ].split (":" )
91
+
92
+ if len (cache_info ) == index :
93
+ cache_info .append ({})
94
+ cache_info [index ][name ] = value
95
+ return cache_info
96
+
82
97
# We will check the cache topology by looking at what each cpu
83
98
# contains as far as cache info.
84
99
# For that we are iterating through the hierarchy of folders inside:
85
100
# /sys/devices/system/cpu/cpuX/cache/indexY/type - the type of the cache
86
101
# (i.e Instruction, Data, Unified)
87
102
# /sys/devices/system/cpu/cpuX/cache/indexY/size - size of the cache
88
103
# /sys/devices/system/cpu/cpuX/cache/indexY/level - L1, L2 or L3 cache.
89
- # There are 2 types of L1 cache (instruction and data) that is why the
90
- # "cache_info" variable below has 4 items.
91
-
92
- sys_cpu = "/sys/devices/system/cpu"
93
104
fields = ["level" , "type" , "size" , "coherency_line_size" , "number_of_sets" ]
94
-
95
- cmd = f"grep . { sys_cpu } /cpu{{0..{ no_cpus - 1 } }}/cache/index*/{{{ ',' .join (fields )} }} |sort"
105
+ cmd = f"grep . /sys/devices/system/cpu/cpu{{0..{ no_cpus - 1 } }}/cache/index*/{{{ ',' .join (fields )} }} |sort"
96
106
97
107
_ , guest_stdout , guest_stderr = test_microvm .ssh .run (cmd )
98
108
assert guest_stderr == ""
99
109
100
- res = subprocess .run (
110
+ host_result = subprocess .run (
101
111
cmd ,
102
112
shell = True ,
103
113
executable = "/bin/bash" ,
104
114
capture_output = True ,
105
115
check = True ,
106
116
encoding = "ascii" ,
107
117
)
108
- assert res .stderr == ""
109
- assert res .stdout == guest_stdout
118
+ assert host_result .stderr == ""
119
+ host_stdout = host_result .stdout
120
+
121
+ guest_cache_info = parse_cache_info (guest_stdout )
122
+ host_cache_info = parse_cache_info (host_stdout )
123
+
124
+ return guest_cache_info , host_cache_info
125
+
126
+
127
+ def _check_cache_topology_arm (test_microvm , no_cpus , kernel_version_tpl ):
128
+ guest_cache_info , host_cache_info = _aarch64_parse_cache_info (test_microvm , no_cpus )
129
+
130
+ # Starting from 6.3 kernel cache representation for aarch64 platform has changed.
131
+ # It is no longer equivalent to the host cache representation.
132
+ # The main change is in the level 1 cache, so for newer kernels we
133
+ # compare only level 2 and level 3 caches
134
+ if kernel_version_tpl < (6 , 3 ):
135
+ assert guest_cache_info == host_cache_info
136
+ else :
137
+ guest_first_non_level_1 = 0
138
+ while guest_cache_info [guest_first_non_level_1 ]["level" ] == "1" :
139
+ guest_first_non_level_1 += 1
140
+ guest_slice = guest_cache_info [guest_first_non_level_1 :]
141
+
142
+ host_first_non_level_1 = 0
143
+ while host_cache_info [host_first_non_level_1 ]["level" ] == "1" :
144
+ host_first_non_level_1 += 1
145
+ host_slice = host_cache_info [host_first_non_level_1 :]
146
+
147
+ assert guest_slice == host_slice
110
148
111
149
112
150
@pytest .mark .skipif (
@@ -129,12 +167,6 @@ def test_cpu_topology(uvm_plain_any, num_vcpus, htt):
129
167
)
130
168
131
169
132
- # TODO remove this check once the solution for keeping
133
- # an old cache representation is found.
134
- @pytest .mark .skipif (
135
- global_props .host_linux_version == "6.5" and PLATFORM == "aarch64" ,
136
- reason = "6.5 kernel changes cache representation for aarch64." ,
137
- )
138
170
@pytest .mark .parametrize ("num_vcpus" , [1 , 2 , 16 ])
139
171
@pytest .mark .parametrize ("htt" , [True , False ])
140
172
def test_cache_topology (uvm_plain_any , num_vcpus , htt ):
@@ -151,6 +183,6 @@ def test_cache_topology(uvm_plain_any, num_vcpus, htt):
151
183
if PLATFORM == "x86_64" :
152
184
_check_cache_topology_x86 (vm , 1 if htt and num_vcpus > 1 else 0 , num_vcpus - 1 )
153
185
elif PLATFORM == "aarch64" :
154
- _check_cache_topology_arm (vm , num_vcpus )
186
+ _check_cache_topology_arm (vm , num_vcpus , global_props . host_linux_version_tpl )
155
187
else :
156
188
raise Exception ("This test is not run on this platform!" )
0 commit comments