55
66import time
77from threading import Thread
8+ from framework .properties import global_props
89
910import psutil
1011
@@ -28,10 +29,20 @@ class MemoryMonitor(Thread):
2829 VMM memory usage.
2930 """
3031
31- # If guest memory is >3328MB, it is split in a 2nd region
32- X86_MEMORY_GAP_START = 3328 * 2 ** 20
33-
34- def __init__ (self , vm , threshold = 5 * 2 ** 20 , period_s = 0.05 ):
32+ # If guest memory is >3GiB, it is split in a 2nd region
33+ # Gap starts at 3GiBs and is 1GiB long
34+ X86_32BIT_MEMORY_GAP_START = 3 * 2 ** 30
35+ X86_32BIT_MEMORY_GAP_SIZE = 1 * 2 ** 30
36+ # If guest memory is >255GiB, it is split in a 3rd region
37+ # Gap starts at 256 GiB and is 256GiB long
38+ X86_64BIT_MEMORY_GAP_START = 256 * 2 ** 30
39+ # On ARM64 we just have a single gap, but memory starts at an offset
40+ # Gap starts at 256 GiB and is GiB long
41+ # Memory starts at 2GiB
42+ ARM64_64BIT_MEMORY_GAP_START = 256 * 2 ** 30
43+ ARM64_MEMORY_START = 2 * 2 ** 30
44+
45+ def __init__ (self , vm , threshold = 5 * 2 ** 20 , period_s = 0.01 ):
3546 """Initialize monitor attributes."""
3647 Thread .__init__ (self )
3748 self ._vm = vm
@@ -71,8 +82,13 @@ def run(self):
7182 return
7283 mem_total = 0
7384 for mmap in mmaps :
85+ if mmap .size >= 512 * 2 ** 20 :
86+ print (f"Checking mmap region: { mmap } . VM memory: { guest_mem_bytes } " )
87+
7488 if self .is_guest_mem (mmap .size , guest_mem_bytes ):
89+ print (f"Region { mmap } is guest memory" )
7590 continue
91+
7692 mem_total += mmap .rss
7793 self ._current_rss = mem_total
7894 if mem_total > self .threshold :
@@ -81,24 +97,55 @@ def run(self):
8197
8298 time .sleep (self ._period_s )
8399
84- def is_guest_mem (self , size , guest_mem_bytes ):
100+ def is_guest_mem_x86 (self , size , guest_mem_bytes ):
85101 """
86- If the address is recognised as a guest memory region,
87- return True, otherwise return False.
102+ Checks if a region is a guest memory region based on
103+ x86_64 physical memory layout
88104 """
105+ return size in (
106+ # memory fits before the first gap
107+ guest_mem_bytes ,
108+ # guest memory spans at least two regions & memory fits before the second gap
109+ self .X86_32BIT_MEMORY_GAP_START ,
110+ # guest memory spans exactly two regions
111+ guest_mem_bytes - self .X86_32BIT_MEMORY_GAP_START ,
112+ # guest memory fills the space between the two gaps
113+ self .X86_64BIT_MEMORY_GAP_START
114+ - self .X86_32BIT_MEMORY_GAP_START
115+ - self .X86_32BIT_MEMORY_GAP_SIZE ,
116+ # guest memory spans 3 regions, this is what remains past the second gap
117+ guest_mem_bytes
118+ - self .X86_64BIT_MEMORY_GAP_START
119+ + self .X86_32BIT_MEMORY_GAP_SIZE ,
120+ )
89121
90- # If x86_64 guest memory exceeds 3328M, it will be split
91- # in 2 regions: 3328M and the rest. We have 3 cases here
92- # to recognise a guest memory region:
93- # - its size matches the guest memory exactly
94- # - its size is 3328M
95- # - its size is guest memory minus 3328M.
122+ def is_guest_mem_arch64 (self , size , guest_mem_bytes ):
123+ """
124+ Checks if a region is a guest memory region based on
125+ ARM64 physical memory layout
126+ """
96127 return size in (
128+ # guest memory fits before the gap
97129 guest_mem_bytes ,
98- self .X86_MEMORY_GAP_START ,
99- guest_mem_bytes - self .X86_MEMORY_GAP_START ,
130+ # guest memory fills the space before the gap
131+ self .ARM64_64BIT_MEMORY_GAP_START - self .ARM64_MEMORY_START ,
132+ # guest memory spans 2 regions, this is what remains past the gap
133+ guest_mem_bytes
134+ - self .ARM64_64BIT_MEMORY_GAP_START
135+ + self .ARM64_MEMORY_START ,
100136 )
101137
138+ def is_guest_mem (self , size , guest_mem_bytes ):
139+ """
140+ If the address is recognised as a guest memory region,
141+ return True, otherwise return False.
142+ """
143+
144+ if global_props .cpu_architecture == "x86_64" :
145+ return self .is_guest_mem_x86 (size , guest_mem_bytes )
146+
147+ return self .is_guest_mem_arch64 (size , guest_mem_bytes )
148+
102149 def check_samples (self ):
103150 """Check that there are no samples over the threshold."""
104151 if self ._exceeded is not None :
0 commit comments